diff --git a/Gemfile b/Gemfile index cf6e9f773..87cd6dba2 100644 --- a/Gemfile +++ b/Gemfile @@ -7,6 +7,7 @@ unless RUBY_PLATFORM =~ /w32/ end gem 'grack', path:'./lib/grack' +gem 'gitlab', path: 'lib/gitlab-cli' gem 'rest-client' gem "mysql2", "= 0.3.18" gem 'redis-rails' @@ -45,7 +46,7 @@ group :development, :test do gem 'pry-stack_explorer' if RUBY_PLATFORM =~ /darwin/ gem 'puma' - end + end end gem 'rspec-rails', '~> 3.0' diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 7632cf591..bb2138062 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -38,7 +38,8 @@ class ApplicationController < ActionController::Base protect_from_forgery def handle_unverified_request super - cookies.delete(autologin_cookie_name) + raise(ActionController::InvalidAuthenticityToken) + # cookies.delete(autologin_cookie_name) end before_filter :find_first_page diff --git a/app/controllers/blog_comments_controller.rb b/app/controllers/blog_comments_controller.rb index 95790a68d..14a0a3536 100644 --- a/app/controllers/blog_comments_controller.rb +++ b/app/controllers/blog_comments_controller.rb @@ -89,6 +89,9 @@ class BlogCommentsController < ApplicationController #回复 def reply + if params[:in_user_center] + @in_user_center = true + end @article = BlogComment.find(params[:id]).root @quote = params[:quote][:quote] @blogComment = BlogComment.new @@ -101,7 +104,11 @@ class BlogCommentsController < ApplicationController @blogComment.title = "RE: #{@article.title}" unless params[:blog_comment][:title] @article.children << @blogComment @user_activity_id = params[:user_activity_id] - + user_activity = UserActivity.where("act_type='BlogComment' and act_id =#{@article.id}").first + if user_activity + user_activity.updated_at = Time.now + user_activity.save + end attachments = Attachment.attach_files(@blogComment, params[:attachments]) render_attachment_warning_if_needed(@blogComment) #@article.save diff --git a/app/controllers/homework_common_controller.rb b/app/controllers/homework_common_controller.rb index 7793ef097..55807886b 100644 --- a/app/controllers/homework_common_controller.rb +++ b/app/controllers/homework_common_controller.rb @@ -217,7 +217,12 @@ class HomeworkCommonController < ApplicationController #评分设置 def score_rule_set - + if params[:user_activity_id] + @user_activity_id = params[:user_activity_id] + else + @user_activity_id = -1 + end + @is_in_course = params[:is_in_course] end private diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index f2f10d5b6..742a02337 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -29,12 +29,12 @@ class RepositoriesController < ApplicationController menu_item :repository menu_item :settings, :only => [:new, :create, :edit, :update, :destroy, :committers] default_search_scope :changesets - + before_filter :find_project_by_project_id, :only => [:new, :create, :newrepo] before_filter :find_repository, :only => [:edit, :update, :destroy, :committers] - before_filter :find_project_repository, :except => [:new, :create, :newcreate, :edit, :update, :destroy, :committers, :newrepo] + before_filter :find_project_repository, :except => [:new, :create, :newcreate, :edit, :update, :destroy, :committers, :newrepo,:to_gitlab] before_filter :find_changeset, :only => [:revision, :add_related_issue, :remove_related_issue] - before_filter :authorize , :except => [:newrepo,:newcreate,:fork] + before_filter :authorize , :except => [:newrepo,:newcreate,:fork, :to_gitlab] accept_rss_auth :revisions # hidden repositories filter // 隐藏代码过滤器 before_filter :check_hidden_repo, :only => [:show, :stats, :revisions, :revision, :diff ] @@ -42,7 +42,7 @@ class RepositoriesController < ApplicationController include RepositoriesHelper helper :project_score #@root_path = RepositoriesHelper::ROOT_PATH - + rescue_from Redmine::Scm::Adapters::CommandFailed, :with => :show_error_command_failed def new @@ -62,8 +62,8 @@ class RepositoriesController < ApplicationController end end - - + + def newrepo scm = params[:repository_scm] || (Redmine::Scm::Base.all & Setting.enabled_scm).first @repository = Repository.factory(scm) @@ -76,23 +76,23 @@ class RepositoriesController < ApplicationController render :layout => 'base_projects' end end - + def fork @repository_url = params[:repository_url] - + # @repository.url # system "htpasswd -mb "+@root_path+"user.passwd "+params[:repository][:identifier]+" "+@upasswd # system "echo -e '"+params[:project_id]+"-"+params[:repository][:identifier]+"-write:"+ - # " "+params[:repository][:identifier]+"' >> "+@root_path+"group.passwd" - system "git clone --bare "+@repository_url + # " "+params[:repository][:identifier]+"' >> "+@root_path+"group.passwd" + system "git clone --bare "+@repository_url # system "mv "+@project_path+"/hooks/post-update{.sample,}" # system "chmod a+x "+@project_path+"/hooks/post-update" # system "."+@project_path+"/hooks/post-update" # system "echo -e 'Allow from all \n Order Deny,Allow \n "+ - # " \n"+ - # "Require group "+params[:project_id]+"-"+params[:repository][:identifier]+"-write \n "+ - # " \n ' >>"+ - # @project_path+"/.htaccess" + # " \n"+ + # "Require group "+params[:project_id]+"-"+params[:repository][:identifier]+"-write \n "+ + # " \n ' >>"+ + # @project_path+"/.htaccess" flash[:notice] = l(:label_notice_fork_successed) @repositories = @project.repositories render :action => 'show', :layout => 'base_projects' @@ -115,77 +115,36 @@ update } def create - if params[:repository_scm].to_s == 'Gitlab' - # add by nwb - # 增加对gitlab版本库的支持 - attrs = pickup_extra_info - @repository = Repository.factory('Git') - @repository.safe_attributes = params[:repository] - if attrs[:attrs_extra].keys.any? - @repository.merge_extra_info(attrs[:attrs_extra]) - end - @repository.project = @project - if request.post? && @repository.save - redirect_to settings_project_url(@project, :tab => 'repositories') - else - redirect_to settings_project_url(@project, :tab => 'repositories') - end - else # 原逻辑 - ##xianbo - @root_path=RepositoriesHelper::ROOT_PATH - @repository_name=User.current.login.to_s+"/"+params[:repository][:identifier]+".git" - @project_path=@root_path+"htdocs/"+@repository_name - @repository_tag=params[:repository][:upassword] || params[:repository][:password] - @repo_name=User.current.login.to_s+"_"+params[:repository][:identifier] - logger.info "htpasswd -mb "+@root_path+"htdocs/user.passwd "+@repo_name+": "+@repository_tag - logger.info "the value of create repository"+@root_path+": "+@repository_name+": "+@project_path+": "+@repo_name - attrs = pickup_extra_info - if((@repository_tag!="")&¶ms[:repository_scm]=="Git") - params[:repository][:url]=@project_path - end - ###xianbo - @repository = Repository.factory(params[:repository_scm]) - @repository.safe_attributes = params[:repository] - if attrs[:attrs_extra].keys.any? - @repository.merge_extra_info(attrs[:attrs_extra]) - end - - @repository.project = @project - if request.post? && @repository.save - if(params[:repository_scm]=="Git") - system "htpasswd -mb "+@root_path+"htdocs/user.passwd "+@repo_name+" "+@repository_tag - system "echo -e '"+@repo_name+"-write:"+ - " "+@repo_name+"' >> "+@root_path+"htdocs/group.passwd" - system "mkdir "+@root_path+"htdocs/"+User.current.login.to_s - system "git init --bare "+@project_path - system "mv "+@project_path+"/hooks/post-update{.sample,}" - system "chmod a+x "+@project_path+"/hooks/post-update" - system "echo -e 'Allow from all \n Order Deny,Allow \n "+ - " \n"+ - "Require group "+@repo_name+"-write \n "+ - " \n ' >> "+ - @root_path+"htdocs/"+ @repository_name+"/.htaccess" - system "cd "+@project_path+" ;git update-server-info" - - File.open(@project_path+"/hooks/post-update", "w+") do |f| - f.write(HOOK_TEMPLATE) - end - - @repository.update_attributes(:login => User.current.login.to_s) - end - redirect_to settings_project_url(@project, :tab => 'repositories',:repository_error_message=>@repository.errors.full_messages) - else if(@repository_tag.blank?) - #render :action => 'newrepo', :layout =>'base_projects' - redirect_to settings_project_url(@project, :tab => 'repositories',:repository => "pswd_is_null",:repository_error_message=>@repository.errors.full_messages) - else - redirect_to settings_project_url(@project, :tab => 'repositories',:repository => @repository,:repository_error_message=>@repository.errors.full_messages) - end - end - - + attrs = pickup_extra_info + @repository = Repository.factory('Git') + @repository.safe_attributes = params[:repository] + if attrs[:attrs_extra].keys.any? + @repository.merge_extra_info(attrs[:attrs_extra]) + end + @repository.project = @project + @repository.type = 'Repository::Gitlab' + @repository.url = @repository.identifier + if request.post? && @repository.save + g = ::Gitlab.client + gid = @project.owner.gid + gproject = g.create_project(@repository.identifier, + path: @repository.identifier, + description: @project.description, + wiki_enabled: false, + wall_enabled: false, + issues_enabled: false, + snippets_enabled: false, + public: false, + user_id: gid + ) + @project.gpid = gproject.id + @project.save! + redirect_to settings_project_url(@project, :tab => 'repositories') + else + redirect_to settings_project_url(@project, :tab => 'repositories',:repository_error_message=>@repository.errors.full_messages) end end - + def edit end @@ -228,15 +187,17 @@ update # Build a hash with repository usernames as keys and corresponding user ids as values @repository.committer_ids = params[:committers].values.inject({}) {|h, c| h[c.first] = c.last; h} flash[:notice] = l(:notice_successful_update) - redirect_to settings_project_url(@project, :tab => 'repositories') + respond_to do |format| + format.html{ + render :layout => "base_projects" + } + end elsif request.get? - respond_to do |format| - format.html{ - render :layout => "base_projects" - } - end - - + respond_to do |format| + format.html{ + render :layout => "base_projects" + } + end end end @@ -247,6 +208,16 @@ update redirect_to settings_project_url(@project, :tab => 'repositories') end + def to_gitlab + @project = Project.find(params[:project_id]) + @repository = Repository.find(params[:id]) + s = Trustie::Gitlab::Sync.new + s.sync_project(@project, path: params[:repo_name], import_url: @repository.url) + @repository.type = 'Repository::Gitlab' + @repository.save + redirect_to :controller => 'repositories', :action => 'show', :id => @project.id, to: 'gitlab' + end + def show ## TODO: the below will move to filter, done. if !User.current.member_of?(@project) @@ -256,19 +227,23 @@ update end end - if params[:to] == 'gitlab' - g = Gitlab.client - g.post('/session', body: {email: User.current.mail, password: User.current.hashed_password}) - redirect_to "http://192.168.41.130:3000/gitlab-org/gitlab-shell/tree/master" + unless @repository.gitlab? + # redirect_to to_gitlab_project_repository_path(@project, @repository) + render :to_gitlab return end #if( !User.current.member_of?(@project) || @project.hidden_repo) @repository.fetch_changesets if Setting.autofetch_changesets? && @path.empty? + # g = Gitlab.client + # project = g.project(20) + # rr = g.trees(project.id, @path) + # r = g.get ("/projects/#{@project}/repository/tree") + # :name, :path, :kind, :size, :lastrev, :changeset @entries = @repository.entries(@path, @rev) + # @trees = g.trees(project, @path) @changeset = @repository.find_changeset_by_name(@rev) - #@project_path_cut = RepositoriesHelper::PROJECT_PATH_CUT #@ip = RepositoriesHelper::REPO_IP_ADDRESS @@ -276,15 +251,22 @@ update @entries ? render(:partial => 'dir_list_content') : render(:nothing => true) else #Modified by young - # (show_error_not_found; return) unless @entries + # (show_error_not_found; return) unless @entries @changesets = @repository.latest_changesets(@path, @rev) + @changesets_count = @repository.latest_changesets(@path, @rev).count + @changesets_latest_coimmit = @changesets.first @properties = @repository.properties(@path, @rev) @repositories = @project.repositories @course_tag = params[:course] project_path_cut = RepositoriesHelper::PROJECT_PATH_CUT ip = RepositoriesHelper::REPO_IP_ADDRESS - @repos_url = "http://"+@repository.login.to_s+"_"+@repository.identifier.to_s+"@"+ip.to_s+ - @repository.url.slice(project_path_cut, @repository.url.length).to_s + gitlab_address = RepositoriesHelper::REPO_GITLAB_ADDRESS + if @repository.type.to_s=="Repository::Gitlab" + @repos_url = "http://"+gitlab_address.to_s+"/"+@project.owner.to_s+"/"+@repository.identifier+"."+"git" + else + @repos_url = "http://"+@repository.login.to_s+"_"+@repository.identifier.to_s+"@"+ip.to_s+ + @repository.url.slice(project_path_cut, @repository.url.length).to_s + end if @course_tag == 1 render :action => 'show', :layout => 'base_courses' else @@ -310,10 +292,10 @@ update per_page_option, params['page'] @changesets = @repository.changesets. - limit(@changeset_pages.per_page). - offset(@changeset_pages.offset). - includes(:user, :repository, :parents). - all + limit(@changeset_pages.per_page). + offset(@changeset_pages.offset). + includes(:user, :repository, :parents). + all respond_to do |format| format.html { render :layout => 'base_projects' } @@ -327,6 +309,7 @@ update def entry entry_and_raw(false) + render :layout => 'base_projects' end def entry_and_raw(is_raw) @@ -339,8 +322,8 @@ update @content = @repository.cat(@path, @rev) (show_error_not_found; return) unless @content if is_raw || - (@content.size && @content.size > Setting.file_max_size_displayed.to_i.kilobyte) || - ! is_entry_text_data?(@content, @path) + (@content.size && @content.size > Setting.file_max_size_displayed.to_i.kilobyte) || + ! is_entry_text_data?(@content, @path) # Force the download send_opt = { :filename => filename_for_content_disposition(@path.split('/').last) } send_type = Redmine::MimeType.of(@path) @@ -423,8 +406,8 @@ update filename = "changeset_r#{@rev}" filename << "_r#{@rev_to}" if @rev_to send_data @diff.join, :filename => "#{filename}.diff", - :type => 'text/x-patch', - :disposition => 'attachment' + :type => 'text/x-patch', + :disposition => 'attachment' else @diff_type = params[:type] || User.current.pref[:diff_type] || 'inline' @diff_type = 'inline' unless %w(inline sbs).include?(@diff_type) @@ -435,7 +418,7 @@ update User.current.preference.save end @cache_key = "repositories/diff/#{@repository.id}/" + - Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}-#{current_language}") + Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}-#{current_language}") unless read_fragment(@cache_key) @diff = @repository.diff(@path, @rev, @rev_to) unless @diff @@ -462,16 +445,16 @@ update def graph data = nil case params[:graph] - when "commits_per_month" - data = graph_commits_per_month(@repository) - when "commits_per_author" - data = graph_commits_per_author(@repository) - when "author_commits_per_month" - data = graph_author_commits_per_month(@repository) - when "author_commits_six_month" - data = author_commits_six_month(@repository) - when "author_code_six_months" - data = author_code_six_month(@repository) + when "commits_per_month" + data = graph_commits_per_month(@repository) + when "commits_per_author" + data = graph_commits_per_author(@repository) + when "author_commits_per_month" + data = graph_author_commits_per_month(@repository) + when "author_commits_six_month" + data = author_commits_six_month(@repository) + when "author_code_six_months" + data = author_code_six_month(@repository) end if data headers["Content-Type"] = "image/svg+xml" @@ -551,14 +534,14 @@ update @date_from = @date_to << 11 @date_from = Date.civil(@date_from.year, @date_from.month, 1) commits_by_day = Changeset.count( - :all, :group => :commit_date, - :conditions => ["repository_id = ? AND commit_date BETWEEN ? AND ?", repository.id, @date_from, @date_to]) + :all, :group => :commit_date, + :conditions => ["repository_id = ? AND commit_date BETWEEN ? AND ?", repository.id, @date_from, @date_to]) commits_by_month = [0] * 12 commits_by_day.each {|c| commits_by_month[(@date_to.month - c.first.to_date.month) % 12] += c.last } changes_by_day = Change.count( - :all, :group => :commit_date, :include => :changeset, - :conditions => ["#{Changeset.table_name}.repository_id = ? AND #{Changeset.table_name}.commit_date BETWEEN ? AND ?", repository.id, @date_from, @date_to]) + :all, :group => :commit_date, :include => :changeset, + :conditions => ["#{Changeset.table_name}.repository_id = ? AND #{Changeset.table_name}.commit_date BETWEEN ? AND ?", repository.id, @date_from, @date_to]) changes_by_month = [0] * 12 changes_by_day.each {|c| changes_by_month[(@date_to.month - c.first.to_date.month) % 12] += c.last } @@ -566,26 +549,26 @@ update 12.times {|m| fields << month_name(((Date.today.month - 1 - m) % 12) + 1)} graph = SVG::Graph::Bar.new( - :height => 300, - :width => 600, - :fields => fields.reverse, - :stack => :side, - :scale_integers => true, - :step_x_labels => 2, - :show_data_values => true, - :graph_title => l(:label_commits_per_month), - :show_graph_title => true + :height => 300, + :width => 600, + :fields => fields.reverse, + :stack => :side, + :scale_integers => true, + :step_x_labels => 2, + :show_data_values => true, + :graph_title => l(:label_commits_per_month), + :show_graph_title => true ) # 具状图 graph.add_data( - :data => commits_by_month[0..11].reverse, - :title => l(:label_revision_plural) + :data => commits_by_month[0..11].reverse, + :title => l(:label_revision_plural) ) graph.add_data( - :data => changes_by_month[0..11].reverse, - :title => l(:label_change_plural) + :data => changes_by_month[0..11].reverse, + :title => l(:label_change_plural) ) graph.burn @@ -610,23 +593,23 @@ update fields = fields.collect {|c| c.gsub(%r{<.+@.+>}, '') } graph = SVG::Graph::BarHorizontal.new( - :height => 400, - :width => 600, - :fields => fields, - :stack => :side, - :scale_integers => true, - :show_data_values => true, - :rotate_y_labels => false, - :graph_title => l(:label_commits_per_author), - :show_graph_title => true + :height => 400, + :width => 600, + :fields => fields, + :stack => :side, + :scale_integers => true, + :show_data_values => true, + :rotate_y_labels => false, + :graph_title => l(:label_commits_per_author), + :show_graph_title => true ) graph.add_data( - :data => commits_data, - :title => l(:label_revision_plural) + :data => commits_data, + :title => l(:label_revision_plural) ) graph.add_data( - :data => changes_data, - :title => l(:label_change_plural) + :data => changes_data, + :title => l(:label_change_plural) ) graph.burn end @@ -637,7 +620,7 @@ update @date_from = @date_to << 12 @date_from = Date.civil(@date_from.year, @date_from.month, @date_from.day) commits_by_author = Changeset.count(:all, :group => :committer, - :conditions => ["#{Changeset.table_name}.repository_id = ? AND #{Changeset.table_name}.commit_date BETWEEN ? AND ?", repository.id, @date_from, @date_to]) + :conditions => ["#{Changeset.table_name}.repository_id = ? AND #{Changeset.table_name}.commit_date BETWEEN ? AND ?", repository.id, @date_from, @date_to]) commits_by_author = commits_by_author.to_a.sort! {|x, y| x.last <=> y.last}.last(25) fields = commits_by_author.collect {|r| r.first} diff --git a/app/controllers/student_work_controller.rb b/app/controllers/student_work_controller.rb index 529c5ea72..25782ec4b 100644 --- a/app/controllers/student_work_controller.rb +++ b/app/controllers/student_work_controller.rb @@ -108,6 +108,7 @@ class StudentWorkController < ApplicationController else @stundet_works = [] end + @student_work_count = (search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").joins(:user).where("users.id in #{student_in_group}").order("#{@order} #{@b_sort}"),@name).count else if @is_teacher || @homework.homework_detail_manual.nil? #老师 || 超级管理员 显示所有列表 @stundet_works = search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").order("#{@order} #{@b_sort}"),@name @@ -128,6 +129,7 @@ class StudentWorkController < ApplicationController else @stundet_works = [] end + @student_work_count = (search_homework_member @homework.student_works.select("student_works.*,IF(final_score is null,null,final_score - absence_penalty - late_penalty) as score").order("#{@order} #{@b_sort}"),@name).count end @score = @b_sort == "desc" ? "asc" : "desc" @@ -456,14 +458,14 @@ class StudentWorkController < ApplicationController student_work.save end end - respond_to do |format| - format.html{ - if params[:student_path] - redirect_to student_work_index_url(:homework => @homework.id) - else - redirect_to user_homeworks_user_path(User.current.id) - end - } + if params[:student_path] + redirect_to student_work_index_url(:homework => @homework.id) + else + @user_activity_id = params[:user_activity_id] + @is_in_course = params[:is_in_course] + respond_to do |format| + format.js + end end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 6d049783e..175c8ce51 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -949,10 +949,19 @@ class UsersController < ApplicationController when "current_user" @user_activities = UserActivity.where("user_id = #{@user.id} and ((container_type = 'Project' and container_id in #{user_project_ids} and act_type in #{project_types}) or (container_type = 'Course' and container_id in #{user_course_ids} and act_type in #{course_types}))").order('updated_at desc').limit(10).offset(@page * 10) else - @user_activities = UserActivity.where("(container_type = 'Project' and container_id in #{user_project_ids} and act_type in #{project_types}) or (container_type = 'Course' and container_id in #{user_course_ids} and act_type in #{course_types}) or (container_type = 'Principal' and act_type= '#{principal_types}' and container_id = #{@user.id})").order('updated_at desc').limit(10).offset(@page * 10) + blog_ids = "("+@user.blog.id.to_s+","+User.watched_by(@user.id).map{|u| u.blog.id}.join(',')+")" + @user_activities = UserActivity.where("(container_type = 'Project' and container_id in #{user_project_ids} and act_type in #{project_types})" + + "or (container_type = 'Course' and container_id in #{user_course_ids} and act_type in #{course_types}) "+ + "or (container_type = 'Principal' and act_type= '#{principal_types}' and container_id = #{@user.id}) " + + "or (container_type = 'Blog' and act_type= 'BlogComment' and container_id in #{blog_ids})").order('updated_at desc').limit(10).offset(@page * 10) end else - @user_activities = UserActivity.where("(container_type = 'Project' and container_id in #{user_project_ids} and act_type in #{project_types}) or (container_type = 'Course' and container_id in #{user_course_ids} and act_type in #{course_types})or (container_type = 'Principal' and act_type= '#{principal_types}' and container_id = #{@user.id})").order('updated_at desc').limit(10).offset(@page * 10) + # @user_activities = UserActivity.where("(container_type = 'Project' and container_id in #{user_project_ids} and act_type in #{project_types}) or (container_type = 'Course' and container_id in #{user_course_ids} and act_type in #{course_types})or (container_type = 'Principal' and act_type= '#{principal_types}' and container_id = #{@user.id})").order('updated_at desc').limit(10).offset(@page * 10) + blog_ids = "("+@user.blog.id.to_s+","+User.watched_by(@user.id).map{|u| u.blog.id}.join(',')+")" + @user_activities = UserActivity.where("(container_type = 'Project' and container_id in #{user_project_ids} and act_type in #{project_types})" + + "or (container_type = 'Course' and container_id in #{user_course_ids} and act_type in #{course_types}) "+ + "or (container_type = 'Principal' and act_type= '#{principal_types}' and container_id = #{@user.id}) " + + "or (container_type = 'Blog' and act_type= 'BlogComment' and container_id in #{blog_ids})").order('updated_at desc').limit(10).offset(@page * 10) end # @user_activities = paginateHelper @user_activities,500 @type = params[:type] diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 7289d534b..84364b4f6 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -2355,16 +2355,16 @@ module ApplicationHelper else #学生显示提交作品、修改作品等按钮 work = cur_user_works_for_homework homework if work.nil? - link_to "提交作品", new_student_work_path(:homework => homework.id),:class => 'c_blue' + link_to "提交作品(#{homework.student_works.count})", new_student_work_path(:homework => homework.id),:class => 'c_blue' else if homework.homework_detail_manual && homework.homework_detail_manual.comment_status == 2 #匿评作业,且作业状态不是在开启匿评之前 link_to "作品匿评", student_work_index_path(:homework => homework.id), :class => 'c_blue', :title => "开启匿评后不可修改作品" elsif homework.homework_detail_manual && homework.homework_detail_manual.comment_status == 3 link_to "匿评结束", student_work_index_path(:homework => homework.id), :class => 'c_blue', :title => "匿评已结束" elsif homework.homework_type == 2 #编程作业不能修改作品 - link_to "修改作品", new_student_work_path(:homework => homework.id),:class => 'c_blue' + link_to "修改作品(#{homework.student_works.count})", new_student_work_path(:homework => homework.id),:class => 'c_blue' else - link_to "修改作品", edit_student_work_path(work.id),:class => 'c_blue' + link_to "修改作品(#{homework.student_works.count})", edit_student_work_path(work.id),:class => 'c_blue' end end end diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb index 710b7488f..ba99fe454 100644 --- a/app/helpers/repositories_helper.rb +++ b/app/helpers/repositories_helper.rb @@ -25,6 +25,7 @@ module RepositoriesHelper end PROJECT_PATH_CUT = 40 REPO_IP_ADDRESS = Setting.host_repository + REPO_GITLAB_ADDRESS = "git.trustie.net" def format_revision(revision) if revision.respond_to? :format_identifier @@ -34,6 +35,10 @@ module RepositoriesHelper end end + def repository_creater rep + repository_creater = User.find_by_login(rep.login) unless rep.login.nil? + end + def truncate_at_line_break(text, length = 255) if text text.gsub(%r{^(.{#{length}}[^\n]*)\n.+$}m, '\\1...') diff --git a/app/models/blog_comment.rb b/app/models/blog_comment.rb index 92970b663..9bb28ddd8 100644 --- a/app/models/blog_comment.rb +++ b/app/models/blog_comment.rb @@ -7,7 +7,8 @@ class BlogComment < ActiveRecord::Base acts_as_tree :counter_cache => :comments_count, :order => "#{BlogComment.table_name}.sticky desc ,#{BlogComment.table_name}.created_on ASC" acts_as_attachable belongs_to :last_reply, :class_name => 'BlogComment', :foreign_key => 'last_comment_id' - + # 虚拟关联 + has_many :user_acts, :class_name => 'UserAcivity',:as =>:act acts_as_watchable validates_presence_of :title, :content @@ -15,6 +16,31 @@ class BlogComment < ActiveRecord::Base #validate :cannot_reply_to_locked_comment, :on => :create safe_attributes 'title', 'content',"sticky", "locked" + after_save :add_user_activity + before_destroy :destroy_user_activity + + #在个人动态里面增加当前动态 + def add_user_activity + if self.parent_id.nil? #只有发博文才插入动态 + user_activity = UserActivity.where("act_type = '#{self.class.to_s}' and act_id = '#{self.id}'").first + if user_activity + user_activity.save + else + user_activity = UserActivity.new + user_activity.act_id = self.id + user_activity.act_type = self.class.to_s + user_activity.container_type = "Blog" + user_activity.container_id = self.blog_id + user_activity.user_id = self.author_id + user_activity.save + end + end + end + + def destroy_user_activity + user_activity = UserActivity.where("act_type = '#{self.class.to_s}' and act_id = '#{self.id}'") + user_activity.destroy_all + end def deleted_attach_able_by? user (user && user.logged? && (self.author == user) ) || user.admin? end diff --git a/app/models/member.rb b/app/models/member.rb index 655c79895..ed7ee81e6 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -34,6 +34,7 @@ class Member < ActiveRecord::Base after_destroy :delete_ivite_list + def role end diff --git a/app/models/member_role.rb b/app/models/member_role.rb index 67122a636..4d493cb27 100644 --- a/app/models/member_role.rb +++ b/app/models/member_role.rb @@ -35,8 +35,11 @@ class MemberRole < ActiveRecord::Base !inherited_from.nil? end + include Trustie::Gitlab::ManageMember + private + def remove_member_if_empty if member.roles.empty? member.destroy diff --git a/app/models/project.rb b/app/models/project.rb index fcc96c404..fd1012fa0 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -770,7 +770,8 @@ class Project < ActiveRecord::Base 'project_type', 'dts_test', 'attachmenttype', - 'enterprise_name' + 'enterprise_name', + 'gpid' @@ -853,6 +854,10 @@ class Project < ActiveRecord::Base end end + def owner + User.find(self.user_id) + end + private def after_parent_changed(parent_was) @@ -1167,5 +1172,7 @@ class Project < ActiveRecord::Base :forge_act_id => self.id,:forge_act_type => "ProjectCreateInfo") fa.save! end + + end diff --git a/app/models/repository.rb b/app/models/repository.rb index 5680f05a7..94b7905c6 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -57,6 +57,11 @@ class Repository < ActiveRecord::Base safe_attributes 'url', :if => lambda {|repository, user| repository.new_record?} + + def gitlab? + self.type == 'Repository::Gitlab' + end + def repo_create_validation unless Setting.enabled_scm.include?(self.class.name.demodulize) errors.add(:type, :invalid) diff --git a/app/models/repository/gitlab.rb b/app/models/repository/gitlab.rb new file mode 100644 index 000000000..5ec725660 --- /dev/null +++ b/app/models/repository/gitlab.rb @@ -0,0 +1,259 @@ +#coding=utf-8 + +require 'redmine/scm/adapters/git_adapter' + +class Repository::Gitlab < Repository + + attr_protected :root_url + validates_presence_of :url + + def self.human_attribute_name(attribute_key_name, *args) + attr_name = attribute_key_name.to_s + if attr_name == "url" + attr_name = "path_to_repository" + end + super(attr_name, *args) + end + + def self.scm_adapter_class + Redmine::Scm::Adapters::GitlabAdapter + end + + def self.scm_name + 'Gitlab' + end + + def commits(authors, start_date, end_date, branch='master') + scm.commits(authors, start_date, end_date,branch).map {|commit| + [commit[:author], commit[:num]] + } + end + + def report_last_commit + extra_report_last_commit + end + + def extra_report_last_commit + return false if extra_info.nil? + v = extra_info["extra_report_last_commit"] + return false if v.nil? + v.to_s != '0' + end + + def supports_directory_revisions? + true + end + + def supports_revision_graph? + true + end + + def repo_log_encoding + 'UTF-8' + end + + # Returns the identifier for the given git changeset + def self.changeset_identifier(changeset) + changeset.scmid + end + + # Returns the readable identifier for the given git changeset + def self.format_changeset_identifier(changeset) + changeset.revision[0, 8] + end + + def branches + scm.branches + end + + def tags + scm.tags + end + + def default_branch + scm.default_branch + rescue Exception => e + logger.error "git: error during get default branch: #{e.message}" + nil + end + + def find_changeset_by_name(name) + if name.present? + changesets.where(:revision => name.to_s).first || + changesets.where('scmid LIKE ?', "#{name}%").first + end + end + + def entries(path=nil, identifier=nil) + entries = scm.entries(path, identifier, :report_last_commit => extra_report_last_commit) + load_entries_changesets(entries) + entries + end + + # With SCMs that have a sequential commit numbering, + # such as Subversion and Mercurial, + # Redmine is able to be clever and only fetch changesets + # going forward from the most recent one it knows about. + # + # However, Git does not have a sequential commit numbering. + # + # In order to fetch only new adding revisions, + # Redmine needs to save "heads". + # + # In Git and Mercurial, revisions are not in date order. + # Redmine Mercurial fixed issues. + # * Redmine Takes Too Long On Large Mercurial Repository + # http://www.redmine.org/issues/3449 + # * Sorting for changesets might go wrong on Mercurial repos + # http://www.redmine.org/issues/3567 + # + # Database revision column is text, so Redmine can not sort by revision. + # Mercurial has revision number, and revision number guarantees revision order. + # Redmine Mercurial model stored revisions ordered by database id to database. + # So, Redmine Mercurial model can use correct ordering revisions. + # + # Redmine Mercurial adapter uses "hg log -r 0:tip --limit 10" + # to get limited revisions from old to new. + # But, Git 1.7.3.4 does not support --reverse with -n or --skip. + # + # The repository can still be fully reloaded by calling #clear_changesets + # before fetching changesets (eg. for offline resync) + def fetch_changesets + scm_brs = branches + return if scm_brs.nil? || scm_brs.empty? + + h1 = extra_info || {} + h = h1.dup + repo_heads = scm_brs.map{ |br| br.scmid } + h["heads"] ||= [] + prev_db_heads = h["heads"].dup + if prev_db_heads.empty? + prev_db_heads += heads_from_branches_hash + end + return if prev_db_heads.sort == repo_heads.sort + + h["db_consistent"] ||= {} + if changesets.count == 0 + h["db_consistent"]["ordering"] = 1 + merge_extra_info(h) + self.save + elsif ! h["db_consistent"].has_key?("ordering") + h["db_consistent"]["ordering"] = 0 + merge_extra_info(h) + self.save + end + save_revisions(prev_db_heads, repo_heads) + end + + def save_revisions(prev_db_heads, repo_heads) + h = {} + opts = {} + opts[:reverse] = true + opts[:excludes] = prev_db_heads + opts[:includes] = repo_heads + + revisions = scm.revisions('', nil, nil, opts) + return if revisions.blank? + + # Make the search for existing revisions in the database in a more sufficient manner + # + # Git branch is the reference to the specific revision. + # Git can *delete* remote branch and *re-push* branch. + # + # $ git push remote :branch + # $ git push remote branch + # + # After deleting branch, revisions remain in repository until "git gc". + # On git 1.7.2.3, default pruning date is 2 weeks. + # So, "git log --not deleted_branch_head_revision" return code is 0. + # + # After re-pushing branch, "git log" returns revisions which are saved in database. + # So, Redmine needs to scan revisions and database every time. + # + # This is replacing the one-after-one queries. + # Find all revisions, that are in the database, and then remove them from the revision array. + # Then later we won't need any conditions for db existence. + # Query for several revisions at once, and remove them from the revisions array, if they are there. + # Do this in chunks, to avoid eventual memory problems (in case of tens of thousands of commits). + # If there are no revisions (because the original code's algorithm filtered them), + # then this part will be stepped over. + # We make queries, just if there is any revision. + limit = 100 + offset = 0 + revisions_copy = revisions.clone # revisions will change + while offset < revisions_copy.size + recent_changesets_slice = changesets.find( + :all, + :conditions => [ + 'scmid IN (?)', + revisions_copy.slice(offset, limit).map{|x| x.scmid} + ] + ) + # Subtract revisions that redmine already knows about + recent_revisions = recent_changesets_slice.map{|c| c.scmid} + revisions.reject!{|r| recent_revisions.include?(r.scmid)} + offset += limit + end + + revisions.each do |rev| + transaction do + # There is no search in the db for this revision, because above we ensured, + # that it's not in the db. + save_revision(rev) + end + end + h["heads"] = repo_heads.dup + merge_extra_info(h) + self.save + end + private :save_revisions + + def save_revision(rev) + parents = (rev.parents || []).collect{|rp| find_changeset_by_name(rp)}.compact + changeset = Changeset.create( + :repository => self, + :revision => rev.identifier, + :scmid => rev.scmid, + :committer => rev.author, + :committed_on => rev.time, + :comments => rev.message, + :parents => parents + ) + unless changeset.new_record? + rev.paths.each { |change| changeset.create_change(change) } + end + changeset + end + private :save_revision + + def heads_from_branches_hash + h1 = extra_info || {} + h = h1.dup + h["branches"] ||= {} + h['branches'].map{|br, hs| hs['last_scmid']} + end + + def latest_changesets(path,rev,limit=10) + revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false) + return [] if revisions.nil? || revisions.empty? + + changesets.find( + :all, + :conditions => [ + "scmid IN (?)", + revisions.map!{|c| c.scmid} + ] + ) + end + + def clear_extra_info_of_changesets + return if extra_info.nil? + v = extra_info["extra_report_last_commit"] + write_attribute(:extra_info, nil) + h = {} + h["extra_report_last_commit"] = v + merge_extra_info(h) + self.save + end + private :clear_extra_info_of_changesets +end diff --git a/app/models/role.rb b/app/models/role.rb index f363b52bf..8bf5ebc05 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -77,6 +77,27 @@ class Role < ActiveRecord::Base self.givable[3..5] end + GUEST = 10 + REPORTER = 20 + DEVELOPER = 30 + MASTER = 40 + OWNER = 50 + def to_gitlab_role + case self.position + when 1,2 + GUEST + when 5 + REPORTER + when 4 + DEVELOPER + when 3 + MASTER + else + GUEST + end + end + + # Copies attributes from another role, arg can be an id or a Role def copy_from(arg, options={}) return unless arg.present? diff --git a/app/models/user.rb b/app/models/user.rb index 7aaae3492..b75b67a1a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -209,7 +209,7 @@ class User < Principal validates_inclusion_of :mail_notification, :in => MAIL_NOTIFICATION_OPTIONS.collect(&:first), :allow_blank => true validate :validate_password_length # validates_email_realness_of :mail - before_create :set_mail_notification + before_create :set_mail_notification, :sync_gitlab_user before_save :update_hashed_password before_destroy :remove_references_before_destroy # added by fq @@ -358,7 +358,7 @@ class User < Principal name end ## end - + #added by nie def count_new_journal_reply count = self.journal_reply.count @@ -1079,6 +1079,17 @@ class User < Principal end + private + def sync_gitlab_user + user = self + g = Gitlab.client + u = g.get("/users?search=#{user.mail}").first + unless u + u = g.create_user(user.mail, user.password, name: user.show_name, username: user.login, confirm: "true") + self.gid = u.id + puts "create user #{user.login}" + end + end end diff --git a/app/views/blog_comments/reply.js.erb b/app/views/blog_comments/reply.js.erb index 7ebe4d077..f8ed4bb24 100644 --- a/app/views/blog_comments/reply.js.erb +++ b/app/views/blog_comments/reply.js.erb @@ -1,2 +1,7 @@ +<% if @in_user_center%> + $("#user_activity_<%= @user_activity_id%>").replaceWith("<%= escape_javascript(render :partial => 'users/user_blog', :locals => {:activity => @article,:user_activity_id =>@user_activity_id}) %>"); + init_activity_KindEditor_data(<%= @user_activity_id%>,"","87%"); +<% else%> $("#user_activity_<%= @user_activity_id%>").replaceWith("<%= escape_javascript(render :partial => 'blogs/article', :locals => {:activity => @article,:user_activity_id =>@user_activity_id,:first_user_activity =>@first_user_activity,:page => @page}) %>"); -init_activity_KindEditor_data(<%= @user_activity_id%>,"","87%"); \ No newline at end of file +init_activity_KindEditor_data(<%= @user_activity_id%>,"","87%"); +<% end %> \ No newline at end of file diff --git a/app/views/blogs/_article.html.erb b/app/views/blogs/_article.html.erb index 943d21852..33a3201c0 100644 --- a/app/views/blogs/_article.html.erb +++ b/app/views/blogs/_article.html.erb @@ -1,10 +1,36 @@ -
-
+
+
<%= link_to image_tag(url_to_avatar(activity.author), :width => "50", :height => "50"), user_path(activity.author_id,:host=>Setting.host_user), :alt => "用户头像" %>
-
+ <% if activity.author.id == User.current.id%> + + <%end%> +
<% if activity.try(:author).try(:realname) == ' ' %> <%= link_to activity.try(:author), user_path(activity.author_id,:host=>Setting.host_user), :class => "newsBlue mr15" %> <% else %> @@ -13,6 +39,7 @@ TO <%= link_to activity.blog.name+" | 博客", user_blogs_path(:user_id=>activity.author_id,:host=>Setting.host_user), :class => "newsBlue ml15 mr5"%>
+