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..6b05e8e4d --- /dev/null +++ b/app/controllers/contestnotifications_controller.rb @@ -0,0 +1,187 @@ +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 = Contestnotification.find(params[:id]) + @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/controllers/welcome_controller.rb b/app/controllers/welcome_controller.rb index c20dfa36d..6105b22b2 100644 --- a/app/controllers/welcome_controller.rb +++ b/app/controllers/welcome_controller.rb @@ -95,6 +95,7 @@ class WelcomeController < ApplicationController def entry_select url = request.original_url if url.include?("course.trustie.net") + course render :course return 0 elsif url.include?("contest.trustie.net") diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 7bfe95123..e62339249 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) @@ -186,9 +193,8 @@ module ApplicationHelper end def thumbnail_tag(attachment) - imagepath = named_attachment_path(attachment, attachment.filename) - link_to image_tag(imagepath), - imagepath , + link_to image_tag(thumbnail_path(attachment)), + named_attachment_path(attachment, attachment.filename), :title => attachment.filename end 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 448dcda14..111213c7a 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/attachments/_links.html.erb b/app/views/attachments/_links.html.erb index f73df8fb4..c135ee214 100644 --- a/app/views/attachments/_links.html.erb +++ b/app/views/attachments/_links.html.erb @@ -33,7 +33,7 @@ <% if images.any? %>
<% images.each do |attachment| %> -
<%= thumbnail_small_tag(attachment) %>
+
<%= thumbnail_tag(attachment) %>
<% 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..fc71bc64a --- /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 %> + +<% 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..eea4cc204 --- /dev/null +++ b/app/views/contestnotifications/show.html.erb @@ -0,0 +1,91 @@ + +
+ <%= 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 %>

+ + + +
+ +
+ <%= 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 @@
- + diff --git a/app/views/open_source_projects/showmemo.html.erb b/app/views/open_source_projects/showmemo.html.erb index 387237113..7c3bd5c31 100644 --- a/app/views/open_source_projects/showmemo.html.erb +++ b/app/views/open_source_projects/showmemo.html.erb @@ -51,5 +51,6 @@ :title => l(:button_delete) ) if @forum.destroyable_by?(User.current) %> +
<%= render :partial => 'open_source_projects/show_memo', :locals => {:memos => @memos, :open_source_project => @open_source_project} %>
\ No newline at end of file diff --git a/app/controllers/roles_controller.rb b/app/views/roles/roles_controller.rb similarity index 100% rename from app/controllers/roles_controller.rb rename to app/views/roles/roles_controller.rb diff --git a/app/views/welcome/_link_to_another.html.erb b/app/views/welcome/_link_to_another.html.erb index f5f360d3e..bda48e753 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/contest.html.erb b/app/views/welcome/contest.html.erb index e6c3ab1f5..c87cc13e1 100644 --- a/app/views/welcome/contest.html.erb +++ b/app/views/welcome/contest.html.erb @@ -109,7 +109,7 @@
@@ -118,13 +118,13 @@
- <%= l(:label_welcome_trustie) %><%= l(:label_welcome_trustie_contest) %> , <%= l(:label_welcome_trustie_contest_description) %> + <%= l(:label_welcome_trustie) %> <%= l(:label_welcome_trustie_contest) %> , <%= l(:label_welcome_trustie_contest_description) %>
<%= form_tag({controller: 'contests', action: 'index'}, method: :get) do %> - <%= text_field_tag 'name', params[:name], placeholder:'请输入要搜索的关键字', name: "name", :class => 'blueinputbar', :style => 'width:240px; padding-right:50px;'%> + <%= text_field_tag 'name', params[:name], :placeholder => l(:label_search_intimation), name: "name", :class => 'blueinputbar', :style => 'width:240px; padding-right:50px;'%>   <%= hidden_field_tag 'project_type', params[:project_type] %> <%= submit_tag l(:label_search), :class => "enterprise" , :name => nil%> @@ -138,9 +138,9 @@
-
-

最新热门竞赛

- <%= link_to "更多>>", {:controller => 'contests', :action => 'index', :host => Setting.contest_domain}, :target => "_blank" %> +
+

<%=l(:label_current_hot_contest)%>

+ <%= link_to l(:label_more_information), {:controller => 'contests', :action => 'index', :host => Setting.contest_domain}, :target => "_blank" %>
<% find_all_hot_contest.map do |contest| break if(contest == find_all_hot_contest[5]) %> @@ -154,9 +154,9 @@ <%= link_to(contest.name, show_contest_contest_path(contest.id), :class => "d-g-blue d-p-project-name", :title => "#{contest.name}", :target => "_blank") %> <% if contest.id == 2 or contest.id == 3 or contest.id == 6 %> - (<%= link_to("含#{contest.projects.where('is_public=1').count}个作品", show_attendingcontest_contest_path(contest), :target => "_blank") %>) + (<%= link_to("#{contest.projects.where('is_public=1').count}"+l(:label_work_quantity), show_attendingcontest_contest_path(contest), :target => "_blank") %>) <% else %> - (<%= link_to("含#{contest.contesting_softapplications.count}个作品", show_attendingcontest_contest_path(contest), :target => "_blank") %>) + (<%= link_to("#{contest.contesting_softapplications.count}"+l(:label_work_quantity), show_attendingcontest_contest_path(contest), :target => "_blank") %>) <% end %>
@@ -166,7 +166,7 @@
- 发布时间:<%=format_time contest.created_on %> + <%=l(:label_release_time)%>: <%=format_time contest.created_on %>
@@ -177,16 +177,39 @@
+
+

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

+ <%#= link_to l(:label_more_information), forums_path %> +
+
+
2014年Android程序设计大赛获奖名单
+
+ +
一等奖: 消灭那怪兽
+
二等奖: 兄弟向前冲
+
二等奖: 鸟鸟文件管理器(银河之光版)
+
三等奖: 疯狂猜图
+
三等奖: 愉快的定向越野
+
三等奖: 体能训练助手
+
三等奖: 迷你日记本
+
三等奖: 永齐飞机大战
+
+
+
+
+

- 问题和反馈动态 - <%= link_to "我要提问" , newbie_send_path, {:class => 'orangeButton idea_btn', :style => "color: #EEEEEE" }%> - <%= link_to "我要反馈" , suggestion_send_path, {:class => 'orangeButton idea_btn', :style => "color: #EEEEEE" }%> + <%=l(:label_issue_feedback_activities)%> + <%= link_to l(:label_my_question), newbie_send_path, {:class => 'orangeButton idea_btn', :style => "color: #EEEEEE" }%> + <%= link_to l(:label_my_feedback), suggestion_send_path, {:class => 'orangeButton idea_btn', :style => "color: #EEEEEE" }%>

- <%= link_to "更多>>", forums_path %> + <%= link_to l(:label_more_information), forums_path %>
    - <% find_new_forum_topics(11).each do |topic|%> + <% find_new_forum_topics(8).each do |topic|%>
  •       @@ -197,13 +220,13 @@ <%= "#{l(:label_updated_time, value: time_tag_welcome(topic_last_time topic))}".html_safe %> - 楼主: <%= link_to_user(topic.author) %> + <%=l(:label_question_sponsor)%>: <%= link_to_user(topic.author) %> - 最后回复:<%=link_to_user topic.last_reply.try(:author) %> + <%=l(:label_final_reply)%>: <%=link_to_user topic.last_reply.try(:author) %> - 回复(<%= link_to topic.try(:replies_count), topic.event_url %>) + <%=l(:label_reply)%>(<%= link_to topic.try(:replies_count), topic.event_url %>)
@@ -213,9 +236,10 @@
-
-

最新参赛作品

- <%= link_to "更多>>", {:controller => 'softapplications', :action => 'index', :host => Setting.contest_domain}, :target => "_blank" %> + +
+

<%=l(:label_current_attendingcontest_work)%>

+ <%= link_to l(:label_more_information), {:controller => 'softapplications', :action => 'index', :host => Setting.contest_domain}, :target => "_blank" %>
<% if Softapplication.count > 0%>
@@ -235,7 +259,7 @@

- 发布时间:<%=format_time softapplication.created_at %> + <%=l(:label_release_time)%>: <%=format_time softapplication.created_at %>
@@ -249,6 +273,8 @@
+ +
<%= render partial: 'link_to_another' %> diff --git a/app/views/welcome/index.html.erb b/app/views/welcome/index.html.erb index a9d7e994a..08d7d13d4 100644 --- a/app/views/welcome/index.html.erb +++ b/app/views/welcome/index.html.erb @@ -54,7 +54,7 @@
    <% projects = find_miracle_project(10, 3) %> <% projects.map do |project| %> - <% cache "welcome_index_hotProject_ul_#{project}_li" do %> + <% cache "welcome_index_hotProject_ul_project_#{project.id}_li" do %>
  • <%= image_tag(get_project_avatar(project), :class => "avatar-4") %> @@ -88,7 +88,7 @@
    <%activities = find_all_activities%> <% activities.each do |event| %> - <% cache "welcome_index_userActivity_ul_#{event}_li" do %> + <% cache "welcome_index_userActivity_ul_event_#{event.class}_#{event.id}_li" do %>
  • <%= image_tag url_to_avatar(event.event_author), :class => "avatar-3" %> @@ -118,8 +118,8 @@ <% end %>
    <% topics = find_new_forum_topics(7) %> - <% topics.each do |topic|%> - <% cache "welcome_index_memosActivity_ul_#{topic}_li" do %> + <% topics.includes(:forum, :last_reply, :author).each do |topic|%> + <% cache "welcome_index_memosActivity_ul_topic_#{topic.id}_li" do %>
  • <%= link_to '['+topic.forum.name + ']',forum_path(topic.forum),:class => 'memo_Bar_title' %><%= link_to topic.subject.truncate(30, omission: '...'), topic.event_url,title: topic.subject %> diff --git a/config/configuration.yml b/config/configuration.yml index e7138b587..a98ea3391 100644 --- a/config/configuration.yml +++ b/config/configuration.yml @@ -173,7 +173,7 @@ default: # Absolute path (e.g. /usr/bin/convert, c:/im/convert.exe) to # the ImageMagick's `convert` binary. Used to generate attachment thumbnails. - imagemagick_convert_command: '/home/pdl/redmine-2.3.1-1/common/bin/convert' + imagemagick_convert_command: '/home/pdl/redmine-2.3.2-0/common/bin/convert' # Configuration of RMagcik font. # diff --git a/config/locales/en.yml b/config/locales/en.yml index d8bfc966c..0f987b81b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1199,7 +1199,7 @@ en: label_message: message board field_add: Add before %{time} button_more: More - label_user_response: Feedbacks # modified by bai + label_user_response: Feedback # modified by bai label_bidding_project: projects button_bidding: I will participate in it label_new_call: New call @@ -1228,9 +1228,9 @@ en: label_follow_people: following # modified by bai #modify by men label_x_follow_people: - zero: follower - one: follower - other: followers + zero: Follower + one: Follower + other: Followers #end label_member_since: joined label_contribute_to: Participates %{project_count} projects: @@ -1271,9 +1271,9 @@ en: other: comments #end label_x_followers: #modified by men - zero: follower - one: follower - other: followers + zero: Follower + one: Follower + other: Followers #end @@ -1406,7 +1406,7 @@ en: label_bid_project: projects label_project_no_follow: The project hasn't been followed now! label_no_bid_project: has no participate project - label_bids_reward_method: reward: + label_bids_reward_method: Reward: label_bids_reward_what: input what for reward label_call_bonus: bonus label_bids_form_new_description: Publish a requirement,a competition or a course work. @@ -1423,11 +1423,13 @@ en: #end label_bids_published: published label_bids_published_ago: ago - label_welcome_trustie: Trustie forge + label_welcome_trustie: Trustie label_welcome_trustie_project: Online projects hosting platform label_welcome_trustie_course: Online Courses practice platform + label_welcome_trustie_contest: Online Contests practice platform label_welcome_trustie_project_description: Software for Chinese college students and practitioners to provide social-oriented project management, code hosting, resource sharing, cooperation and exchange. label_welcome_trustie_course_description: Teachers and Students for Chinese universities to provide social-oriented curriculum management, resource sharing, cooperation achieved, collaborative research. + label_welcome_trustie_contest_description: Software for Chinese college students and practitioners to provide social-oriented contest management, code hosting, resource sharing, cooperation and exchange. label_welcome_trustie_description: a socialized collaboration platform for project management, collaborative research, software development and software crowdsourcing for creative university students and entrepreneurs. label_user_project: Projects label_bid_respond_quote: Respond @@ -1579,7 +1581,11 @@ en: label_course_file: File label_stores_index: Resource search label_course_news: News - + #wang + label_contest_userresponse: Userresponse + label_contest_joincontest: Joincontest + label_contest_notification: Notification + #end label_x_base_courses_member: zero: member one: member @@ -1607,7 +1613,7 @@ en: label_user_location: Location label_requirement_enterprise: Requirements label_requirement_enterprise_list: Requirements List - label_contest_innovate: Competitions + label_contest_innovate: Competition community label_software_user: Users label_course_practice: Courses label_course_all: Teacher @@ -1642,5 +1648,144 @@ en: label_have_message : have a new message label_login_prompt: Email/NickName :lable_not_receive_mail: Click here don't receive email form site! +#added by linchun as competition# + + label_current_hot_contest: Latest Hot Competition + label_current_attendingcontest_work: Latest Competition Work + label_issue_feedback_activities: Question&Feedback + label_more_information: More... + label_my_question: My-question + label_my_feedback: My-feedback + label_release_time: Release-time + label_question_sponsor: Sponsor + label_final_reply: Final-reply + label_reply: Reply + label_weixin: WeiXin + label_search_intimation: please input the keywords + label_work_quantity: work + label_projects_management_platform: Projects-platform + label_courses_management_platform: Courses-platform + label_contests_management_platform: Competitions-platform + label_contest_work: Competition work + label_contests_reward_method: Reward method + label_attendingcontestwork_developers: Developers + label_attendingcontestwork_release_time: Release time + label_attendingcontestwork_belongs_contest: Contesting + label_attendingcontestwork_belongs_type: Work-type + label_attendingcontestwork_release_person: Release person + label_attendingcontestwork_adaptive_system: Adaptive-system + label_attendingcontestwork_download: Work download + label_attendingcontestwork_average_scores: Average score + label_attendingcontestwork_deposit_project: Deposit project + label_attendingcontestwork_sorting_intimation: You can re-scoring, but just record the last scoring result! + + label_upload_files: Files-upload + label_upload_softwarepackage: Softwarepackage-upload + label_upload_cuttingphoto: Photo-upload + label_system_platform: Platform + label_nextstep: Next + label_participate: Participate + label_setting: Setting + label_contest_project: Competition-project + label_contest_softapplication: Competition-application + label_contest_response: Feedback + label_contest_watchers: Watchers + label_contest_work: Competition-work + button_contesting_as_project: Competition(New-project) + button_contesting_as_application: Competition(Release-app) + label_release_softapplication: Release-application + label_upload_softapplication_packets: Upload-apppacket + label_upload_softapplication_photo: Upload-appphoto + label_upload_softapplication_packets_mustpacketed: Works code and ralated-document must be packaged before upload. + label_upload_softapplication_photo_condition: Need upload 0~4 works screenshot, each is less than 5M, photo format such as gif,jpg,png etc. + label_updated_caution: Note:if you edit the work, the uploaded screenshot and package will be deleted, please re-load! + label_softapplication_name: App-name + label_work_name: Work name + label_softapplication_description: App-description + label_work_description: Work description + label_work_scores: Work score + label_work_rating: Work rating + label_work_tishi: You can re-scoring, but just record the last scoring result! + label_work_scores_proportion: Score porportion + label_softapplication_type: App-type + label_work_type: Work type + label_work_photo: Work photo + label_work_comment: Work comment + label_softapplication_version_available: Version + label_running_platform: Running platform + label_softapplication_developer: Upload person + label_softapplication_developers: Developers + label_work_deposit_project_url: Deposit url + label_work_deposit_project: Deposit project + label_softapplication_name_condition: Less than 50 characters + label_softapplication_description_condition: Less than 250 characters + label_user_login_softapplication_board: You are not logged in, please log in and then participate in the evaluation! + label_user_login_attending_contest: You are not logged in, please log in and then join the competition! + label_contest_description_no: No description + label_no_contest_softapplication: No application + label_button_ok: Ok + label_tags_contest: Competition tag + label_final_scores: Final scores + label_rating_person_amount: Rating person + label_tags_contest_description: Contest description + label_release_add_contest_succeed: The application succeed released and added! + label_add_contest_succeed_fail: Added fails, the application has been joined the competition! + label_no_ftapplication: No application + label_edit_softapplication: Edit application + label_edit_work: Edit work + label_contest_delete: Delete contest + label_noawards_current: No awards + label_softapplication: Application software + label_attending_contest: Joining + label_new_attendingcontest_work: New competition work + label_workname_lengthlimit: Less than 50 characters + label_workdescription_lengthlimit: Less than 250 characters + label_please_input_password: Please input the competition password! + label_please_select_project: Please select the project! + label_upload_softworkpacket_photo: Upload work package and screenshots + label_reward: Reward + label_please_select_contestingsoftapplication: Please select the competition application! + label_attendingcontest_time: Join-contest time + label_attendingcontest_spoksman: Join-contest representive + label_wellmeaning_intimation_contentone: Note:if you are ready attenging contest, please click"New competition work"! + label_wellmeaning_intimation_contenttwo: if you have already completed the development, and just release your work, you can not select"Deposit project"! + label_wellmeaning_intimation_contentthree: if you want to deposit the competition data and code, and want to keep track of the development and code-submission,please selcet a created project from"Deposit project", if you have no project, please click"New project"! + + notice_attendingcontest_work_successfully_created: Congratulations, competition work successfully created! + notice_softapplication_was_successfully_updated: Congratulations, competition work successfully updated! + + label_contest_notification: Notice + lable_contest_user: Release person + label_contest_innovate_community: Competition community + + label_user_login_score_and_comment: You are not logged in, please log in and then score and comment the work! + label_user_login_notificationcomment: You are not logged in, please log in and then comment the notification! + label_contest_work_list: Competition work list + + + label_borad_project: Project-borad + label_search_intimation: please input the searching keywords! + label_update_time: Update time + label_project_notice: release the notice + label_no_file_uploaded: No file uploaded + label_forum_new: New forum + label_memo_new_from_forum: Release memo + + label_user_grade: Individual score + label_active_homework: homework + label_course_term: Semester + label_comment_time: Comment time + label_bidding_user_studentcode: Student ID + + label_organizers: Organizer + label_organizers_information: National Key Laboratory of Parallel and Distributed Processing, NUDT + label_organizers_information_institute: Department of Computer Sciencer and Technology + label_copyright: Copyright + label_contact_us: Contact us + label_record: 湘ICP备09019772 + label_check_comment: Check comment + label_notification: Notification +#end + # ajax异步验证 modal_valid_passing: can be used. diff --git a/config/locales/zh.yml b/config/locales/zh.yml index 0625ebe6a..483d5e10b 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -563,7 +563,7 @@ zh: label_enterprise_into: 进入企业 label_college_into: 进入高校 label_investor: 投资人: - lable_contest_user: 竞赛发布人: #huang + lable_contest_user: 竞赛发布人 label_user_home: 创客空间 label_user_location: 当前位置 label_course_term: 开课学期 @@ -586,6 +586,7 @@ zh: label_user_login_project_board: 您还没有登录,请登录后参与项目讨论 label_user_login_attending_contest: 您还没有登录,请登录后参赛 label_user_login_score_and_comment: 您还没有登录,请登录后对作品进行打分评价 + label_user_login_notificationcomment: 您还没有登录,请登录后参加评论 #end #by huang # modified by bai label_college: 高校进入 @@ -1730,6 +1731,11 @@ zh: label_course_homework_list: 作业列表 label_course_homework_new: 发布作业 label_fork_homework_new: 选为作业 + #wang + label_contest_userresponse: 用户留言 + label_contest_joincontest: 参入竞赛 + label_contest_notification: 竞赛通知 + #end label_x_course_data: zero: 资料 @@ -1995,6 +2001,36 @@ zh: label_attendingcontestwork_deposit_project: 托管项目 label_attendingcontestwork_sorting_intimation: 您可以重新打分,打分结果以最后一次打分为主! lable_not_receive_mail: 点此设置接收本站邮件偏好! + label_contest_notification: 竞赛通知 + label_contest_innovate_community: 创新竞赛社区 + #english site translation + label_current_hot_contest: 最新热门竞赛 + label_current_attendingcontest_work: 最新参赛作品 + label_issue_feedback_activities: 问题和反馈动态 + label_more_information: 更多... + label_my_question: 我要提问 + label_my_feedback: 我要反馈 + label_release_time: 发布时间 + label_question_sponsor: 楼主 + label_final_reply: 最后回复 + label_reply: 回复 + label_weixin: 微信扫码 + label_search_intimation: 请输入要搜索的关键字 + label_work_quantity: 个作品 + label_projects_management_platform: 项目托管平台 + label_courses_management_platform: 课程实践平台 + label_contests_management_platform: 竞赛托管平台 + + label_organizers: 主办单位 + label_organizers_information: 国防科学技术大学并行与分布处理国家重点实验室 + label_organizers_information_institute: 计算机科学与技术系 + label_copyright: 版权 + label_contact_us: 联系我们 + label_record: 湘ICP备09019772 + label_check_comment: 查看通知评论 + label_notification: 通知公告 + #end + #end # ajax异步验证 diff --git a/config/routes.rb b/config/routes.rb index 5a5810c78..03b437eeb 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -16,6 +16,10 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. RedmineApp::Application.routes.draw do + + + #match '/contests/:id/contestnotifications', :controller => 'contestnotifications', :action => 'index' + resources :homework_users resources :no_uses @@ -76,8 +80,17 @@ RedmineApp::Application.routes.draw do end end + #resources :contestnotifications, :only => [:index, :show, :edit, :update, :destroy] + # match '/contestnotifications/:id/notificationcomments', :to => 'notificationcomments#create', :via => :post + # match '/contestnotifications/:id/notificationcomments/:notificationcomment_id', :to => 'notificationcomments#destroy', :via => :delete + match '/contestnotifications/preview', :controller => 'previews', :action => 'contestnotification', :as => 'preview_contestnotifications', :via => [:get, :post, :put] ## new added by linchun #新竞赛相关 resources :contests, only: [:index] do + resources :contestnotifications do + # get 'preview', on: :collection + resources :notificationcomments + end + collection do match 'new_contest' , via: :get match 'join_in_contest' , via: :post @@ -87,13 +100,14 @@ RedmineApp::Application.routes.draw do match 'new' , via: :post end member do + delete 'destroy_contest' match 'add_softapplication' match 'update_contest' , via: [:put] - match 'show_contest' , via: :get + match 'show_contest' , via: [:get, :post] match 'show_project' , via: :get match 'show_softapplication' , via: :get match 'show_attendingcontest' , via: :get - match 'show_notification' , via: :get + #match 'show_notification' , via: :get match 'show_participator' , via: :get match 'set_reward_project' , via: [:get, :post] match 'set_reward_softapplication' , via: [:get, :post] @@ -657,6 +671,7 @@ RedmineApp::Application.routes.draw do get 'school/search_school/', :to => 'school#search_school' post 'school/upload', :to => 'school#upload' + get 'school/upload_logo', :to => 'school#upload_logo' ######added by nie match 'tags/show_projects_tags',:to => 'tags#show_projects_tags' diff --git a/db/migrate/20140401004102_create_relative_memos.rb b/db/migrate/20140401004102_create_relative_memos.rb index 6f0d776db..04b8862a3 100644 --- a/db/migrate/20140401004102_create_relative_memos.rb +++ b/db/migrate/20140401004102_create_relative_memos.rb @@ -4,7 +4,7 @@ class CreateRelativeMemos < ActiveRecord::Migration t.integer :osp_id, :null => true t.integer :parent_id, null: true t.string :subject, null: false - t.mediumtext :content, null: false + t.text :content, null: false t.integer :author_id t.integer :replies_count, default: 0 t.integer :last_reply_id diff --git a/db/migrate/20140530010015_create_contestnotifications.rb b/db/migrate/20140530010015_create_contestnotifications.rb new file mode 100644 index 000000000..5aa1e2f9f --- /dev/null +++ b/db/migrate/20140530010015_create_contestnotifications.rb @@ -0,0 +1,14 @@ +class CreateContestnotifications < ActiveRecord::Migration + def change + create_table :contestnotifications do |t| + t.integer :contest_id + t.string :title + t.string :summary + t.string :description + t.integer :author_id + t.integer :notificationcomments_count + + t.timestamps + end + end +end diff --git a/db/migrate/20140605003915_create_notificationcomments.rb b/db/migrate/20140605003915_create_notificationcomments.rb new file mode 100644 index 000000000..58588d0a5 --- /dev/null +++ b/db/migrate/20140605003915_create_notificationcomments.rb @@ -0,0 +1,12 @@ +class CreateNotificationcomments < ActiveRecord::Migration + def change + create_table :notificationcomments do |t| + t.string :notificationcommented_type + t.integer :notificationcommented_id + t.integer :author_id + t.text :notificationcomments + + t.timestamps + end + end +end diff --git a/lib/redmine.rb b/lib/redmine.rb index 7d3aa9ea7..0fb13076e 100644 --- a/lib/redmine.rb +++ b/lib/redmine.rb @@ -93,6 +93,7 @@ Redmine::AccessControl.map do |map| map.permission :edit_project, {:projects => [:settings, :edit, :update]}, :require => :member map.permission :close_project, {:projects => [:close, :reopen]}, :require => :member, :read => true map.permission :select_project_modules, {:projects => :modules}, :require => :member + map.permission :select_contest_modules, {:contests => :modules}, :require => :member map.permission :manage_members, {:projects => :settings, :members => [:index, :show, :create, :update, :destroy, :autocomplete]}, :require => :member map.permission :manage_versions, {:projects => :settings, :versions => [:new, :create, :edit, :update, :close_completed, :destroy]}, :require => :member map.permission :add_subprojects, {:projects => [:new, :create]}, :require => :member @@ -146,6 +147,12 @@ Redmine::AccessControl.map do |map| map.permission :comment_news, {:comments => :create} end + map.contest_module :contestnotifications do |map| + map.permission :manage_contestnotifications, {:contestnotifications => [:new, :create, :edit, :update, :destroy], :notificationcomments => [:destroy]}, :require => :member + map.permission :view_contestnotifications, {:contestnotifications => [:index, :show]}, :public => true, :read => true + map.permission :notificationcomment_contestnotifications, {:notificationcomments => :create} + end + map.project_module :documents do |map| map.permission :add_documents, {:documents => [:new, :create, :add_attachment]}, :require => :loggedin map.permission :edit_documents, {:documents => [:edit, :update, :add_attachment]}, :require => :loggedin @@ -306,7 +313,8 @@ Redmine::MenuManager.map :contest_menu do |menu| #menu.push :project, :show_project_contest_path, :caption => :label_contest_project #menu.push :application, :show_softapplication_contest_path, :caption => :label_contest_application menu.push :attendingcontest, {:controller => 'contests', :action => 'show_attendingcontest'}, :caption => :label_attending_contest - # menu.push :contestnotification, {:controller => 'contests', :action => 'show_notification'}, :caption => :label_contest_notification + menu.push :contestnotifications, { :controller => 'contestnotifications', :action => 'index' }, :param => :contest_id, :caption => :label_contest_notification + #menu.push :contestnotification, {:controller => 'contests', :action => 'show_notification'}, :caption => :label_contest_notification # menu.push :attendingcontest, :show_attendingcontest_contest_path, :caption => :label_attendin,g_contest # menu.push :result, { :controller => 'bids', :action => 'show_results' }, # :caption => :label_bidding_results,:if => Proc.new{ |p| User.current.id == p } @@ -409,6 +417,7 @@ Redmine::Activity.map do |activity| activity.register :issues, :class_name => %w(Issue Journal) activity.register :changesets activity.register :news + activity.register :contestnotification activity.register :documents, :class_name => %w(Document Attachment) activity.register :files, :class_name => 'Attachment' activity.register :wiki_edits, :class_name => 'WikiContent::Version', :default => false @@ -424,6 +433,7 @@ end Redmine::Search.map do |search| search.register :issues search.register :news + search.register :contestnotification search.register :documents search.register :changesets search.register :wiki_pages diff --git a/lib/redmine/access_control.rb b/lib/redmine/access_control.rb index 7c4a5a5ec..dfde5debc 100644 --- a/lib/redmine/access_control.rb +++ b/lib/redmine/access_control.rb @@ -67,20 +67,26 @@ module Redmine def available_project_modules @available_project_modules ||= @permissions.collect(&:project_module).uniq.compact end - + def available_contest_modules + @available_contest_modules ||= @permissions.collect(&:contest_module).uniq.compact + end + def modules_permissions(modules) @permissions.select {|p| p.project_module.nil? || modules.include?(p.project_module.to_s)} + @permissions.select {|p| p.contest_module.nil? || modules.include?(p.contest_module.to_s)} end end class Mapper def initialize @project_module = nil + @contest_module = nil end def permission(name, hash, options={}) @permissions ||= [] options.merge!(:project_module => @project_module) + options.merge!(:contest_module => @contest_module) @permissions << Permission.new(name, hash, options) end @@ -90,13 +96,19 @@ module Redmine @project_module = nil end + def contest_module(name, options={}) + @contest_module = name + yield self + @contest_module = nil + end + def mapped_permissions @permissions end end class Permission - attr_reader :name, :actions, :project_module + attr_reader :name, :actions, :project_module, :contest_module def initialize(name, hash, options) @name = name @@ -105,6 +117,8 @@ module Redmine @require = options[:require] @read = options[:read] || false @project_module = options[:project_module] + @contest_module = options[:contest_module] + hash.each do |controller, actions| if actions.is_a? Array @actions << actions.collect {|action| "#{controller}/#{action}"} diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css index f5a21da5f..57a9ea013 100644 --- a/public/stylesheets/application.css +++ b/public/stylesheets/application.css @@ -2072,6 +2072,7 @@ button.tab-left, button.tab-right { padding:4px; width: 20px; bottom: -1px; + } button.tab-left { @@ -2115,6 +2116,9 @@ button.tab-right { font-weight:bold; border-top-left-radius:4px; border-top-right-radius:4px; + /*new added*/ + margin-top: 16px; + /*end*/ } #content .tabs_new ul li a:hover { @@ -2747,6 +2751,12 @@ div.repos_explain{ border-bottom: 1px dashed rgb(204, 204, 204); width: 688px; } +.underline-contests_four{ + margin-bottom: 10px; + border-bottom: 1px dashed rgb(204, 204, 204); + width: 349px; + padding-bottom:5px +} .contest-star{ color: #bb0000; } diff --git a/public/stylesheets/buglist-div-use.css b/public/stylesheets/buglist-div-use.css index de0c7c4ad..8ee6af1e8 100644 --- a/public/stylesheets/buglist-div-use.css +++ b/public/stylesheets/buglist-div-use.css @@ -31,7 +31,7 @@ overflow: hidden; float: left; width: 440px; - left: 3%; + left: 2%; } diff --git a/public/stylesheets/buglist.css b/public/stylesheets/buglist.css index 4bc9267f7..49e816581 100644 --- a/public/stylesheets/buglist.css +++ b/public/stylesheets/buglist.css @@ -9,6 +9,7 @@ padding:0 0 0 0px; .li_time { padding:0 7px 0 0; +list-style-type: square; } diff --git a/test/fixtures/contestnotifications.yml b/test/fixtures/contestnotifications.yml new file mode 100644 index 000000000..6409a5f71 --- /dev/null +++ b/test/fixtures/contestnotifications.yml @@ -0,0 +1,17 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html + +one: + contest_id: 1 + title: MyString + summary: MyString + description: MyString + author_id: 1 + comments_count: 1 + +two: + contest_id: 1 + title: MyString + summary: MyString + description: MyString + author_id: 1 + comments_count: 1 diff --git a/test/fixtures/notificationcomments.yml b/test/fixtures/notificationcomments.yml new file mode 100644 index 000000000..54c42b849 --- /dev/null +++ b/test/fixtures/notificationcomments.yml @@ -0,0 +1,13 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/Fixtures.html + +one: + notificationcommented_type: MyString + notificationcommented_id: 1 + author_id: 1 + notificationcomments: MyText + +two: + notificationcommented_type: MyString + notificationcommented_id: 1 + author_id: 1 + notificationcomments: MyText diff --git a/test/functional/contestnotifications_controller_test.rb b/test/functional/contestnotifications_controller_test.rb new file mode 100644 index 000000000..948955a87 --- /dev/null +++ b/test/functional/contestnotifications_controller_test.rb @@ -0,0 +1,49 @@ +require 'test_helper' + +class ContestnotificationsControllerTest < ActionController::TestCase + setup do + @contestnotification = contestnotifications(:one) + end + + test "should get index" do + get :index + assert_response :success + assert_not_nil assigns(:contestnotifications) + end + + test "should get new" do + get :new + assert_response :success + end + + test "should create contestnotification" do + assert_difference('Contestnotification.count') do + post :create, contestnotification: { author_id: @contestnotification.author_id, comments_count: @contestnotification.comments_count, contest_id: @contestnotification.contest_id, description: @contestnotification.description, summary: @contestnotification.summary, title: @contestnotification.title } + end + + assert_redirected_to contestnotification_path(assigns(:contestnotification)) + end + + test "should show contestnotification" do + get :show, id: @contestnotification + assert_response :success + end + + test "should get edit" do + get :edit, id: @contestnotification + assert_response :success + end + + test "should update contestnotification" do + put :update, id: @contestnotification, contestnotification: { author_id: @contestnotification.author_id, comments_count: @contestnotification.comments_count, contest_id: @contestnotification.contest_id, description: @contestnotification.description, summary: @contestnotification.summary, title: @contestnotification.title } + assert_redirected_to contestnotification_path(assigns(:contestnotification)) + end + + test "should destroy contestnotification" do + assert_difference('Contestnotification.count', -1) do + delete :destroy, id: @contestnotification + end + + assert_redirected_to contestnotifications_path + end +end diff --git a/test/functional/notificationcomments_controller_test.rb b/test/functional/notificationcomments_controller_test.rb new file mode 100644 index 000000000..21496467e --- /dev/null +++ b/test/functional/notificationcomments_controller_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class NotificationcommentsControllerTest < ActionController::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/unit/contestnotification_test.rb b/test/unit/contestnotification_test.rb new file mode 100644 index 000000000..22b8113c7 --- /dev/null +++ b/test/unit/contestnotification_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class ContestnotificationTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/unit/helpers/contestnotifications_helper_test.rb b/test/unit/helpers/contestnotifications_helper_test.rb new file mode 100644 index 000000000..d79755d82 --- /dev/null +++ b/test/unit/helpers/contestnotifications_helper_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class ContestnotificationsHelperTest < ActionView::TestCase +end diff --git a/test/unit/helpers/notificationcomments_helper_test.rb b/test/unit/helpers/notificationcomments_helper_test.rb new file mode 100644 index 000000000..ecec0cbde --- /dev/null +++ b/test/unit/helpers/notificationcomments_helper_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class NotificationcommentsHelperTest < ActionView::TestCase +end diff --git a/test/unit/notificationcomments_test.rb b/test/unit/notificationcomments_test.rb new file mode 100644 index 000000000..798084efb --- /dev/null +++ b/test/unit/notificationcomments_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class NotificationcommentsTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end
创新竞赛社区<%=l(:label_contest_innovate_community)%> <%= l(:label_user_location) %> :