diff --git a/Gemfile.lock b/Gemfile.lock index e6ee7da71..efc236e7e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -74,11 +74,19 @@ GEM mail (2.5.4) mime-types (~> 1.16) treetop (~> 1.4.8) + method_source (0.8.2) mime-types (1.23) multi_json (1.7.6) mysql2 (0.3.11-x86-mingw32) net-ldap (0.3.1) polyglot (0.3.3) + pry (0.9.12.6-x86-mingw32) + coderay (~> 1.0) + method_source (~> 0.8) + slop (~> 3.4) + win32console (~> 1.3) + pry-nav (0.2.3) + pry (~> 0.9.10) rack (1.4.5) rack-cache (1.2) rack (>= 0.4) @@ -113,6 +121,7 @@ GEM railties (~> 3.2.0) sass (>= 3.1.10) tilt (~> 1.3) + slop (3.5.0) sprockets (2.2.2) hike (~> 1.2) multi_json (~> 1.0) @@ -127,6 +136,7 @@ GEM uglifier (1.0.3) execjs (>= 0.3.0) multi_json (>= 1.0.2) + win32console (1.3.2-x86-mingw32) PLATFORMS x86-mingw32 @@ -144,6 +154,8 @@ DEPENDENCIES jquery-rails (~> 2.0.2) mysql2 (~> 0.3.11) net-ldap (~> 0.3.1) + pry + pry-nav rack-mini-profiler! rack-openid rails (= 3.2.13) diff --git a/app/assets/javascripts/contestnotifications.js b/app/assets/javascripts/contestnotifications.js new file mode 100644 index 000000000..dee720fac --- /dev/null +++ b/app/assets/javascripts/contestnotifications.js @@ -0,0 +1,2 @@ +// Place all the behaviors and hooks related to the matching controller here. +// All this logic will automatically be available in application.js. diff --git a/app/assets/javascripts/notificationcomments.js.coffee b/app/assets/javascripts/notificationcomments.js.coffee new file mode 100644 index 000000000..761567942 --- /dev/null +++ b/app/assets/javascripts/notificationcomments.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/stylesheets/contestnotifications.css b/app/assets/stylesheets/contestnotifications.css new file mode 100644 index 000000000..afad32db0 --- /dev/null +++ b/app/assets/stylesheets/contestnotifications.css @@ -0,0 +1,4 @@ +/* + Place all the styles related to the matching controller here. + They will automatically be included in application.css. +*/ diff --git a/app/assets/stylesheets/notificationcomments.css.scss b/app/assets/stylesheets/notificationcomments.css.scss new file mode 100644 index 000000000..aea714e47 --- /dev/null +++ b/app/assets/stylesheets/notificationcomments.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the notificationcomments controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 4b877818b..28611e515 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -264,7 +264,13 @@ class ApplicationController < ActionController::Base render_404 end - #根据course_id找project + def find_contest_by_contest_id + @contest = Contest.find(params[:contest_id]) + rescue ActiveRecord::RecordNotFound + render_404 + end + + #course_idproject def find_project_by_course_id @bid = Bid.find params[:course_id] @project = @bid.courses[0] @@ -282,12 +288,26 @@ class ApplicationController < ActionController::Base render_404 end + def find_optional_contest + @contest = Contest.find(params[:contest_id]) unless params[:contest_id].blank? + allowed = User.current.allowed_to?({:controller => params[:controller], :action => params[:action]}, @contest, :global => true) + allowed ? true : deny_access + rescue ActiveRecord::RecordNotFound + render_404 + end + # Finds and sets @project based on @object.project def find_project_from_association render_404 unless @object.present? @project = @object.project end + + def find_contest_from_association + render_404 unless @object.present? + + @contest =@object.contest + end def find_model_object model = self.class.model_object @@ -299,6 +319,16 @@ class ApplicationController < ActionController::Base render_404 end + # def find_model_object_contest + # model = self.class.model_object + # if model + # @object = model.find(params[:id]) + # self.instance_variable_set('@' + controller_name.singularize, @object) if @object + # end + # rescue ActiveRecord::RecordNotFound + # render_404 + # end + def self.model_object(model) self.model_object = model end diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index b2689d0c2..90c034fdb 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -18,7 +18,7 @@ class CommentsController < ApplicationController default_search_scope :news model_object News - before_filter :find_model_object + before_filter :find_model_object before_filter :find_project_from_association before_filter :authorize @@ -50,4 +50,6 @@ class CommentsController < ApplicationController @comment = nil @news end + + end diff --git a/app/controllers/contestnotifications_controller.rb b/app/controllers/contestnotifications_controller.rb new file mode 100644 index 000000000..0d05d6ca1 --- /dev/null +++ b/app/controllers/contestnotifications_controller.rb @@ -0,0 +1,186 @@ +class ContestnotificationsController < ApplicationController + # GET /contestnotifications + # GET /contestnotifications.json + layout 'base_newcontest' + default_search_scope :contestnotifications + model_object Contestnotification + # before_filter :find_model_object, :except => [:new, :create, :index] + # before_filter :find_contest_from_association, :except => [:new, :create, :index] + before_filter :find_contest_by_contest_id, :only => [:new, :create] + before_filter :find_contest + before_filter :find_author + # before_filter :authorize, :except => [:index] + before_filter :find_optional_contest, :only => [:index] + accept_rss_auth :index + accept_api_auth :index + + before_filter :access_edit_destroy, only: [:edit ,:update, :destroy] + + def find_author + @user = @contest.author + render_404 if @user.nil? + end + def find_contest + @contest = Contest.find(params[:contest_id]) + render_404 if @contest.nil? + end + + + def index + + # @contestnotifications = Contestnotification.all + # + # respond_to do |format| + # format.html # index.html.erb + # format.json { render json: @contestnotifications } + # end + + ### begin ### + case params[:format] + when 'xml', 'json' + @offset, @limit = api_offset_and_limit + else + @limit = 10 + end + + scope = @contest ? @contest.contestnotifications.visible : Contestnotifications.visible + + @contestnotifications_count = scope.count + @contestnotifications_pages = Paginator.new @contestnotifications_count, @limit, params['page'] + @offset ||= @contestnotifications_pages.offset + @contestnotificationss = scope.all(:include => [:author, :contest], + :order => "#{Contestnotification.table_name}.created_at DESC", + :offset => @offset, + :limit => @limit) + + respond_to do |format| + format.html { + @contestnotification = Contestnotification.new # for adding news inline + render :layout => 'base_newcontest' + } + format.api + format.atom { render_feed(@contestnotificationss, :title => (@contest ? @contest.name : Setting.app_title) + ": #{l(:label_contest_notification)}") } + end + ### end ### + end + + # GET /contestnotifications/1 + # GET /contestnotifications/1.json + def show + @contestnotification = Contestnotification.find(params[:id]) + + # + # respond_to do |format| + # format.html # show.html.erb + # format.json { render json: @contestnotification } + # end + @notificationcomments = @contestnotification.notificationcomments + @notificationcomments.reverse! if User.current.wants_notificationcomments_in_reverse_order? + render :layout => 'base_newcontest' + + end + + # GET /contestnotifications/new + # GET /contestnotifications/new.json + def new + # @contestnotification = Contestnotification.new +# + # respond_to do |format| + # format.html # new.html.erb + # format.json { render json: @contestnotification } + # end + @contestnotification = Contestnotification.new(:contest => @contest, :author => User.current) + render :layout => 'base_newcontest' + end + + # GET /contestnotifications/1/edit + def edit + @contestnotification = Contestnotification.find(params[:id]) + end + + # POST /contestnotifications + # POST /contestnotifications.json + def create + # @contestnotification = Contestnotification.new(params[:contestnotification]) + # + # respond_to do |format| + # if @contestnotification.save + # format.html { redirect_to @contestnotification, notice: 'Contestnotification was successfully created.' } + # format.json { render json: @contestnotification, status: :created, location: @contestnotification } + # else + # format.html { render action: "new" } + # format.json { render json: @contestnotification.errors, status: :unprocessable_entity } + # end + # end + @contestnotification = Contestnotification.new(:contest => @contest, :author => User.current) + @contestnotification.safe_attributes = params[:contestnotification] + @contestnotification.save_attachments(params[:attachments]) + if @contestnotification.save + render_attachment_warning_if_needed(@contestnotification) + flash[:notice] = l(:notice_successful_create) + redirect_to contest_contestnotifications_path(@contest) + else + layout_file = 'base_newcontest' + render :action => 'new', :layout => layout_file + end + end + + # PUT /contestnotifications/1 + # PUT /contestnotifications/1.json + def update + # @contestnotification = Contestnotification.find(params[:id]) + # + # respond_to do |format| + # if @contestnotification.update_attributes(params[:contestnotification]) + # format.html { redirect_to @contestnotification, notice: 'Contestnotification was successfully updated.' } + # format.json { head :no_content } + # else + # format.html { render action: "edit" } + # format.json { render json: @contestnotification.errors, status: :unprocessable_entity } + # end + # end + @contestnotification = Contestnotification.find(params[:id]) + @contestnotification.safe_attributes = params[:contestnotification] + @contestnotification.save_attachments(params[:attachments]) + if @contestnotification.save + render_attachment_warning_if_needed(@contestnotification) + flash[:notice] = l(:notice_successful_update) + redirect_to contest_contestnotification_path(@contestnotification.contest, @contestnotification) + else + render :action => 'edit' + end + end + + # DELETE /contestnotifications/1 + # DELETE /contestnotifications/1.json + def destroy + # @contestnotification = Contestnotification.find(params[:id]) + # @contestnotification.destroy + # + # respond_to do |format| + # format.html { redirect_to contestnotifications_url } + # format.json { head :no_content } + # end + @contestnotification.destroy + redirect_to contest_contestnotifications_path(@contest) + end + + private + + def find_optional_contest + return true unless params[:id] + @contest = Contest.find(params[:id]) + # authorize + rescue ActiveRecord::RecordNotFound + render_404 + end + + def access_edit_destroy + if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?) + return true + else + render_403 + end + end + +end diff --git a/app/controllers/contests_controller.rb b/app/controllers/contests_controller.rb index c89fef5a6..c1c817517 100644 --- a/app/controllers/contests_controller.rb +++ b/app/controllers/contests_controller.rb @@ -4,9 +4,9 @@ class ContestsController < ApplicationController menu_item :respond menu_item :project, :only => :show_project menu_item :application, :only => :show_softapplication - menu_item :attendingcontest, :only => :show_attendingcontest - menu_item :contestnotification, :only => :show_notification - before_filter :find_contest, :only => [:show_contest, :show_project, :show_softapplication, :show_attendingcontest, :show_notification, :set_reward_project, :set_reward_softapplication, :create,:destroy,:more,:back,:add,:add_softapplication,:new,:show_results, :set_reward, + menu_item :attendingcontests, :only => :show_attendingcontest + menu_item :contestnotifications, :only => :index + before_filter :find_contest, :only => [:show_contest, :show_project, :show_softapplication, :show_attendingcontest, :index, :set_reward_project, :set_reward_softapplication, :create,:destroy,:more,:back,:add,:add_softapplication,:new,:show_results, :set_reward, :show_contest_project, :show_contest_user, :join_in_contest, :unjoin_in_contest, :new_join,:show_participator, :settings] # added by fq diff --git a/app/controllers/issue_categories_controller.rb b/app/controllers/issue_categories_controller.rb index a716653a5..9803eb789 100644 --- a/app/controllers/issue_categories_controller.rb +++ b/app/controllers/issue_categories_controller.rb @@ -19,6 +19,7 @@ class IssueCategoriesController < ApplicationController menu_item :settings model_object IssueCategory before_filter :find_model_object, :except => [:index, :new, :create] + #before_filter :find_model_object_contest, :except => [:index, :new, :create] before_filter :find_project_from_association, :except => [:index, :new, :create] before_filter :find_project_by_project_id, :only => [:index, :new, :create] before_filter :authorize @@ -119,4 +120,10 @@ class IssueCategoriesController < ApplicationController super @category = @object end + + def find_model_object_contest + super + @category = @object + end + end diff --git a/app/controllers/members_controller.rb b/app/controllers/members_controller.rb index 30c6c7e80..5a2f6027e 100644 --- a/app/controllers/members_controller.rb +++ b/app/controllers/members_controller.rb @@ -17,6 +17,7 @@ class MembersController < ApplicationController model_object Member before_filter :find_model_object, :except => [:index, :create, :autocomplete] + #before_filter :find_model_object_contest, :except => [:index, :create, :autocomplete] before_filter :find_project_from_association, :except => [:index, :create, :autocomplete] before_filter :find_project_by_project_id, :only => [:index, :create, :autocomplete] before_filter :authorize diff --git a/app/controllers/notificationcomments_controller.rb b/app/controllers/notificationcomments_controller.rb new file mode 100644 index 000000000..80500ab10 --- /dev/null +++ b/app/controllers/notificationcomments_controller.rb @@ -0,0 +1,27 @@ +class NotificationcommentsController < ApplicationController + # default_search_scope :contestnotifications + # model_object Contestnotifications + # before_filter :authorize + + def create + #raise Unauthorized unless @contestnotifications.notificationcommentable? + @contest = Contest.find(params[:contest_id]) + @contestnotification = Contestnotification.find(params[:contestnotification_id]) + + # @notificaioncomment = Notificationcomment.new + # @notificaioncomment.safe_attributes = params[:notificationcomment] + # @notificaioncomment.author = User.current + comment = @contestnotification.notificationcomments.new(params[:notificationcomment].merge(author_id: User.current.id)) + if comment.save + flash[:notice] = l(:label_comment_added) + end + + redirect_to contest_contestnotification_path(@contest, @contestnotification) + end + + def destroy + @contestnotifications.notificaioncomments.find(params[:notificaioncomment_id]).destroy + redirect_to contest_contestnotification_path(@contestnotifications) + end + +end diff --git a/app/controllers/previews_controller.rb b/app/controllers/previews_controller.rb index 0083116d2..579f8caa8 100644 --- a/app/controllers/previews_controller.rb +++ b/app/controllers/previews_controller.rb @@ -16,10 +16,11 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. class PreviewsController < ApplicationController - before_filter :find_project, :find_attachments + before_filter :find_project, :find_attachments, :find_contest, except: [:contestnotification] def issue @issue = @project.issues.find_by_id(params[:id]) unless params[:id].blank? + @issue = @contest.issues.find_by_id(params[:id]) unless params[:id].blank? if @issue @description = params[:issue] && params[:issue][:description] if @description && @description.gsub(/(\r?\n|\n\r?)/, "\n") == @issue.description.to_s.gsub(/(\r?\n|\n\r?)/, "\n") @@ -41,6 +42,12 @@ class PreviewsController < ApplicationController render :partial => 'common/preview' end + def contestnotification + @previewed = Contestnotification.find(params[:id]) + @text = (params[:contestnotification] ? params[:contestnotification][:description] : nil) + render :partial => 'common/preview' + end + private def find_project @@ -50,4 +57,20 @@ class PreviewsController < ApplicationController render_404 end + def contestnotifications + if params[:id].present? && contestnotifications = Contestnotifications.visible.find_by_id(params[:id]) + @previewed = contestnotifications + end + @text = (params[:contestnotifications] ? params[:contestnotifications][:description] : nil) + render :partial => 'common/preview' + end + + private + def find_contest + contest_id = (params[:issue] && params[:issue][:contest_id]) || params[:contest_id] + @contest = Contest.find(contest_id) + rescue ActiveRecord::RecordNotFound + render_404 + end + end diff --git a/app/controllers/versions_controller.rb b/app/controllers/versions_controller.rb index 49e32ba17..0bbbd1bd6 100644 --- a/app/controllers/versions_controller.rb +++ b/app/controllers/versions_controller.rb @@ -20,6 +20,7 @@ class VersionsController < ApplicationController menu_item :roadmap model_object Version before_filter :find_model_object, :except => [:index, :new, :create, :close_completed] + #before_filter :find_model_object_contest, :except => [:index, :new, :create] before_filter :find_project_from_association, :except => [:index, :new, :create, :close_completed] before_filter :find_project_by_project_id, :only => [:index, :new, :create, :close_completed] before_filter :authorize @@ -154,6 +155,13 @@ class VersionsController < ApplicationController redirect_to settings_project_path(@project, :tab => 'versions') end + def close_completed_contest + if request.put? + @contest.close_completed_versions + end + redirect_to settings_contest_path(@contest, :tab => 'versions') + end + def destroy if @version.fixed_issues.empty? @version.destroy diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 7bfe95123..1623e00e3 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -46,6 +46,10 @@ module ApplicationHelper def authorize_for(controller, action) User.current.allowed_to?({:controller => controller, :action => action}, @project) end + + def authorize_for_contest(controller, action) + User.current.allowed_to?({:controller => controller, :action => action}, @contest) + end # Display a link if user is authorized # @@ -57,6 +61,9 @@ module ApplicationHelper link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller] || params[:controller], options[:action]) end + def link_to_if_authorized_contest(name, options = {}, html_options = nil, *parameters_for_method_reference) + link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for_contest(options[:controller] || params[:controller], options[:action]) + end # Displays a link to user's account page if active def link_to_user(user, canShowRealName = false, options={}) if user.is_a?(User) diff --git a/app/helpers/contestnotifications_helper.rb b/app/helpers/contestnotifications_helper.rb new file mode 100644 index 000000000..ab17149d7 --- /dev/null +++ b/app/helpers/contestnotifications_helper.rb @@ -0,0 +1,2 @@ +module ContestnotificationsHelper +end diff --git a/app/helpers/notificationcomments_helper.rb b/app/helpers/notificationcomments_helper.rb new file mode 100644 index 000000000..2d90bfe32 --- /dev/null +++ b/app/helpers/notificationcomments_helper.rb @@ -0,0 +1,2 @@ +module NotificationcommentsHelper +end diff --git a/app/helpers/welcome_helper.rb b/app/helpers/welcome_helper.rb index c00f629dc..d35fd8275 100644 --- a/app/helpers/welcome_helper.rb +++ b/app/helpers/welcome_helper.rb @@ -319,9 +319,10 @@ module WelcomeHelper "show_documents" => true, "show_messages" => true, "show_news" => true, - "show_bids" => true + "show_bids" => true, + "show_contest" => true } - activity.scope_select{|t| ['changesets', 'documents', 'memos', 'messages', 'journals_for_messages', 'bids', 'news'].include?(t) ? nil : 'You may think you know what the following code does, may be. but why don"t you close this file and go play with something else, Now?' } + activity.scope_select{|t| ['changesets', 'documents', 'memos', 'messages', 'journals_for_messages', 'bids', 'news', 'contestnotification'].include?(t) ? nil : 'You may think you know what the following code does, may be. but why don"t you close this file and go play with something else, Now?' } activity.events_welcome(nil, nil, {:limit => limit, :types => 'welcome'}) end diff --git a/app/models/contest.rb b/app/models/contest.rb index 9a3268654..d41506b87 100644 --- a/app/models/contest.rb +++ b/app/models/contest.rb @@ -13,6 +13,7 @@ class Contest < ActiveRecord::Base has_many :join_in_competitions, foreign_key: 'competition_id', :dependent => :destroy has_many :join_in_contests, class_name: 'JoinInCompetition', foreign_key: 'competition_id', :dependent => :destroy has_many :praise_tread, as: :praise_tread_object, dependent: :destroy + has_many :contestnotifications, :dependent => :destroy, :include => :author @@ -93,6 +94,17 @@ class Contest < ActiveRecord::Base end end + # Closes open and locked project versions that are completed + def close_completed_versions_contest + Version.transaction do + versions.where(:status => %w(open locked)).all.each do |version| + if version.completed? + version.update_attribute(:status, 'closed') + end + end + end + end + def set_commit(commit) self.update_attribute(:commit, commit) end diff --git a/app/models/contestnotification.rb b/app/models/contestnotification.rb new file mode 100644 index 000000000..0bda49548 --- /dev/null +++ b/app/models/contestnotification.rb @@ -0,0 +1,63 @@ +class Contestnotification < ActiveRecord::Base + #attr_accessible :author_id, :notificationcomments_count, :contest_id, :description, :summary, :title + + include Redmine::SafeAttributes + #Contestnotification::Notificationcomment + belongs_to :contest + belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' + has_many :notificationcomments, as: :notificationcommented, :dependent => :delete_all, :order => "created_at" + # fq + has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy + + validates_presence_of :title, :description + validates_length_of :title, :maximum => 60 + validates_length_of :summary, :maximum => 255 + + acts_as_attachable :delete_permission => :manage_contestnotifications + acts_as_searchable :columns => ['title', 'summary', "#{table_name}.description"], :include => :contest + acts_as_event :url => Proc.new {|o| {:controller => 'contestnotifications', :action => 'show', :id => o.id}} + acts_as_activity_provider :find_options => {:include => [:contest, :author]}, + :author_key => :author_id + acts_as_watchable + + after_create :add_author_as_watcher + + after_create :act_as_activity + + + scope :visible, lambda {|*args| + nil + #includes(:contest).where(Contest.allowed_to_condition(args.shift || User.current, :view_contestnotifications, *args)) + } + + safe_attributes 'title', 'summary', 'description' + + def visible?(user=User.current) + !user.nil? && user.allowed_to?(:view_contestnotifications, contest) + end + + # Returns true if the news can be commented by user + def notificationcommentable?(user=User.current) + user.allowed_to?(:notificationcomment_contestnotifications, contest) + end + + def recipients + #contest.users.select {|user| user.notify_about?(self)}.map(&:mail) + end + + # returns latest news for contests visible by user + def self.latest(user = User.current, count = 5) + visible(user).includes([:author, :contest]).order("#{Contestnotification.table_name}.created_at DESC").limit(count).all + end + + private + + def add_author_as_watcher + #Watcher.create(:watchable => self, :user => author) + end + ## fq + def act_as_activity + self.acts << Activity.new(:user_id => self.author_id) + end + +end diff --git a/app/models/notificationcomment.rb b/app/models/notificationcomment.rb new file mode 100644 index 000000000..9cc658f22 --- /dev/null +++ b/app/models/notificationcomment.rb @@ -0,0 +1,11 @@ +class Notificationcomment < ActiveRecord::Base + attr_accessible :author_id, :notificationcommented_id, :notificationcommented_type, :notificationcomments + + include Redmine::SafeAttributes + belongs_to :notificationcommented, :polymorphic => true#, :counter_cache => true + belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' + + validates_presence_of :notificationcommented, :author, :notificationcomments + + # safe_attributes 'notificationcomments' +end diff --git a/app/models/user.rb b/app/models/user.rb index b4aaea49f..0308dd606 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -108,7 +108,9 @@ class User < Principal # added by bai has_many :join_in_contests, :dependent => :destroy has_many :news, :foreign_key => 'author_id' + has_many :contestnotification, :foreign_key => 'author_id' has_many :comments, :foreign_key => 'author_id' + has_many :notificationcomments, :foreign_key => 'author_id' has_many :wiki_contents, :foreign_key => 'author_id' has_many :journals has_many :messages, :foreign_key => 'author_id' @@ -524,6 +526,9 @@ class User < Principal self.pref[:comments_sorting] == 'desc' end + def wants_notificationcomments_in_reverse_order? + self.pref[:notificationcomments_sorting] == 'desc' + end # Return user's RSS key (a 40 chars long string), used to access feeds def rss_key if rss_token.nil? @@ -959,6 +964,7 @@ class User < Principal substitute = User.anonymous Attachment.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] Comment.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] + Notificationcomment.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] Issue.update_all ['author_id = ?', substitute.id], ['author_id = ?', id] Issue.update_all 'assigned_to_id = NULL', ['assigned_to_id = ?', id] Journal.update_all ['user_id = ?', substitute.id], ['user_id = ?', id] diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb index 5b95386be..e0a541804 100644 --- a/app/models/user_preference.rb +++ b/app/models/user_preference.rb @@ -54,6 +54,9 @@ class UserPreference < ActiveRecord::Base def comments_sorting; self[:comments_sorting] end def comments_sorting=(order); self[:comments_sorting]=order end + def notificationcomments_sorting; self[:notificationcomments_sorting] end + def notificationcomments_sorting=(order); self[:notificationcomments_sorting]=order end + def warn_on_leaving_unsaved; self[:warn_on_leaving_unsaved] || '1'; end def warn_on_leaving_unsaved=(value); self[:warn_on_leaving_unsaved]=value; end end diff --git a/app/views/contestnotifications/_form.html.erb b/app/views/contestnotifications/_form.html.erb new file mode 100644 index 000000000..7e7b10a23 --- /dev/null +++ b/app/views/contestnotifications/_form.html.erb @@ -0,0 +1,11 @@ +<%= error_messages_for @contestnotifications %> +
+ <%= l(:bale_news_notice) %> +
+
+

<%= f.text_field :title, :required => true, :size => 60, :style => "width:488px;" %>

+

<%= f.text_area :description, :required => true, :cols => 60, :rows => 11, :class => 'wiki-edit', :style => "width:490px;" %>

+ +
+ +<%= wikitoolbar_for 'news_description' %> diff --git a/app/views/contestnotifications/_news.html.erb b/app/views/contestnotifications/_news.html.erb new file mode 100644 index 000000000..301a193d8 --- /dev/null +++ b/app/views/contestnotifications/_news.html.erb @@ -0,0 +1,28 @@ + + + + + + + +
+ + + + + + + + + + +
<%=link_to contestnotifications.author,contest_contestnotification_path(contestnotifications)%> + <%= l(:label_project_newshare) %> <%= link_to h(contestnotifications.title), contest_contestnotification_path(contestnotifications) %> +

<%=h contestnotifications.description%>

<%= contestnotifications.created_at %><%= link_to l(:label_project_newother),contest_contestnotification_path(contestnotifications)%> + <%= "(#{l(:label_x_comments, :count => contestnotifications.notificationcomments_count)})" if contestnotifications.notificationcomments_count > 0 %> +
diff --git a/app/views/contestnotifications/edit.html.erb b/app/views/contestnotifications/edit.html.erb new file mode 100644 index 000000000..7b91d922c --- /dev/null +++ b/app/views/contestnotifications/edit.html.erb @@ -0,0 +1,12 @@ +

<%=l(:label_news)%>

+ +<%= labelled_form_for @contestnotification, url: contest_contestnotification_path, :html => { :id => 'contestnotifications-form', :multipart => true, :method => :put } do |f| %> +<%= render :partial => 'form', :locals => { :f => f } %> +<%= submit_tag l(:button_save) %> +<%= preview_link preview_contestnotifications_path(id: @contestnotification), 'contestnotifications-form' %> +<% end %> +
+ +<% content_for :header_tags do %> + <%= stylesheet_link_tag 'scm' %> +<% end %> \ No newline at end of file diff --git a/app/views/contestnotifications/index.api.rsb b/app/views/contestnotifications/index.api.rsb new file mode 100644 index 000000000..6509d2915 --- /dev/null +++ b/app/views/contestnotifications/index.api.rsb @@ -0,0 +1,14 @@ +api.array :contestnotifications, api_meta(:total_count => @contestnotifications_count, :offset => @offset, :limit => @limit) do + @contestnotificationss.each do |contestnotifications| + api.contestnotifications do + api.id contestnotifications.id + api.contest(:id => contestnotifications.contest_id, :name => contestnotifications.contest.name) unless contestnotifications.contest.nil? + api.author(:id => contestnotifications.author_id, :name => contestnotifications.author.name) unless contestnotifications.author.nil? + + api.title contestnotifications.title + api.summary contestnotifications.summary + api.description contestnotifications.description + api.created_at contestnotifications.created_at + end + end +end diff --git a/app/views/contestnotifications/index.html.erb b/app/views/contestnotifications/index.html.erb new file mode 100644 index 000000000..e05abbdc8 --- /dev/null +++ b/app/views/contestnotifications/index.html.erb @@ -0,0 +1,97 @@ + + <%= l(:label_notification) %> + + +<% if User.current.logged? && User.current == @contest.author %> +<%= link_to(l(:bale_news_notice), + new_contest_contestnotification_path(@contest), + :class => 'icon icon-add', + :onclick => 'showAndScrollTo("add-contestnotifications", "contestnotifications_title"); return false;') %> +<% end %> + + + +<% if @contest && User.current.allowed_to?(:manage_contestnotifications, @contest) %> + +<% end %> +
+ <% if @contestnotificationss.empty? %> +

+ <%= l(:label_no_data) %> +

+ <% else %> + <% @contestnotificationss.each do |contestnotifications| %> + + + + + + +
<%= link_to image_tag(url_to_avatar(contestnotifications.author), :class => "avatar"), user_path(contestnotifications.author) %> + + + + + + + + + + + + +
+ <%= link_to_user(contestnotifications.author) if contestnotifications.respond_to?(:author) %> + <%= l(:label_project_notice) %><%= link_to h(contestnotifications.title), contest_contestnotification_path(@contest, contestnotifications) %> + + <%= link_to l(:button_edit), edit_contest_contestnotification_path(@contest, contestnotifications) if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?) %> + <%= delete_link contest_contestnotification_path(@contest, contestnotifications) if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?) %> + +
+ <%= textilizable(contestnotifications, :description) %>
<%= l :label_update_time %> +  <%= format_time(contestnotifications.created_at) %><%= link_to l(:label_check_comment), contest_contestnotification_path(@contest, contestnotifications) %><%#= "(#{l(:label_x_comments, :count => contestnotifications.notificationcomments_count)})" if contestnotifications.notificationcomments_count >= 0 %>
+
+ <% end %> + <% end %> +
+ +
+ + + <% content_for :header_tags do %> + <%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :page => nil, :key => User.current.rss_key})) %> + <%= stylesheet_link_tag 'scm' %> + <% end %> + + <% html_title(l(:label_news_plural)) -%> +
+ + + + \ No newline at end of file diff --git a/app/views/contestnotifications/new.html.erb b/app/views/contestnotifications/new.html.erb new file mode 100644 index 000000000..30d5f0106 --- /dev/null +++ b/app/views/contestnotifications/new.html.erb @@ -0,0 +1,9 @@ + +<%= labelled_form_for @contestnotification, :url => contest_contestnotifications_path(@contest), :html => { :id => 'contestnotifications-form', :multipart => true } do |f| %> + <%= render :partial => 'contestnotifications/form', :locals => { :f => f } %> + <%= submit_tag l(:button_create), :class => "whiteButton m3p10 h30" %> + <%= submit_tag l(:button_cancel), :class => "whiteButton m3p10 h30",:onclick => "cancel();" %> + + +<% end %> +
diff --git a/app/views/contestnotifications/show.html.erb b/app/views/contestnotifications/show.html.erb new file mode 100644 index 000000000..152d0d02a --- /dev/null +++ b/app/views/contestnotifications/show.html.erb @@ -0,0 +1,93 @@ + +
+ <%= link_to(l(:button_edit), + edit_contest_contestnotification_path(@contest, @contestnotification), + :class => 'icon icon-edit', + :accesskey => accesskey(:edit), + :onclick => '$("#edit-contestnotifications").show(); return true;') if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?)%> + <%= delete_link contest_contestnotification_path(@contest, @contestnotification) if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?) %> +
+ +

<%=h @contestnotification.title %>

+ +<% if authorize_for_contest('contestnotifications', 'edit') %> + +<% end %> + +
+ +
+ <%= textilizable(@contestnotification, :description) %> +
+ <%#= link_to_attachments @contestnotification %> +
+ + + <% if User.current.logged? %> +

+ <%= toggle_link l(:label_comment_add), "add_notificationcomment_form", :focus => "notificationcomment_notificationcomments" %> +

+ <% else %> + <%= l(:label_user_login_notificationcomment) %> + <%= link_to l(:label_user_login_new), signin_path %> + <% end %> + + <%= form_tag( contest_contestnotification_notificationcomments_path(@contest, @contestnotification) , :id => "add_notificationcomment_form", :style => "display:none;") do %> +
+ <%= text_area 'notificationcomment', 'notificationcomments', :cols => 80, :rows => 15, :class => 'wiki-edit' %> + <%= wikitoolbar_for 'notificationcomment_notificationcomments' %> +
+

+ <%= submit_tag l(:button_add) %> + <%= submit_tag l(:button_cancel), :onclick => "cancel();" %> +

+ <% end %> + + + <% html_title @contestnotification.title -%> + + <% content_for :header_tags do %> + <%= stylesheet_link_tag 'scm' %> + <% end %> + + +
+
+

<%= l(:label_comment_plural) %>

+ <% notificationcomments = @notificationcomments.reverse %> + <% notificationcomments.each do |notificationcomment| %> + <% next if notificationcomment.new_record? %> + + + + + +
<%= image_tag(url_to_avatar(notificationcomment.author), :class => "avatar")%> + + + + + + + + + + + +
<%= link_to_user(notificationcomment.author) if notificationcomment.respond_to?(:author) %> <%= l(:label_project_newadd) %><%= l(:label_comment_plural) %>
+

+ <%= textilizable(notificationcomment.notificationcomments) %> +

<%= format_time(notificationcomment.created_at) %><%= link_to_if_authorized_contest image_tag('delete.png'), {:controller => 'notificationcomments', :action => 'destroy', :id => @contestnotifications, :notificationcomment_id => notificationcomment}, + :data => {:confirm => l(:text_are_you_sure)}, :method => :delete, :title => l(:button_delete) %>
+ <% end if @notificationcomments.any? %> +
+ + diff --git a/app/views/layouts/_base_footer.html.erb b/app/views/layouts/_base_footer.html.erb index 3d55869a4..c62a974d0 100644 --- a/app/views/layouts/_base_footer.html.erb +++ b/app/views/layouts/_base_footer.html.erb @@ -8,12 +8,12 @@

- 主办单位: - <%= link_to "国防科学技术大学并行与分布处理国家重点实验室","http://www.nudt.edu.cn/ArticleShow.asp?ID=47",:target=>"_blank"%> - <%= link_to "计算机科学与技术系", "http://www.nudt.edu.cn/ArticleShow.asp?ID=41", :target => "_blank" %> - 版权@2007~2014 - <%= link_to "联系我们","http://forge.trustie.net/projects/2/member", :target=>"_blank" %> - <%= link_to "湘ICP备09019772","http://www.miibeian.gov.cn/", :target => "_blank" %> + <%=l(:label_organizers)%> + <%= link_to l(:label_organizers_information),"http://www.nudt.edu.cn/ArticleShow.asp?ID=47",:target=>"_blank"%> + <%= link_to l(:label_organizers_information_institute), "http://www.nudt.edu.cn/ArticleShow.asp?ID=41", :target => "_blank" %> + <%=l(:label_copyright)%>@2007~2014 + <%= link_to l(:label_contact_us),"http://forge.trustie.net/projects/2/member", :target=>"_blank" %> + <%= link_to l(:label_record),"http://www.miibeian.gov.cn/", :target => "_blank" %>

-<% end %> \ No newline at end of file +<% end %> diff --git a/app/views/layouts/_base_softapplication_index_top_content.html.erb b/app/views/layouts/_base_softapplication_index_top_content.html.erb index d029d27e4..7fa65bec4 100644 --- a/app/views/layouts/_base_softapplication_index_top_content.html.erb +++ b/app/views/layouts/_base_softapplication_index_top_content.html.erb @@ -1,7 +1,7 @@
- +
创新竞赛社区<%=l(:label_contest_innovate_community)%> <%= l(:label_user_location) %> :