diff --git a/.metadata/.plugins/org.eclipse.debug.core/.launches/Firefox - Internal Server.launch b/.metadata/.plugins/org.eclipse.debug.core/.launches/Firefox - Internal Server.launch index f21eed9f2..678ced8a0 100644 --- a/.metadata/.plugins/org.eclipse.debug.core/.launches/Firefox - Internal Server.launch +++ b/.metadata/.plugins/org.eclipse.debug.core/.launches/Firefox - Internal Server.launch @@ -2,6 +2,7 @@ + diff --git a/.metadata/.plugins/org.eclipse.debug.core/.launches/Internet Explorer - Internal Server.launch b/.metadata/.plugins/org.eclipse.debug.core/.launches/Internet Explorer - Internal Server.launch index 2134fa92c..f7b0844d8 100644 --- a/.metadata/.plugins/org.eclipse.debug.core/.launches/Internet Explorer - Internal Server.launch +++ b/.metadata/.plugins/org.eclipse.debug.core/.launches/Internet Explorer - Internal Server.launch @@ -2,6 +2,7 @@ + diff --git a/.rspec b/.rspec new file mode 100644 index 000000000..8c18f1abd --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--format documentation +--color diff --git a/app/controllers/account_controller.rb b/app/controllers/account_controller.rb index 6c95294d7..69c2d3002 100644 --- a/app/controllers/account_controller.rb +++ b/app/controllers/account_controller.rb @@ -345,7 +345,10 @@ class AccountController < ApplicationController if user.save and token.save UserStatus.create(:user_id => user.id, :changsets_count => 0, :watchers_count => 0) Mailer.register(token).deliver + + flash[:notice] = l(:notice_account_register_done) + render action: 'email_valid', locals: {:mail => user.mail} else yield if block_given? diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 2721c57c7..06e5dac30 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -156,7 +156,16 @@ class ApplicationController < ActionController::Base user end end + def try_to_autologin1 + # auto-login feature starts a new session + user = User.try_to_autologin(params[:token]) + if user + start_user_session(user) + end + user + + end # Sets the logged in user def logged_user=(user) reset_session @@ -248,7 +257,30 @@ class ApplicationController < ActionController::Base end end end + def authorize1(ctrl = params[:controller], action = params[:action],token = params[:token], global = false) + + if(!User.current.logged? && !token.nil?) + User.current =try_to_autologin1 + end + allowed = authorize_allowed(params[:controller], params[:action],global) + + if allowed + true + else + if @project && @project.archived? + render_403 :message => :notice_not_authorized_archived_project + else + deny_access + end + end + end + def auth_login1(token = params[:token]) + if(!User.current.logged? && !token.nil?) + + User.current =try_to_autologin1 + end + end def authorize_allowed(ctrl = params[:controller], action = params[:action], global = false) #modify by NWB if @project @@ -261,6 +293,7 @@ class ApplicationController < ActionController::Base allowed end def authorize_attachment_download(ctrl = params[:controller], action = params[:action], global = false) + case @attachment.container_type when "Memo" allowed = User.current.allowed_to?(:memos_attachments_download,nil,:global => true) @@ -289,6 +322,37 @@ class ApplicationController < ActionController::Base end end + def authorize_attachment_download1(ctrl = params[:controller], action = params[:action],token = params[:token], global = false) + if(!User.current.logged? && !token.nil?) + User.current = try_to_autologin1 + end + case @attachment.container_type + when "Memo" + allowed = User.current.allowed_to?(:memos_attachments_download,nil,:global => true) + when "Message" + if @project + allowed = User.current.allowed_to?(:projects_attachments_download,@project,:global => false) + elsif @course + allowed = User.current.allowed_to?(:course_attachments_download, @course, :global => false) + end + when "contest" + return true + when "Course" + allowed = User.current.allowed_to?(:course_attachments_download, @course, :global => false) + else + return true + end + + if allowed + true + else + if @project && @project.archived? + render_403 :message => :notice_not_authorized_archived_project + else + deny_access + end + end + end def authorize_course(ctrl = params[:controller], action = params[:action], global = false) allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @course || @course, :global => global) if allowed @@ -789,4 +853,29 @@ class ApplicationController < ActionController::Base @organizer = WebFooterOranizer.first @companies = WebFooterCompany.all end + + + + + def password_authentication + user, last_login_on = User.try_to_login(params[:user_name], params[:password]) + + + successful_authentication(user, last_login_on) + + end + + + def successful_authentication(user, last_login_on) + logger.info "Successful authentication for '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}" + # Valid user + self.logged_user = user + # generate a key and set cookie if autologin + if params[:autologin] && Setting.autologin? + set_autologin_cookie(user) + end + call_hook(:controller_account_success_authentication_after, {:user => user }) + + + end end diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb index 952dcdf44..2c6a002b4 100644 --- a/app/controllers/attachments_controller.rb +++ b/app/controllers/attachments_controller.rb @@ -17,11 +17,12 @@ class AttachmentsController < ApplicationController layout "users_base" + before_filter :find_project, :only => [:show, :download, :thumbnail, :destroy, :delete_homework]#, :except => [:upload, :autocomplete] before_filter :file_readable, :read_authorize, :only => [:show, :thumbnail]#Modified by young before_filter :delete_authorize, :only => :destroy before_filter :authorize_global, :only => :upload - before_filter :authorize_attachment_download, :only => :download + before_filter :authorize_attachment_download1, :only => :download #before_filter :login_without_softapplication, only: [:download] accept_api_auth :show, :download, :upload require 'iconv' diff --git a/app/controllers/bids_controller.rb b/app/controllers/bids_controller.rb index ec2fb7d77..7e5894b83 100644 --- a/app/controllers/bids_controller.rb +++ b/app/controllers/bids_controller.rb @@ -9,6 +9,8 @@ class BidsController < ApplicationController menu_item :homework_statistics, :only => :homework_statistics menu_item :edit, :only => :edit + + before_filter :can_show_course,only: [] before_filter :can_show_contest,only: [] #Ended by young diff --git a/app/controllers/courses_controller.rb b/app/controllers/courses_controller.rb index 1a8506b12..edd3f1b9d 100644 --- a/app/controllers/courses_controller.rb +++ b/app/controllers/courses_controller.rb @@ -19,7 +19,7 @@ class CoursesController < ApplicationController before_filter :authorize_course, :only => [:show, :settings, :edit, :update, :modules, :close, :reopen, :view_homework_attaches, :course] before_filter :authorize_course_global, :only => [:view_homework_attaches, :new,:create] before_filter :require_admin, :only => [:copy, :archive, :unarchive, :destroy, :calendar] - before_filter :toggleCourse, only: [:finishcourse, :restartcourse] + before_filter :toggleCourse, :only => [:finishcourse, :restartcourse] before_filter :require_login, :only => [:join, :unjoin] #before_filter :allow_join, :only => [:join] @@ -809,9 +809,9 @@ class CoursesController < ApplicationController # modify by nwb # 添加私密性判断 if User.current.member_of_course?(@course)|| User.current.admin? - events = @activity.events(@date_from, @date_to) + events = @activity.events(@days, @course.created_at) else - events = @activity.events(@date_from, @date_to, :is_public => 1) + events = @activity.events(@days, @course.created_at, :is_public => 1) end # 无新动态时,显示老动态 diff --git a/app/controllers/forums_controller.rb b/app/controllers/forums_controller.rb index cd51d2e58..54b8c6305 100644 --- a/app/controllers/forums_controller.rb +++ b/app/controllers/forums_controller.rb @@ -13,6 +13,44 @@ class ForumsController < ApplicationController include SortHelper PageLimit = 20 + def create_feedback + if User.current.logged? + @memo = Memo.new(params[:memo]) + @memo.forum_id = "1" + @memo.author_id = User.current.id + #@forum = @memo.forum + respond_to do |format| + if @memo.save + format.html { redirect_to forum_path(@memo.forum) } + else + sort_init 'updated_at', 'desc' + sort_update 'created_at' => "#{Memo.table_name}.created_at", + 'replies' => "#{Memo.table_name}.replies_count", + 'updated_at' => "COALESCE (last_replies_memos.created_at, #{Memo.table_name}.created_at)" + + @topic_count = @forum.topics.count + @topic_pages = Paginator.new @topic_count, per_page_option, params['page'] + @memos = @forum.topics. + reorder("#{Memo.table_name}.sticky DESC"). + includes(:last_reply). + limit(@topic_pages.per_page). + offset(@topic_pages.offset). + order(sort_clause). + preload(:author, {:last_reply => :author}). + all + + flash.now[:error] = "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}" + # back_error_page = @memo.parent_id.nil? ? forum_path(@forum) : forum_memo_path(@forum, @memo.parent_id) + format.html { render action: :show, layout: 'base_forums' }#, error: "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}" } + format.json { render json: @memo.errors, status: :unprocessable_entity } + end + end + else + respond_to do |format| + format.html { redirect_to signin_path } + end + end + end def create_memo @memo = Memo.new(params[:memo]) @@ -49,16 +87,15 @@ class ForumsController < ApplicationController end end end - + def index @offset, @limit = api_offset_and_limit({:limit => 10}) @forums_all = Forum.reorder("sticky DESC") @forums_count = @forums_all.count @forums_pages = Paginator.new @forums_count, @limit, params['page'] - @offset ||= @forums_pages.offset - @forums = @forums_all.offset(@offset).limit(@limit).all + @forums = @forums_all.offset(@offset).limit(@limit).all #@forums = Forum.all respond_to do |format| format.html # index.html.erb @@ -86,14 +123,12 @@ class ForumsController < ApplicationController preload(:author, {:last_reply => :author}). all - - # @offset, @limit = api_offset_and_limit({:limit => 10}) # @forum = Forum.find(params[:id]) # @memos_all = @forum.topics # @topic_count = @memos_all.count # @topic_pages = Paginator.new @topic_count, @limit, params['page'] - + # @offset ||= @topic_pages.offset # @memos = @memos_all.offset(@offset).limit(@limit).all respond_to do |format| @@ -125,12 +160,15 @@ class ForumsController < ApplicationController def create @forum = Forum.new(params[:forum]) @forum.creator_id = User.current.id + if @forum.save + respond_to do |format| - respond_to do |format| - if @forum.save - format.html { redirect_to @forum, notice: l(:label_forum_create_succ) } - format.json { render json: @forum, status: :created, location: @forum } - else + format.html { redirect_to @forum, notice: l(:label_forum_create_succ) } + format.json { render json: @forum, status: :created, location: @forum } + end + + else + respond_to do |format| flash.now[:error] = "#{l :label_forum_create_fail}: #{@forum.errors.full_messages[0]}" format.html { render action: "new" } format.json { render json: @forum.errors, status: :unprocessable_entity } @@ -176,7 +214,6 @@ class ForumsController < ApplicationController @forums_count = @forums_all.count @forums_pages = Paginator.new @forums_count, @limit, params['page'] - @offset ||= @forums_pages.offset @forums = @forums_all.offset(@offset).limit(@limit).all respond_to do |format| @@ -197,7 +234,7 @@ class ForumsController < ApplicationController @memos_all = @forum.topics.where("subject LIKE ?", q) @topic_count = @memos_all.count @topic_pages = Paginator.new @topic_count, @limit, params['page'] - + @offset ||= @topic_pages.offset @memos = @memos_all.offset(@offset).limit(@limit).all respond_to do |format| @@ -205,20 +242,17 @@ class ForumsController < ApplicationController render 'show', :layout => 'base_forums' } format.json { render json: @forum } - end + end end - - private - def find_forum_if_available @forum = Forum.find(params[:id]) if params[:id] rescue ActiveRecord::RecordNotFound render_404 nil - end + end def authenticate_user_edit find_forum_if_available diff --git a/app/controllers/homework_attach_controller.rb b/app/controllers/homework_attach_controller.rb index 8b9bf9099..8e69d1d72 100644 --- a/app/controllers/homework_attach_controller.rb +++ b/app/controllers/homework_attach_controller.rb @@ -26,6 +26,7 @@ class HomeworkAttachController < ApplicationController get_not_batch_homework_list sort,direction, @bid.id @cur_page = params[:page] || 1 @cur_type = 1 + @cur_sort,@cur_direction = params[:sort] || "s_socre", params[:direction] || "desc" @direction = direction == 'asc'? 'desc' : 'asc' respond_to do |format| format.js @@ -433,7 +434,7 @@ class HomeworkAttachController < ApplicationController #添加留言 def addjours @is_teacher,@is_anonymous_comments,@m_score = params[:is_teacher]=="true",params[:is_anonymous_comments]=="true",params[:stars_value] - @cur_page,@cur_type = params[:cur_page] || 1,params[:cur_type] || 5 + @cur_page,@cur_type = params[:page] || 1,params[:cur_type] || 5 @homework = HomeworkAttach.find(params[:homework_id]) @stars_reates = @homework.rates(:quality) homework = @homework @@ -479,7 +480,7 @@ class HomeworkAttachController < ApplicationController if @cur_type == "1" #如果当前是老师未批列表,需要刷新整个作业列表界面 @bid = @homework.bid - get_not_batch_homework_list "s_socre","desc",@homework.bid_id + get_not_batch_homework_list params[:cur_sort] || "s_socre",params[:cur_direction] || "desc",@homework.bid_id elsif @cur_type == "2" #老师已批列表 @result_homework = HomeworkAttach.find_by_sql("SELECT homework_attaches.*, (SELECT stars FROM seems_rateable_rates WHERE rateable_type = 'HomeworkAttach' AND rateable_id = homework_attaches.id AND is_teacher_score = 1 AND stars IS NOT NULL ORDER BY updated_at DESC limit 0,1) AS t_score, diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index f3c2b199c..c0d83fdcd 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -19,10 +19,13 @@ class IssuesController < ApplicationController layout 'base_projects'#Added by young default_search_scope :issues + before_filter :authorize1, :only => [:show] before_filter :find_issue, :only => [:show, :edit, :update] before_filter :find_issues, :only => [:bulk_edit, :bulk_update, :destroy] before_filter :find_project, :only => [:new, :create, :update_form] + #before_filter :authorize, :except => [:index, :show] before_filter :authorize, :except => [:index] + before_filter :find_optional_project, :only => [:index] before_filter :check_for_default_issue_status, :only => [:new, :create] before_filter :build_new_issue_from_params, :only => [:new, :create, :update_form] @@ -107,7 +110,7 @@ class IssuesController < ApplicationController end def show - + @journals = @issue.journals.includes(:user, :details).reorder("#{Journal.table_name}.id ASC").all @journals.each_with_index {|j,i| j.indice = i+1} @journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project) diff --git a/app/controllers/my_controller.rb b/app/controllers/my_controller.rb index 308cb62ca..8f00c49cd 100644 --- a/app/controllers/my_controller.rb +++ b/app/controllers/my_controller.rb @@ -17,6 +17,9 @@ class MyController < ApplicationController layout "users_base" + # edit + before_filter :auth_login1, :only => [:account] + # before_filter :require_login helper :issues @@ -150,6 +153,7 @@ class MyController < ApplicationController File.delete(diskfile1) end end + end # Destroys user's account diff --git a/app/controllers/poll_controller.rb b/app/controllers/poll_controller.rb new file mode 100644 index 000000000..4abddaa5e --- /dev/null +++ b/app/controllers/poll_controller.rb @@ -0,0 +1,419 @@ +class PollController < ApplicationController + before_filter :find_poll_and_course, :only => [:edit,:update,:destroy,:show,:statistics_result,:create_poll_question,:commit_poll,:commit_answer,:publish_poll,:republish_poll,:poll_result] + before_filter :find_container, :only => [:new,:create, :index] + before_filter :is_member_of_course, :only => [:index,:show,:poll_result] + before_filter :is_course_teacher, :only => [:new,:create,:edit,:update,:destroy,:publish_poll,:republish_poll] + include PollHelper + def index + if @course + @is_teacher = User.current.allowed_to?(:as_teacher,@course) + if @is_teacher + polls = Poll.where("polls_type = 'Course' and polls_group_id = #{@course.id}") + else + polls = Poll.where("polls_type = 'Course' and polls_group_id = #{@course.id} and polls_status = 2") + end + @polls = paginateHelper polls,20 #分页 + respond_to do |format| + format.html{render :layout => 'base_courses'} + end + elsif @project + #项目的问卷调查相关代码 + end + end + + def show + @poll = Poll.find params[:id] + #已提交问卷的用户不能再访问该界面 + if has_commit_poll?(@poll.id,User.current.id) && (!User.current.admin?) + render_403 + else + @can_edit_poll = (!has_commit_poll?(@poll.id,User.current.id)) || User.current.admin? + @percent = get_percent(@poll,User.current) + poll_questions = @poll.poll_questions + @poll_questions = paginateHelper poll_questions,5 #分页 + respond_to do |format| + format.html {render :layout => 'base_courses'} + end + end + end + + def new + if @course + option = { + :polls_name => "", + :polls_type => @course.class.to_s, + :polls_group_id => @course.id, + :polls_status => 1, + :user_id => User.current.id, + :published_at => Time.now, + :closed_at => Time.now, + :polls_description => "" + } + @poll = Poll.create option + if @poll + redirect_to edit_poll_url @poll.id + end + elsif @project + #项目的问卷调查相关代码 + end + end + + def create + + end + + def edit + respond_to do |format| + format.html{render :layout => 'base_courses'} + end + end + + def update + @poll.polls_name = params[:polls_name].empty? ? l(:label_poll_title) : params[:polls_name] + @poll.polls_description = params[:polls_description].empty? ? l(:label_poll_description) : params[:polls_description] + if @poll.save + respond_to do |format| + format.js + end + else + render_404 + end + end + + def destroy + if @poll && @poll.destroy + respond_to do |format| + format.js + end + end + end + + def statistics_result + @poll = Poll.find(params[:id]) + poll_questions = @poll.poll_questions + @poll_questions = paginateHelper poll_questions, 5 + respond_to do |format| + format.html{render :layout => 'base_courses'} + end + end + + def get_poll_totalcount poll_question + @total_questions_count = poll_question.poll_votes.count + end + + def get_poll_everycount poll_answer + @every_answer_count = poll_answer.poll_votes.count + end + + + #添加题目 + def create_poll_question + question_title = params[:poll_questions_title].nil? || params[:poll_questions_title].empty? ? l(:label_enter_single_title) : params[:poll_questions_title] + option = { + :is_necessary => (params[:is_necessary]=="true" ? 1 : 0), + :question_title => question_title, + :question_type => params[:question_type] || 1, + :question_number => @poll.poll_questions.count + 1 + } + @poll_questions = @poll.poll_questions.new option + if params[:question_answer] + for i in 1..params[:question_answer].count + answer = (params[:question_answer].values[i-1].nil? || params[:question_answer].values[i-1].empty?) ? l(:label_new_answer) : params[:question_answer].values[i-1] + question_option = { + :answer_position => i, + :answer_text => answer + } + @poll_questions.poll_answers.new question_option + end + end + if @poll_questions.save + respond_to do |format| + format.js + end + end + end + + #修改题目 + def update_poll_question + @poll_question = PollQuestion.find params[:poll_question] + #@poll = @poll_question.poll + @poll_question.is_necessary = params[:is_necessary]=="true" ? 1 : 0 + @poll_question.question_title = params[:poll_questions_title].nil? || params[:poll_questions_title].empty? ? l(:label_enter_single_title) : params[:poll_questions_title] + ################处理选项 + if params[:question_answer] + @poll_question.poll_answers.each do |answer| + answer.destroy unless params[:question_answer].keys.include? answer.id.to_s + end + for i in 1..params[:question_answer].count + question = @poll_question.poll_answers.find_by_id params[:question_answer].keys[i-1] + answer = (params[:question_answer].values[i-1].nil? || params[:question_answer].values[i-1].empty?) ? l(:label_new_answer) : params[:question_answer].values[i-1] + if question + question.answer_position = i + question.answer_text = answer + question.save + else + question_option = { + :answer_position => i, + :answer_text => answer + } + @poll_question.poll_answers.new question_option + end + end + end + @poll_question.save + respond_to do |format| + format.js + end + end + + #删除题目 + def delete_poll_question + @poll_question = PollQuestion.find params[:poll_question] + @poll = @poll_question.poll + poll_questions = @poll.poll_questions.where("question_number > #{@poll_question.question_number}") + poll_questions.each do |question| + question.question_number -= 1 + question.save + end + if @poll_question && @poll_question.destroy + respond_to do |format| + format.js + end + end + end + + #发布问卷 + def publish_poll + @poll.polls_status = 2 + @poll.published_at = Time.now + if @poll.save + if params[:is_remote] + redirect_to poll_index_url(:polls_type => "Course", :polls_group_id => @course.id) + else + respond_to do |format| + format.js + end + end + end + end + + #提交答案 + def commit_answer + pq = PollQuestion.find(params[:poll_question_id]) + if has_commit_poll?(@poll.id,User.current.id) && (!User.current.admin?) + render :json => {:text => "failure"} + return + end + if pq.question_type == 1 + #单选题 + pv = PollVote.find_by_poll_question_id_and_user_id(params[:poll_question_id],User.current.id) + if pv.nil? + #尚未答该题,添加答案 + pv = PollVote.new + pv.user_id = User.current.id + pv.poll_question_id = params[:poll_question_id] + end + #修改该题对应答案 + pv.poll_answer_id = params[:poll_answer_id] + if pv.save + #保存成功返回成功信息及当前以答题百分比 + @percent = get_percent(@poll,User.current) + render :json => {:text => "ok" ,:percent => format("%.2f" ,@percent)} + else + #返回失败信息 + render :json => {:text => "failure"} + end + elsif pq.question_type == 2 + #多选题 + pv = PollVote.find_by_poll_answer_id_and_user_id(params[:poll_answer_id],User.current.id) + if pv.nil? + #尚未答该题,添加答案 + pv = PollVote.new + pv.user_id = User.current.id + pv.poll_question_id = params[:poll_question_id] + pv.poll_answer_id = params[:poll_answer_id] + if pv.save + @percent = get_percent(@poll,User.current) + render :json => {:text => "true",:percent => format("%.2f" ,@percent)} + else + render :json => {:text => "failure"} + end + else + #pv不为空,则当前选项之前已被选择,再次点击则是不再选择该项,故删除该答案 + if pv.delete + @percent = get_percent(@poll,User.current) + render :json => {:text => "false" ,:percent => format("%.2f" ,@percent)} + else + render :json => {:text => "failure"} + end + end + elsif pq.question_type == 3 || pq.question_type == 4 + #单行文本,多行文本题 + pv = PollVote.find_by_poll_question_id_and_user_id(params[:poll_question_id],User.current.id) + if pv.nil? + #pv为空之前尚未答题,添加答案 + if params[:vote_text].nil? || params[:vote_text].blank? + #用户提交空答案,视作不作答 + @percent = get_percent(@poll,User.current) + render :json => {:text => pv.vote_text,:percent => format("%.2f" ,@percent)} + else + #添加答案 + pv = PollVote.new + pv.user_id = User.current.id + pv.poll_question_id = params[:poll_question_id] + pv.vote_text = params[:vote_text] + if pv.save + @percent = get_percent(@poll,User.current) + render :json => {:text => pv.vote_text,:percent => format("%.2f" ,@percent)} + else + render :json => {:text => "failure"} + end + end + else + #pv不为空说明用户之前已作答 + if params[:vote_text].nil? || params[:vote_text].blank? + #用户提交空答案,视为删除答案 + if pv.delete + @percent = get_percent(@poll,User.current) + render :json => {:text => pv.vote_text,:percent => format("%.2f" ,@percent)} + else + render :json => {:text => "failure"} + end + else + #用户修改答案 + pv.vote_text = params[:vote_text] + if pv.save + @percent = get_percent(@poll,User.current) + render :json => {:text => pv.vote_text,:percent => format("%.2f" ,@percent)} + else + render :json => {:text => "failure"} + end + end + end + + else + render :json => {:text => "failure"} + end + end + + #提交问卷 + def commit_poll + @uncomplete_question = get_uncomplete_question(@poll,User.current) + if @uncomplete_question.count < 1 + pu = get_poll_user(@poll.id,User.current.id) + pu.user_id = User.current.id + pu.poll_id = @poll.id + if pu.save + #redirect_to poll_index_path(:polls_group_id => @course.id,:polls_type => 'Course') + @status = 0 #提交成功 + else + @status = 2 #未知错误 + end + else + @status = 1 #有未做得必答题 + end + respond_to do |format| + format.js + end + end + + #重新发布问卷 + def republish_poll + @poll.poll_questions.each do |poll_question| + poll_question.poll_votes.destroy_all + end + @poll.poll_users.destroy_all + @poll.polls_status = 1 + @poll.save + respond_to do |format| + format.js + end + end + + #显示某个学生某份问卷的填写结果 + def poll_result + @poll_questions = paginateHelper @poll.poll_questions,5 + respond_to do |format| + format.html{render :layout => 'base_courses'} + end + end + + private + def find_poll_and_course + @poll = Poll.find params[:id] + @course = Course.find @poll.polls_group_id + rescue Exception => e + render_404 + end + + def find_container + if params[:polls_type] && params[:polls_group_id] + case params[:polls_type] + when "Course" + @course = Course.find_by_id params[:polls_group_id] + when "Project" + @project = Project.find_by_id params[:polls_group_id] + end + else + render_404 + end + end + + def is_member_of_course + render_403 unless(@course && User.current.member_of_course?(@course)) + end + + def is_course_teacher + @is_teacher = User.current.allowed_to?(:as_teacher,@course) + render_403 unless(@course && @is_teacher) + end + + #获取未完成的题目 + def get_uncomplete_question poll,user + necessary_questions = poll.poll_questions.where("#{PollQuestion.table_name}.is_necessary = 1") + uncomplete_question = [] + necessary_questions.each do |question| + answers = get_user_answer(question,user) + if answers.nil? || answers.count < 1 + uncomplete_question << question + end + end + uncomplete_question + end + + #获取用户对某个问题的答案 + def get_user_answer(question,user) + user_answer = question.poll_votes.where("#{PollVote.table_name}.user_id = #{user.id}") + user_answer + end + + def get_complete_question(poll,user) + questions = poll.poll_questions + complete_question = [] + questions.each do |question| + answers = get_user_answer(question,user) + if !(answers.nil? || answers.count < 1) + complete_question << question + end + end + complete_question + end + + def get_percent poll,user + complete_count = get_complete_question(poll,user).count + if poll.poll_questions.count == 0 + return 0 + else + return (complete_count.to_f / poll.poll_questions.count.to_f)*100 + end + end + + #PollUser记录用户是否已提交问卷有对应的记录则已提交,没有则新建一个 + def get_poll_user poll_id,user_id + pu = PollUser.find_by_poll_id_and_user_id(poll_id,user_id) + if pu.nil? + pu = PollUser.new + end + pu + end +end \ No newline at end of file diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index fa0beb311..58af43da3 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -15,8 +15,10 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. class UsersController < ApplicationController + layout :setting_layout #Added by young + before_filter :auth_login1, :only => [:show, :user_activities] menu_item :activity menu_item :user_information, :only => :info menu_item :user_course, :only => :user_courses @@ -29,6 +31,9 @@ class UsersController < ApplicationController #Ended by young + # edit + + # before_filter :can_show_course, :only => [:user_courses,:user_homeworks] before_filter :require_admin, :except => [:show, :index, :search, :tag_save, :tag_saveEx,:user_projects, :user_newfeedback, :user_comments, :watch_bids, :watch_contests, :info, :user_watchlist, :user_fanslist,:update, :user_courses, :user_homeworks, :watch_projects, :show_score, :topic_score_index, :project_score_index, @@ -41,7 +46,7 @@ class UsersController < ApplicationController :activity_score_index, :influence_score_index, :score_index,:show_new_score, :topic_new_score_index, :project_new_score_index, :activity_new_score_index, :influence_new_score_index, :score_new_index,:user_projects_index] before_filter :auth_user_extension, only: :show - before_filter :rest_user_score, only: :show + #before_filter :rest_user_score, only: :show #before_filter :select_entry, only: :user_projects accept_api_auth :index, :show, :create, :update, :destroy,:tag_save , :tag_saveEx @@ -129,7 +134,7 @@ class UsersController < ApplicationController end def show_new_score - render :layout => false + render :layout => 'users_base' end # end @@ -188,9 +193,9 @@ class UsersController < ApplicationController for user in @watcher events << Redmine::Activity::Fetcher.new(User.current, :author => @user).events(nil, nil, :limit => 30) end - - - + + + @events_by_day = events.group_by(&:event_date) unless User.current.admin? diff --git a/app/controllers/zipdown_controller.rb b/app/controllers/zipdown_controller.rb index 3612bf7a4..b329e4c27 100644 --- a/app/controllers/zipdown_controller.rb +++ b/app/controllers/zipdown_controller.rb @@ -7,17 +7,6 @@ class ZipdownController < ApplicationController SAVE_FOLDER = "#{Rails.root}/files" OUTPUT_FOLDER = "#{Rails.root}/tmp/archiveZip" - #通过作业Id找到项目(课程) - def find_project_by_bid_id - obj_class = params[:obj_class] - obj_id = params[:obj_id] - obj = obj_class.constantize.find(obj_id) - case obj.class.to_s.to_sym - when :Bid - @project = obj.courses[0] - end - end - def assort if params[:obj_class] == "Bid" bid = Bid.find params[:obj_id] @@ -33,8 +22,8 @@ class ZipdownController < ApplicationController end send_file zipfile, :filename => bid.name + ".zip", :type => detect_content_type(zipfile) if zipfile - rescue Exception => e - render file: 'public/no_file_found.html' + #rescue Exception => e + # render file: 'public/no_file_found.html' end #下载某一学生的作业的所有文件 @@ -56,12 +45,23 @@ class ZipdownController < ApplicationController else render_403 end - rescue => e - render file: 'public/file_not_found.html' + #rescue => e + # render file: 'public/file_not_found.html' end private + #通过作业Id找到项目(课程) + def find_project_by_bid_id + obj_class = params[:obj_class] + obj_id = params[:obj_id] + obj = obj_class.constantize.find(obj_id) + case obj.class.to_s.to_sym + when :Bid + @project = obj.courses[0] + end + end + def zip_bid(bid) # Todo: User Access Controll bid_homework_path = [] @@ -75,16 +75,21 @@ class ZipdownController < ApplicationController def zip_homework_by_user(homeattach) homeworks_attach_path = [] + not_exist_file = [] # 需要将所有homework.attachments遍历加入zip # 并且返回zip路径 homeattach.attachments.each do |attach| - homeworks_attach_path << attach.diskfile#.to_s.slice((length+1)..-1) + if File.exist?(attach.diskfile) + homeworks_attach_path << attach.diskfile + else + not_exist_file << attach.filename + end end - zipping("#{homeattach.user.lastname}#{homeattach.user.firstname}_#{((homeattach.user.user_extensions.nil? || homeattach.user.user_extensions.student_id.nil?) ? "" : homeattach.user.user_extensions.student_id)}_#{Time.now.to_i.to_s}.zip", homeworks_attach_path, OUTPUT_FOLDER, true) + zipping("#{homeattach.user.lastname}#{homeattach.user.firstname}_#{((homeattach.user.user_extensions.nil? || homeattach.user.user_extensions.student_id.nil?) ? "" : homeattach.user.user_extensions.student_id)}_#{Time.now.to_i.to_s}.zip", homeworks_attach_path, OUTPUT_FOLDER, true, not_exist_file) end - def zipping(zip_name_refer, files_paths, output_path, is_attachment=false) + def zipping(zip_name_refer, files_paths, output_path, is_attachment=false, not_exist_file=[]) # 输入待打包的文件列表,已经打包文件定位到ouput_path ic = Iconv.new('GBK//IGNORE', 'UTF-8//IGNORE') input_filename = files_paths @@ -96,19 +101,31 @@ class ZipdownController < ApplicationController Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile| input_filename.each do |filename| + flag = true + index = 1 rename_file = ic.iconv( (File.basename(filename)) ).to_s rename_file = ic.iconv( filename_to_real( File.basename(filename))).to_s if is_attachment - zipfile.add(rename_file, filename) + begin + zipfile.add(rename_file, filename) + flag = false + rescue Exception => e + zipfile.get_output_stream('FILE_NOTICE.txt') do |os| + os.write l(:label_file_exist) + end + next + end + end + unless not_exist_file.empty? + zipfile.get_output_stream('FILE_LOST.txt') do |os| + os.write l(:label_file_lost) + not_exist_file.join(',').to_s + end end - #zipfile.get_output_stream('ReadMe') do |os| - # os.write 'Homeworks' - #end end zipfile_name - rescue Errno => e - logger.error "[zipdown#zipping] ===> #{e}" - @error = e + #rescue Errno => e + # logger.error "[zipdown#zipping] ===> #{e}" + # @error = e end def detect_content_type(name) content_type = Redmine::MimeType.of(name) @@ -119,4 +136,4 @@ class ZipdownController < ApplicationController attach = Attachment.find_by_disk_filename(name) attach.filename end -end +end \ No newline at end of file diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 8c2542aa2..7efa02503 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -140,10 +140,12 @@ module ApplicationHelper # * :text - Link text (default to attachment filename) # * :download - Force download (default: false) def link_to_attachment(attachment, options={}) + token = options[:token] if options[:token] text = options.delete(:text) || attachment.filename route_method = options.delete(:download) ? :download_named_attachment_path : :named_attachment_path html_options = options.slice!(:only_path) url = send(route_method, attachment, attachment.filename, options) + url << "?token=#{token}" unless token.nil? link_to text, url, html_options end @@ -1593,6 +1595,12 @@ module ApplicationHelper end s end + + def get_memo + @new_memo = Memo.new + #@new_memo.subject = "有什么想说的,尽管来咆哮吧~~" + @public_forum = Forum.find(1) + end private diff --git a/app/helpers/courses_helper.rb b/app/helpers/courses_helper.rb index 096ce7ad8..22eb9bfae 100644 --- a/app/helpers/courses_helper.rb +++ b/app/helpers/courses_helper.rb @@ -20,7 +20,7 @@ module CoursesHelper # 返回教师数量,即roles表中定义的Manager def teacherCount project - searchTeacherAndAssistant(project).count + project.members.count - studentCount(project).to_i # or # searchTeacherAndAssistant(project).count end @@ -111,10 +111,14 @@ module CoursesHelper #garble count # end + #获取课程所有成员 + def course_all_member course + course.members + end # 学生人数计算 # add by nwb def studentCount course - searchStudent(course).count.to_s#course.student.count + course.student.count.to_s#course.student.count end #课程成员数计算 @@ -561,12 +565,13 @@ module CoursesHelper def course_in_current_or_next_term course is_current_term = false is_next_term = false - if course.time == Time.now.year && course.term == cur_course_term + year_now = Time.now.month < 3 ? Time.now.year - 1:Time.now.year + if course.time == year_now && course.term == cur_course_term is_current_term = true end - if cur_course_term == "秋季学期" && course.time == (Time.now.year + 1) && course.term == "春季学期" + if cur_course_term == "秋季学期" && course.time == (year_now + 1) && course.term == "春季学期" is_next_term = true - elsif cur_course_term == "春季学期" && course.time == Time.now.year && course.term == "秋季学期" + elsif cur_course_term == "春季学期" && course.time == year_now && course.term == "秋季学期" is_next_term = true end is_current_term || is_next_term diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index 8390fc61c..6a708051a 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -224,6 +224,7 @@ module IssuesHelper # as an array of strings def details_to_strings(details, no_html=false, options={}) options[:only_path] = (options[:only_path] == false ? false : true) + options[:token] = options[:token] if options[:token] strings = [] values_by_field = {} details.each do |detail| @@ -312,7 +313,11 @@ module IssuesHelper old_value = content_tag("del", old_value) if detail.old_value and detail.value.blank? if detail.property == 'attachment' && !value.blank? && atta = Attachment.find_by_id(detail.prop_key) # Link to the attachment if it has not been removed - value = link_to_attachment(atta, :download => true, :only_path => options[:only_path]) + if options[:token].nil? + value = link_to_attachment(atta, :download => true, :only_path => options[:only_path]) + else + value = link_to_attachment(atta, :download => true, :only_path => options[:only_path], :token => options[:token]) + end if options[:only_path] != false && atta.is_text? value += link_to( image_tag('magnifier.png'), diff --git a/app/helpers/poll_helper.rb b/app/helpers/poll_helper.rb new file mode 100644 index 000000000..60d82c096 --- /dev/null +++ b/app/helpers/poll_helper.rb @@ -0,0 +1,77 @@ +# encoding: utf-8 +# +# Redmine - project management software +# Copyright (C) 2006-2013 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +module PollHelper + #判断选项是否被选中 + def answer_be_selected?(answer,user) + pv = answer.poll_votes.where("#{PollVote.table_name}.user_id = #{user.id} ") + if !pv.nil? && pv.count > 0 + true + else + false + end + end + + #获取文本题答案 + def get_anwser_vote_text(question_id,user_id) + pv = PollVote.find_by_poll_question_id_and_user_id(question_id,user_id) + if pv.nil? + '' + else + pv.vote_text + end + end + + #判断用户是否已经提交了问卷 + def has_commit_poll?(poll_id,user_id) + pu = PollUser.find_by_poll_id_and_user_id(poll_id,user_id) + if pu.nil? + false + else + true + end + end + + #统计答题百分比,统计结果保留两位小数 + def statistics_result_percentage(e, t) + e = e.to_f + t = t.to_f + t == 0 ? 0 : format("%.2f", e*100/t) + end + + #多选的时候查询去重 + def total_answer id + total = PollVote.find_by_sql("SELECT distinct(user_id) FROM `poll_votes` where poll_question_id = #{id}").count + end + + #页面体型显示 + def options_show pq + case pq + when 1 + "单选题" + when 2 + "多选题" + when 3 + "单行主观题" + else + "多行主观题" + end + end + +end \ No newline at end of file diff --git a/app/models/contest.rb b/app/models/contest.rb index ad54e8fb4..650e363a8 100644 --- a/app/models/contest.rb +++ b/app/models/contest.rb @@ -15,7 +15,8 @@ class Contest < ActiveRecord::Base has_many :praise_tread, as: :praise_tread_object, dependent: :destroy has_many :contestnotifications, :dependent => :destroy, :include => :author - + + acts_as_attachable diff --git a/app/models/course.rb b/app/models/course.rb index 196e7168d..c11f66d49 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -38,7 +38,7 @@ class Course < ActiveRecord::Base validates_presence_of :password, :term,:name validates_format_of :class_period, :with =>/^[1-9]\d*$/ - validates_format_of :name,:with =>/^[a-zA-Z0-9_\u4e00-\u9fa5]+$/ + validates_format_of :name,:with =>/^[^ ]+[a-zA-Z0-9_\u4e00-\u9fa5\s\S]+$/ validates_length_of :description, :maximum => 10000 before_save :self_validate after_create :create_board_sync diff --git a/app/models/forum.rb b/app/models/forum.rb index dc1603288..e47d18b02 100644 --- a/app/models/forum.rb +++ b/app/models/forum.rb @@ -23,7 +23,7 @@ class Forum < ActiveRecord::Base acts_as_taggable scope :by_join_date, order("created_at DESC") - + after_create :send_email def reset_counters! self.class.reset_counters!(id) end @@ -38,6 +38,11 @@ class Forum < ActiveRecord::Base self.creator == user || user.admin? end + def send_email + Thread.start do + Mailer.forum_add(self).deliver if Setting.notified_events.include?('forum_add') + end + end # Updates topic_count, memo_count and last_memo_id attributes for +board_id+ def self.reset_counters!(forum_id) forum_id = forum_id.to_i diff --git a/app/models/forum_observer.rb b/app/models/forum_observer.rb new file mode 100644 index 000000000..1c514d6ab --- /dev/null +++ b/app/models/forum_observer.rb @@ -0,0 +1,8 @@ +class ForumObserver < ActiveRecord::Observer + def after_create(forum) + Thread.start do + Mailer.forum_add(forum).deliver if Setting.notified_events.include?('forum_add') + end + + end +end diff --git a/app/models/issue_observer.rb b/app/models/issue_observer.rb index 3369387ee..50cbf2a42 100644 --- a/app/models/issue_observer.rb +++ b/app/models/issue_observer.rb @@ -18,8 +18,12 @@ class IssueObserver < ActiveRecord::Observer def after_create(issue) - thread1=Thread.new do - Mailer.issue_add(issue).deliver if Setting.notified_events.include?('issue_added') - end + Thread.start do + recipients = issue.recipients + recipients.each do |rec| + Mailer.issue_add(issue,rec).deliver if Setting.notified_events.include?('issue_added') + end + end + end end diff --git a/app/models/issue_overdue.rb b/app/models/issue_overdue.rb index 5caec94c9..3002b74ef 100644 --- a/app/models/issue_overdue.rb +++ b/app/models/issue_overdue.rb @@ -20,7 +20,11 @@ class IssueOverdue < ActiveRecord::Base #发邮件 #puts "11" + issue.id.to_s #Mailer.issue_expire(issue).deliver - Mailer.issue_add(issue).deliver + recipients = issue.recipients + recipients.each do |rec| + + Mailer.issue_edit(issue,rec).deliver + end break end end diff --git a/app/models/journal_observer.rb b/app/models/journal_observer.rb index 0357fb74d..10d3f7b4b 100644 --- a/app/models/journal_observer.rb +++ b/app/models/journal_observer.rb @@ -23,8 +23,12 @@ class JournalObserver < ActiveRecord::Observer (Setting.notified_events.include?('issue_status_updated') && journal.new_status.present?) || (Setting.notified_events.include?('issue_priority_updated') && journal.new_value_for('priority_id').present?) ) - Thread.new do - Mailer.issue_edit(journal).deliver + Thread.start do + recipients = journal.recipients + recipients.each do |rec| + + Mailer.issue_edit(journal,rec).deliver + end end end end diff --git a/app/models/journals_for_message_observer.rb b/app/models/journals_for_message_observer.rb index 093002a2c..0e5f29d03 100644 --- a/app/models/journals_for_message_observer.rb +++ b/app/models/journals_for_message_observer.rb @@ -1,7 +1,9 @@ # Added by young class JournalsForMessageObserver < ActiveRecord::Observer def after_create(journals_for_message) + thread1 = Thread.start do Mailer.journals_for_message_add(User.current, journals_for_message).deliver + end end end diff --git a/app/models/mailer.rb b/app/models/mailer.rb index a7f850766..23ac36054 100644 --- a/app/models/mailer.rb +++ b/app/models/mailer.rb @@ -26,7 +26,37 @@ class Mailer < ActionMailer::Base def self.default_url_options { :host => Setting.host_name, :protocol => Setting.protocol } end - + + # 贴吧新建贴吧发送邮件 + # example Mailer.forum(forum).deliver + def forum_add(forum) + + redmine_headers 'Forum' => forum.id + @forum = forum + @author = forum.creator + recipients = forum.creator.mail + # cc = wiki_content.page.wiki.watcher_recipients - recipients + + @forum_url = url_for(:controller => 'forums', :action => 'show', :id => forum.id) + mail :to => recipients,:subject => "[ #{l(:label_forum)} : #{forum.name} #{l(:notice_successful_create)}]" + + end + + def forum_message_added(memo) + @memo = memo + redmine_headers 'Memo' => memo.id + @forum = memo.forum + @author = memo.author + recipients ||= [] + mems = memo.self_and_siblings + mems.each do |mem| + recipients << mem.author.mail unless recipients.include? mem.author.mail + end + # cc = wiki_content.page.wiki.watcher_recipients - recipients + + @memo_url = url_for(forum_memo_url(@forum, (@memo.parent_id.nil? ? @memo : @memo.parent_id))) + mail :to => recipients,:subject => "[ #{l(:label_message_plural)} : #{memo.subject} #{l(:label_memo_create_succ)}]" + end # Builds a Mail::Message object used to email recipients of the added journals for message. # 留言分为直接留言,和对留言人留言的回复 @@ -62,13 +92,13 @@ class Mailer < ActionMailer::Base course = journals_for_message.jour @author = journals_for_message.user #课程的教师 - @teachers = searchTeacherAndAssistant journals_for_message.jour + @members = course_all_member journals_for_message.jour #收件人邮箱 @recipients ||= [] - @teachers.each do |teacher| - if teacher.user.notify_about? journals_for_message + @members.each do |teacher| + @recipients << teacher.user.mail - end + end mail :to => @recipients, @@ -95,29 +125,52 @@ class Mailer < ActionMailer::Base # Example: # issue_add(issue) => Mail::Message object # Mailer.issue_add(issue).deliver => sends an email to issue recipients - def issue_add(issue) + def issue_add(issue, recipients) issue_id = issue.project_index redmine_headers 'Project' => issue.project.identifier, 'Issue-Id' => issue_id, 'Issue-Author' => issue.author.login redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to message_id issue + @author = issue.author @issue = issue - @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue.id) - recipients = issue.recipients - cc = issue.watcher_recipients - recipients - mail :to => recipients, - :cc => cc, - :subject => "[#{issue.project.name} - #{issue.tracker.name} ##{issue_id}] (#{issue.status.name}) #{issue.subject}" + user = User.find_by_mail(recipients) + + token = Token.new(:user =>user , :action => 'autologin') + token.save + @token = token + @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue.id, :token => @token.value) + + # edit + @issue_author_url = url_for(user_activities_url(@author,:token => @token.value)) + @project_url = url_for(:controller => 'projects', :action => 'show', :id => issue.project_id, :token => @token.value) + + @user_url = url_for(my_account_url(user,:token => @token.value)) + cc = nil + if recipients == issue.recipients[0] + cc = issue.watcher_recipients - issue.recipients + end + subject = "[#{issue.project.name} - #{issue.tracker.name} ##{issue_id}] (#{issue.status.name}) #{issue.subject}" + mail(:to => recipients, + :cc => cc, + :subject => subject) end + # issue.attachments.each do |attach| + # attachments["#{attach.filename}"] = File.read("#{attach.disk_filename}") + # end + # cc = issue.watcher_recipients - recipients + #mail.attachments['test'] = File.read("#{RAILS.root}/files/2015/01/150114094010_libegl.dll") + + + # Builds a Mail::Message object used to email recipients of the edited issue. # # Example: # issue_edit(journal) => Mail::Message object # Mailer.issue_edit(journal).deliver => sends an email to issue recipients - def issue_edit(journal) + def issue_edit(journal,recipients) issue = journal.journalized.reload issue_id = issue.project_index redmine_headers 'Project' => issue.project.identifier, @@ -127,18 +180,45 @@ class Mailer < ActionMailer::Base message_id journal references issue @author = journal.user - recipients = journal.recipients + + user = User.find_by_mail(recipients) + + token = Token.new(:user =>user , :action => 'autologin') + token.save + @token = token + + + # edit + @issue_author_url = url_for(:controller => 'users', :action => 'show', :id => issue.author_id, :token => @token.value) + @project_url = url_for(:controller => 'projects', :action => 'show', :id => issue.project_id, :token => @token.value) + @user_url = url_for(my_account_url(user,:token => @token.value)) + + @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue.id, :anchor => "change-#{journal.id}", :token => @token.value) + + + + # Watchers in cc - cc = journal.watcher_recipients - recipients + cc = nil + if recipients == journal.recipients[0] + cc = journal.watcher_recipients - journal.recipients + end + s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue_id}] " s << "(#{issue.status.name}) " if journal.new_value_for('status_id') s << issue.subject @issue = issue @journal = journal - @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}") - mail :to => recipients, - :cc => cc, - :subject => s + # @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}") + mail(:to => recipients, + :cc => cc, + :subject => s) + end + + def self.deliver_mailer(to,cc, subject) + mail :to => to, + :cc => cc, + :subject => subject end # 用户申请加入项目邮件通知 @@ -237,7 +317,7 @@ class Mailer < ActionMailer::Base recipients = container.notified_users.select { |user| user.allowed_to?(:view_files, container) }.collect { |u| u.mail } when 'Course' added_to_url = url_for(:controller => 'files', :action => 'index', :course_id => container) - added_to = "#{l(:label_course)}: #{container}" + added_to = "#{l(:label_course)}: #{container.name}" recipients = container.notified_users.select { |user| user.allowed_to?(:view_files, container) }.collect { |u| u.mail } when 'Version' added_to_url = url_for(:controller => 'files', :action => 'index', :project_id => container.project) @@ -278,13 +358,25 @@ class Mailer < ActionMailer::Base # news_added(news) => Mail::Message object # Mailer.news_added(news).deliver => sends an email to the news' project recipients def news_added(news) - redmine_headers 'Project' => news.project.identifier - @author = news.author - message_id news - @news = news - @news_url = url_for(:controller => 'news', :action => 'show', :id => news) - mail :to => news.recipients, - :subject => "[#{news.project.name}] #{l(:label_news)}: #{news.title}" + + if news.project + redmine_headers 'Project' => news.project.identifier + @author = news.author + message_id news + @news = news + @news_url = url_for(:controller => 'news', :action => 'show', :id => news) + mail :to => news.recipients, + :subject => "[#{news.project.name}] #{l(:label_news)}: #{news.title}" + elsif news.course + redmine_headers 'Course' => news.course.id + @author = news.author + message_id news + @news = news + recipients = news.course.notified_users.select { |user| user.allowed_to?(:view_files, news.course) }.collect { |u| u.mail } + @news_url = url_for(:controller => 'news', :action => 'show', :id => news) + mail :to => recipients, + :subject => "[#{news.course.name}] #{l(:label_news)}: #{news.title}" + end end # Builds a Mail::Message object used to email recipients of a news' project when a news comment is added. @@ -294,15 +386,28 @@ class Mailer < ActionMailer::Base # Mailer.news_comment_added(comment) => sends an email to the news' project recipients def news_comment_added(comment) news = comment.commented - redmine_headers 'Project' => news.project.identifier - @author = comment.author - message_id comment - @news = news - @comment = comment - @news_url = url_for(:controller => 'news', :action => 'show', :id => news) - mail :to => news.recipients, - :cc => news.watcher_recipients, - :subject => "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}" + if news.project + redmine_headers 'Project' => news.project.identifier + @author = comment.author + message_id comment + @news = news + @comment = comment + @news_url = url_for(:controller => 'news', :action => 'show', :id => news) + mail :to => news.recipients, + :cc => news.watcher_recipients, + :subject => "Re: [#{news.project.name}] #{l(:label_news)}: #{news.title}" + elsif news.course + redmine_headers 'Course' => news.course.id + @author = comment.author + message_id comment + @news = news + @comment = comment + @news_url = url_for(:controller => 'news', :action => 'show', :id => news) + recipients = news.course.notified_users.select { |user| user.allowed_to?(:view_files, news.course) }.collect { |u| u.mail } + + mail :to => recipients, + :subject => "[#{news.course.name}] #{l(:label_news)}: #{news.title}" + end end # Builds a Mail::Message object used to email the recipients of the specified message that was posted. @@ -311,18 +416,33 @@ class Mailer < ActionMailer::Base # message_posted(message) => Mail::Message object # Mailer.message_posted(message).deliver => sends an email to the recipients def message_posted(message) - redmine_headers 'Project' => message.project.identifier, - 'Topic-Id' => (message.parent_id || message.id) - @author = message.author - message_id message - references message.parent unless message.parent.nil? - recipients = message.recipients - cc = ((message.root.watcher_recipients + message.board.watcher_recipients).uniq - recipients) - @message = message - @message_url = url_for(message.event_url) - mail :to => recipients, - :cc => cc, - :subject => "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}" + if message.project + redmine_headers 'Project' => message.project.identifier, + 'Topic-Id' => (message.parent_id || message.id) + @author = message.author + message_id message + references message.parent unless message.parent.nil? + recipients = message.recipients + cc = ((message.root.watcher_recipients + message.board.watcher_recipients).uniq - recipients) + @message = message + @message_url = url_for(message.event_url) + mail :to => recipients, + :cc => cc, + :subject => "[#{message.board.project.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}" + elsif message.course + redmine_headers 'Course' => message.course.id, + 'Topic-Id' => (message.parent_id || message.id) + @author = message.author + message_id message + references message.parent unless message.parent.nil? + recipients = message.course.notified_users.select { |user| user.allowed_to?(:view_files, message.course) }.collect { |u| u.mail } + cc = ((message.root.watcher_recipients + message.board.watcher_recipients).uniq - recipients) + @message = message + @message_url = url_for(message.event_url) + mail :to => recipients, + :cc => cc, + :subject => "[#{message.board.course.name} - #{message.board.name} - msg#{message.root.id}] #{message.subject}" + end end # Builds a Mail::Message object used to email the recipients of a project of the specified wiki content was added. @@ -615,5 +735,15 @@ class Mailer < ActionMailer::Base Rails.logger end - + def add_attachments(obj) + if email.attachments && email.attachments.any? + email.attachments.each do |attachment| + obj.attachments << Attachment.create(:container => obj, + :file => attachment.decoded, + :filename => attachment.filename, + :author => user, + :content_type => attachment.mime_type) + end + end + end end diff --git a/app/models/memo.rb b/app/models/memo.rb index 495f97ad3..165f8e144 100644 --- a/app/models/memo.rb +++ b/app/models/memo.rb @@ -47,7 +47,7 @@ class Memo < ActiveRecord::Base "parent_id", "replies_count" - after_create :add_author_as_watcher, :reset_counters!#,:be_user_score -- 公共区发帖暂不计入得分 + after_create :add_author_as_watcher, :reset_counters!, :sendmail#,:be_user_score -- 公共区发帖暂不计入得分 # after_update :update_memos_forum after_destroy :reset_counters!#,:down_user_score -- 公共区发帖暂不计入得分 # after_create :send_notification @@ -58,6 +58,12 @@ class Memo < ActiveRecord::Base # includes(:forum => ).where() # } + def sendmail + thread1=Thread.new do + Mailer.forum_message_added(self).deliver if Setting.notified_events.include?('forum_message_added') + end + end + def cannot_reply_to_locked_topic errors.add :base, l(:label_memo_locked) if root.locked? && self != root end diff --git a/app/models/memo_observer.rb b/app/models/memo_observer.rb new file mode 100644 index 000000000..66cabe923 --- /dev/null +++ b/app/models/memo_observer.rb @@ -0,0 +1,8 @@ +class MemoObserver < ActiveRecord::Observer + def after_create(memo) + + thread1=Thread.new do + Mailer.forum_message_added(memo).deliver if Setting.notified_events.include?('forum_message_added') + end + end +end diff --git a/app/models/poll.rb b/app/models/poll.rb new file mode 100644 index 000000000..06f1369c1 --- /dev/null +++ b/app/models/poll.rb @@ -0,0 +1,9 @@ +class Poll < ActiveRecord::Base + #attr_accessible :closed_at, :polls_group_id, :polls_name, :polls_status, :polls_type, :published_at, :user_id + include Redmine::SafeAttributes + + belongs_to :user + has_many :poll_questions, :dependent => :destroy,:order => "#{PollQuestion.table_name}.question_number" + has_many :poll_users, :dependent => :destroy + has_many :users, :through => :poll_users #该文件被哪些用户提交答案过 +end diff --git a/app/models/poll_answer.rb b/app/models/poll_answer.rb new file mode 100644 index 000000000..93c75da97 --- /dev/null +++ b/app/models/poll_answer.rb @@ -0,0 +1,7 @@ +class PollAnswer < ActiveRecord::Base + # attr_accessible :answer_position, :answer_text, :poll_questions_id + include Redmine::SafeAttributes + + belongs_to :poll_question + has_many :poll_votes, :dependent => :destroy +end diff --git a/app/models/poll_question.rb b/app/models/poll_question.rb new file mode 100644 index 000000000..2d9912fc2 --- /dev/null +++ b/app/models/poll_question.rb @@ -0,0 +1,8 @@ +class PollQuestion < ActiveRecord::Base + # attr_accessible :is_necessary, :polls_id, :question_title, :question_type + include Redmine::SafeAttributes + + belongs_to :poll + has_many :poll_answers, :order => "#{PollAnswer.table_name}.answer_position",:dependent => :destroy + has_many :poll_votes, :dependent => :destroy +end diff --git a/app/models/poll_user.rb b/app/models/poll_user.rb new file mode 100644 index 000000000..e7a122da9 --- /dev/null +++ b/app/models/poll_user.rb @@ -0,0 +1,7 @@ +class PollUser < ActiveRecord::Base + # attr_accessible :poll_id, :user_id + include Redmine::SafeAttributes + + belongs_to :poll + belongs_to :user +end diff --git a/app/models/poll_vote.rb b/app/models/poll_vote.rb new file mode 100644 index 000000000..550563e38 --- /dev/null +++ b/app/models/poll_vote.rb @@ -0,0 +1,8 @@ +class PollVote < ActiveRecord::Base + # attr_accessible :poll_answers_id, :poll_questions_id, :user_id, :vote_text + include Redmine::SafeAttributes + + belongs_to :poll_answer + belongs_to :poll_question + belongs_to :user +end diff --git a/app/models/user.rb b/app/models/user.rb index e966742f1..bef65fe54 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -77,6 +77,13 @@ class User < Principal has_many :homework_attaches, :through => :homework_users has_many :homework_evaluations + #问卷相关关关系 + has_many :poll_users, :dependent => :destroy + has_many :poll_votes, :dependent => :destroy + has_many :poll, :dependent => :destroy #用户创建的问卷 + has_many :answers, :source => :poll, :through => :poll_users, :dependent => :destroy #用户已经完成问答的问卷 + # end + has_and_belongs_to_many :groups, :after_add => Proc.new {|user, group| group.user_added(user)}, :after_remove => Proc.new {|user, group| group.user_removed(user)} has_many :changesets, :dependent => :nullify @@ -181,7 +188,7 @@ class User < Principal validates_confirmation_of :password, :allow_nil => true 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_save :update_hashed_password before_destroy :remove_references_before_destroy @@ -373,7 +380,7 @@ class User < Principal raise text end - # Returns the user who matches the given autologin +key+ or nil + def self.try_to_autologin(key) user = Token.find_active_user('autologin', key, Setting.autologin.to_i) if user @@ -459,7 +466,11 @@ class User < Principal User.hash_password("#{salt}#{User.hash_password clear_password}") == hashed_password end end + def check_password1?(clear_password) + + clear_password == hashed_password + end # Generates a random salt and computes hashed_password for +clear_password+ # The hashed password is stored in the following form: SHA1(salt + SHA1(password)) def salt_password(clear_password) diff --git a/app/views/bids/_bid_homework_show.html.erb b/app/views/bids/_bid_homework_show.html.erb index 2d6c35555..1009f405f 100644 --- a/app/views/bids/_bid_homework_show.html.erb +++ b/app/views/bids/_bid_homework_show.html.erb @@ -56,18 +56,30 @@ <%= link_to(bid.name, course_for_bid_path(bid), :class => 'bid_path') %> - + <% if User.current.logged? && is_cur_course_student(@course) %> <% cur_user_homework = cur_user_homework_for_bid(bid) %> + + <% if bid.open_anonymous_evaluation == 1 %> + <% case bid.comment_status %> + <% when 0 %> + 未开启匿评 + <% when 1 %> +   匿评中..   + <% when 2 %> +   匿评结束   + <% end %> + <% end%> + <% if cur_user_homework && cur_user_homework.empty? %> <%= link_to l(:label_commit_homework),new_exercise_book_path(bid) %> <% else %> - - <%= l(:lable_has_commit_homework)%> - + + 已 提 交 + <% end %> <% end %> <% if (User.current.admin?||User.current.allowed_to?(:as_teacher,@course)) %> diff --git a/app/views/bids/_homework.html.erb b/app/views/bids/_homework.html.erb index db1f555d3..e107e50b3 100644 --- a/app/views/bids/_homework.html.erb +++ b/app/views/bids/_homework.html.erb @@ -36,6 +36,7 @@ $('#ajax-modal').html('<%= escape_javascript(render :partial => 'homework_attach/praise_alert') %>'); showModal('ajax-modal', '480px'); $('#ajax-modal').css('height','240px'); + $('#ajax-modal').siblings().remove(); $('#ajax-modal').before("" + ""); $('#ajax-modal').parent().css("top","").css("left","").css("width","511"); diff --git a/app/views/contests/index.html.erb b/app/views/contests/index.html.erb index 75b892461..170f11037 100644 --- a/app/views/contests/index.html.erb +++ b/app/views/contests/index.html.erb @@ -10,7 +10,7 @@ <%= l(:label_user_location) %> : - + <% if User.current.logged? %> <% unless User.current.user_extensions.identity == 1 %> <%= link_to(l(:label_newtype_contest), new_contest_contests_path, :class => 'icon icon-add', :target => "_blank") %> diff --git a/app/views/courses/_course_form.html.erb b/app/views/courses/_course_form.html.erb index c48d24935..d293f9ed1 100644 --- a/app/views/courses/_course_form.html.erb +++ b/app/views/courses/_course_form.html.erb @@ -127,9 +127,7 @@ <%= l(:label_new_course_description) %>      - +

diff --git a/app/views/courses/_member_list.html.erb b/app/views/courses/_member_list.html.erb index 41b4f41e7..dd543ec2c 100644 --- a/app/views/courses/_member_list.html.erb +++ b/app/views/courses/_member_list.html.erb @@ -56,24 +56,36 @@

    <% if @canShowCode %> -
  • - <%= l(:label_bidding_user_studentname) %> : - <%= link_to member.user.show_name, user_path(member.user) %> -
  • -
    + <% if member.user.show_name == '' && member.user.user_extensions.student_id == '' %> +
  • + <%= l(:label_username)%> + <%= link_to(member.user.name, user_path(member.user)) %> +
  • + <% else %> + <% unless member.user.show_name == ''%> +
  • + <%= l(:label_bidding_user_studentname) %> : + <%= link_to member.user.show_name, user_path(member.user) %> +
  • +
    + <% end %> + <% unless member.user.user_extensions.student_id == '' %> +
  • + <%= l(:label_bidding_user_studentcode) %> : + <%= link_to member.user.user_extensions.student_id, user_path(member.user) %> +
  • + <% end %> + <% end %> <%#= content_tag "li", "#{l(:label_bidding_user_studentname)}#{' : '}"link_to(member.user.show_name, user_path(member.user)) %> <% else %> - <%= content_tag "li", link_to(member.user.name, user_path(member.user)) %> - <% end %> - - - <% if @canShowCode %>
  • - <%= l(:label_bidding_user_studentcode) %> : - <%= link_to member.user.user_extensions.student_id, user_path(member.user) %> + <%= l(:label_username)%> + <%= link_to(member.user.name, user_path(member.user)) %>
  • - <%#= content_tag "li", "#{l(:label_bidding_user_studentcode)}#{' : '}#{member.user.user_extensions.student_id}", :style=> "color:#1c9ec7;" %> - <% end %> + <% end %> + + +
<% if @subPage_title == l(:label_student_list) %> <%= link_to format("%0.2f",member.score.nil? ? 0 : member.score.to_s), { diff --git a/app/views/courses/_member_list_detail.html.erb b/app/views/courses/_member_list_detail.html.erb index f37067cb5..bc6cbd242 100644 --- a/app/views/courses/_member_list_detail.html.erb +++ b/app/views/courses/_member_list_detail.html.erb @@ -7,24 +7,36 @@ <%= member.user.nil? ? '' : (image_tag(url_to_avatar(member.user), :width => 40, :height => 40)) %>
    <% if @canShowCode %> -
  • - <%= l(:label_bidding_user_studentname) %> : - <%= link_to member.user.show_name, user_path(member.user) %> - -

  • + <% if member.user.show_name == '' && member.user.user_extensions.student_id == '' %> +
  • + <%= l(:label_username)%> + <%= link_to(member.user.name, user_path(member.user)) %> +
  • + <% else %> + <% unless member.user.show_name == ''%> +
  • + <%= l(:label_bidding_user_studentname) %> : + <%= link_to member.user.show_name, user_path(member.user) %> +
  • +
    + <% end %> + <% unless member.user.user_extensions.student_id == '' %> +
  • + <%= l(:label_bidding_user_studentcode) %> : + <%= link_to member.user.user_extensions.student_id, user_path(member.user) %> +
  • + <% end %> + <% end %> <%#= content_tag "li", "#{l(:label_bidding_user_studentname)}#{' : '}"link_to(member.user.show_name, user_path(member.user)) %> <% else %> - <%= content_tag "li", link_to(member.user.name, user_path(member.user)) %> - <% end %> - - - <% if @canShowCode %>
  • - <%= l(:label_bidding_user_studentcode) %> : - <%= link_to member.user.user_extensions.student_id, user_path(member.user) %> + <%= l(:label_username)%> + <%= link_to(member.user.name, user_path(member.user)) %>
  • - <%#= content_tag "li", "#{l(:label_bidding_user_studentcode)}#{' : '}#{member.user.user_extensions.student_id}", :style=> "color:#1c9ec7;" %> <% end %> + + +
<% if @subPage_title == l(:label_student_list) %> <%= link_to format("%0.2f",member.score.to_s), { diff --git a/app/views/courses/member.html.erb b/app/views/courses/member.html.erb index 313e50748..803be3731 100644 --- a/app/views/courses/member.html.erb +++ b/app/views/courses/member.html.erb @@ -1,21 +1,21 @@ <%= stylesheet_link_tag 'course_group', :media => 'all' %> -
+
<% end %> diff --git a/app/views/users/_mail_notifications.html.erb b/app/views/users/_mail_notifications.html.erb index a8d3edc55..7dd4ad77f 100644 --- a/app/views/users/_mail_notifications.html.erb +++ b/app/views/users/_mail_notifications.html.erb @@ -1,5 +1,5 @@

-<%= label_tag "user_mail_notification", l(:description_user_mail_notification), :class => "hidden-for-sighted_bak" %> +<%= label_tag "user_mail_notification", l(:description_user_mail_notification), :class => "hidden-for-sighted_bak" , :style=> 'margin-right: 5px;'%> <%= select_tag( 'user[mail_notification]', options_for_select( diff --git a/app/views/welcome/_link_to_another.html.erb b/app/views/welcome/_link_to_another.html.erb index 14640897c..e9a19be4e 100644 --- a/app/views/welcome/_link_to_another.html.erb +++ b/app/views/welcome/_link_to_another.html.erb @@ -1,6 +1,6 @@ -

-
- <%=l(:label_projects_management_platform)%> - <%=l(:label_courses_management_platform)%> - <%=l(:label_contests_management_platform)%> + + \ No newline at end of file diff --git a/app/views/welcome/_search_course.html.erb b/app/views/welcome/_search_course.html.erb index fda9dae7c..c3bbd46d8 100644 --- a/app/views/welcome/_search_course.html.erb +++ b/app/views/welcome/_search_course.html.erb @@ -1,58 +1,58 @@ -<% - select_option = [] - (select_option << ['项目', 'projects']) if project_type == Project::ProjectType_project - (select_option << ['课程', 'courses']) if project_type == Project::ProjectType_course - select_option << ['用户', 'users'] - #select_option << ['教师', 'users_teacher'], - #select_option << ['学生', 'users_student'] -%> - -<%= form_tag({controller: :welcome, action: :search }, method: :get) do %> - -<% end %> +<% + select_option = [] + (select_option << ['项目', 'projects']) if project_type == Project::ProjectType_project + (select_option << ['课程', 'courses']) if project_type == Project::ProjectType_course + select_option << ['用户', 'users'] + #select_option << ['教师', 'users_teacher'], + #select_option << ['学生', 'users_student'] +%> + +<%= form_tag({controller: :welcome, action: :search }, method: :get) do %> + +<% end %> diff --git a/app/views/welcome/_search_project.html.erb b/app/views/welcome/_search_project.html.erb index b86ff64f9..1b3552c86 100644 --- a/app/views/welcome/_search_project.html.erb +++ b/app/views/welcome/_search_project.html.erb @@ -29,7 +29,7 @@ form #search_type{ border-bottom-left-radius: 0px; border-top-left-radius: 0px; border-left: 1px outset #83A9A9; - margin-left: -4px; + margin-left: 0px; -webkit-appearance: none; -moz-appearance: none; text-indent: 0.01px; @@ -45,7 +45,7 @@ form #search_by border-bottom-left-radius: 0px; border-top-left-radius: 0px; border-left: 1px outset #83A9A9; - margin-left: -6px; + margin-left: 0px; -webkit-appearance: none; -moz-appearance: none; text-indent: 0.01px; @@ -86,14 +86,15 @@ form #search_by } <%= form_tag({controller: :welcome, action: :search }, method: :get) do %> -