# encoding: utf-8 # # Redmine - project management software # Copyright (C) 2006-2013 Jean-Philippe Lang # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. require 'forwardable' require 'cgi' require 'iconv' module ApplicationHelper include Redmine::WikiFormatting::Macros::Definitions include Redmine::I18n include GravatarHelper::PublicMethods include Redmine::Pagination::Helper include AvatarHelper ## added by william include PraiseTreadHelper include CoursesHelper extend Forwardable def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter # 课堂相关controller def course_controller ["courses", "homework_common", "student_work", "exercise", "poll", "boards", "messages", "graduation_topics", "graduation_tasks", "graduation_works", "files"] end # 实训课程相关controller def subjects_controller ["subjects", "stages"] end # 实训路径相关controller def shixuns_controller ["shixuns", "challenges", "myshixuns", "games"] end # 工程认证相关controller def ecs_controller ["ecs", "ec_courses", "ec_course_evaluations", "ec_course_supports", "ec_course_targets", "ec_graduation_requirements", "ec_major_schools", "ec_majors", "ec_years"] end def exercise_bank_json_data exercises exercises.map do |exercise| exercise_path = exercise_bank_path(exercise) course_list = exercise.course_list.name user_name = exercise.user.show_real_name user_path = user_path(exercise.user) exercise.attributes.dup.except("description", "is_public", "quotes", "container_id", "container_type", "created_at", "updated_at").merge({ user_name: user_name, user_path: user_path, course_list: course_list, exercise_path: exercise_path }) end end def ac_pass?(standard_value, real_value) standard_value && real_value && real_value > standard_value ? "达成" : "未达成" end def ec_pass?(standard_value, real_value) standard_value && real_value && real_value > standard_value ? 1 : 0 end # 工程认证删除关联课堂 def delete_course_correlation_ec_course_evaluations ec_course ec_course_evaluations = ec_course.ec_course_evaluations.where(:is_course_type => true) ec_course_evaluations.destroy_all if ec_course_evaluations end def sync_ec_year_student_score ec_subitem, ce, year_students, students, works, position=1 year_students.each do |year_student| if students.map(&:id).include?(year_student.id) work = works.where(:user_id => students.select{|s| s.id == year_student.id}[0].try(:user_id)).first score = work.respond_to?(:work_score) ? work.try(:work_score) : work.try(:score) else score = 0 end ec_subitem.ec_student_achievements << EcStudentAchievement.new(:ec_year_student_id => year_student.id, :student_number => year_student.student_id, :student_name => year_student.name, :score => score.to_f, :position => position, :ec_course_evaluation_id => ce.id) Rails.logger.info("############work_score:#{score}") end end # 同步在线课堂的考核标准和考核分项 # ec_course: 工程认证的课程 # course: 关联的在线课堂 def sync_course_correlation_ec_course_evaluations ec_course, course # 先删除之前的关联数据 delete_course_correlation_ec_course_evaluations ec_course students = EcYearStudent.find_by_sql("SELECT eys.id, eys.student_id, eys.name, uxe.user_id FROM ec_year_students eys JOIN (SELECT ue.student_id, ue.user_id FROM user_extensions ue JOIN students_for_courses sfc ON ue.`user_id` = sfc.`student_id` WHERE sfc.`course_id` = #{course.id})uxe ON eys.student_id = uxe.student_id WHERE eys.ec_year_id = #{ec_course.ec_year_id}") year_students = ec_course.ec_year.ec_year_students # 实训作业模块 shixun_models = course.homework_commons.where("homework_type = 4 and publish_time < '#{Time.now}'") unless shixun_models.blank? ce = EcCourseEvaluation.create(:name => "实训作业", :evluation_count => 1, :status => 2, :ec_course_id => ec_course.id, :is_course_type => true) shixun_models.each do |shixun| ec_subitem = EcCourseEvaluationSubitem.create(:name => shixun.name, :ec_course_evaluation_id => ce.id) sync_ec_year_student_score ec_subitem, ce, year_students, students, shixun.student_works end end # 普通作业模块 common_models = course.homework_commons.where("homework_type = 1 and publish_time < '#{Time.now}'") unless common_models.blank? ce = EcCourseEvaluation.create(:name => "普通作业", :evluation_count => 1, :status => 2, :ec_course_id => ec_course.id, :is_course_type => true) common_models.each do |common| ec_subitem = EcCourseEvaluationSubitem.create(:name => common.name, :ec_course_evaluation_id => ce.id) sync_ec_year_student_score ec_subitem, ce, year_students, students, common.student_works end end # 分组作业模块 group_models = course.homework_commons.where("homework_type = 3 and publish_time < '#{Time.now}'") unless group_models.blank? ce = EcCourseEvaluation.create(:name => "分组作业", :evluation_count => 1, :status => 2, :ec_course_id => ec_course.id, :is_course_type => true) group_models.each do |group| ec_subitem = EcCourseEvaluationSubitem.create(:name => group.name, :ec_course_evaluation_id => ce.id) sync_ec_year_student_score ec_subitem, ce, year_students, students, group.student_works end end # 试卷模块 exercise_models = course.exercises.where("exercise_status > 1") unless exercise_models.blank? ce = EcCourseEvaluation.create(:name => "试卷", :evluation_count => 1, :status => 2, :ec_course_id => ec_course.id, :is_course_type => true) exercise_models.each do |exercise| ec_subitem = EcCourseEvaluationSubitem.create(:name => exercise.exercise_name, :ec_course_evaluation_id => ce.id) sync_ec_year_student_score ec_subitem, ce, year_students, students, exercise.exercise_users end end # 毕设任务模块 task_models = course.graduation_tasks.where("publish_time < '#{Time.now}'") unless task_models.blank? ce = EcCourseEvaluation.create(:name => "毕设任务", :evluation_count => task_models.size, :status => 1, :ec_course_id => ec_course.id, :is_course_type => true) task_models.each_with_index do |task, index| ec_subitem = EcCourseEvaluationSubitem.create(:name => task.name, :ec_course_evaluation_id => ce.id) sync_ec_year_student_score ec_subitem, ce, year_students, students, task.graduation_works, index + 1 end end end # 选用实训的学校情况 def school_user_detail shixun user_ids = shixun.myshixuns.pluck(:user_id) schools = School.where(:id => UserExtensions.where(:user_id => user_ids).pluck(:school_id)) school_size = schools.size str = school_size > 0 ? "#{schools.limit(2).map(&:name).join("、")}等 #{school_size}所" : "0所" end def shixun_json_data shixuns shixuns.map do |shixun| school_detail = school_user_detail shixun preference = shixun.shixun_preference shixun_path = shixun_path(shixun) shixun.attributes.dup.merge({ school_detail: school_detail, preference: preference, shixun_path: shixun_path }) end end # 分班 def member_group_name members, user_id member = members.where(:user_id => user_id).first group_name = member.try(:course_group_id).to_i == 0 ? '未分班' : member.course_group.name end # 分班 def new_member_group_name course_id, user_id group_id = Member.where(:course_id => course_id, :user_id => user_id).pluck(:course_group_id).first group_id == 0 ? '未分班' : CourseGroup.where(:id => group_id).pluck(:name).first end # 分班id def member_group_id members, user_id member = members.where(:user_id => user_id).first group_id = member.try(:course_group_id).to_i end # 推荐实训 def recommend_shixun shixun shixun_id = ShixunTagRepertoire.where("tag_repertoire_id = #{shixun.tag_repertoires.first.present? ? shixun.tag_repertoires.first.try(:id) : 0} and shixun_id != #{shixun.id}").map(&:shixun_id) shixuns = Shixun.select([:id, :name, :user_id, :status, :myshixuns_count, :trainee, :identifier]).where(:id => shixun_id, :status => 2, :hidden => 0).order("myshixuns_count desc").limit(3) if shixuns.size < 3 ids = shixuns.size == 0 ? "(-1)" : "(" + shixuns.map(&:id).join(',') + ")" hot_shixuns = Shixun.select([:id, :name, :user_id, :status, :myshixuns_count, :trainee, :identifier]).where("status = 2 and hidden = 0 and id not in #{ids}").order("myshixuns_count desc").limit(3-shixuns.size) return shixuns + hot_shixuns else return shixuns end end # 用户获取的技能标签 def user_get_tags challenge_ids, user=User.current tags = ChallengeTag.where(:challenge_id => user.games.where(:challenge_id => challenge_ids, :status => 2).pluck(:challenge_id)).pluck(:name).uniq return tags end # 所属路径 def belongto_path shixun Subject.where(:id => shixun.stage_shixuns.map(&:subject_id), :hidden => 0).limit(2) end # 已授权老师加入示例课堂 def join_ex_course user course = Course.where(:id => 1309).first if course if course.members.where(:user_id => user.id).empty? member = Member.new(:role_ids => [9], :user_id => user.id) course.members << member Tiding.create(:user_id => user.id, :trigger_user_id => 1, :container_id => course.id, :container_type => 'TeacherJoinCourse', :belong_container_id => course.id, :belong_container_type => "Course", :tiding_type => "System", :extra => "9") end end end # 成员身份 def member_zh_role member role = "" if member.roles.first case member.roles.first.id when 3 role = "管理人员" when 4 role = "开发人员" when 5 role = "报告人员" end end end def container_limit mirror_repositories container = [] mirror_repositories.each do |mr| if mr.name.present? container << {:image => mr.name, :cpuLimit => mr.cpu_limit, :memoryLimit => "#{mr.memory_limit}M", :type => mr.try(:main_type) == "1" ? "main" : "sub"} end end return container.to_json end # 实训作品列表的提交状态 def list_work_status work, homework, member if work.work_status == 0 str = "未提交" else if work.compelete_status == 0 setting_time = homework_group_setting homework, member.try(:course_group_id) end_time = setting_time.end_time.present? ? setting_time.end_time : homework.end_time if end_time > Time.now || (homework.allow_late && !homework.course.is_end) str = "正在提交" else str = "延时提交" end else if work.work_status == 1 str = "按时提交" else str = "延时提交" end end end str end # 试卷、问卷提交状态 def ex_poll_work_status status str = "" case status when 0 str = "未提交" when 1 str = "按时提交" when 2 str = "延时提交" end str end #传入分数,获取对应颜色 def score_color score if score color = score >= 90 ? "color-red" : "color-green" else color = "color-grey" end color end # 获取两断时间的日期差 def time_between_days t1, t2 Date.parse(t1.to_s) - Date.parse(t2.to_s) if t1.present? && t2.present? end def update_valuate_time game_id, column record = EvaluateRecord.where(:game_id => game_id).first if record consume_time = format("%.2f", (Time.now.to_f - record.created_at.to_f)).to_f if column == "file_update" record.update_attributes!(:file_update => consume_time) elsif column == "pull" record.update_attributes!(:consume_time => consume_time) elsif column == "create_pod" record.update_attributes!(:create_pod => consume_time) elsif column == "pod_execute" record.update_attributes!(:pod_execute => consume_time) end end end # TPM查看权限 # result一般为页面权限 def shixun_view_allow shixun, result = nil if params[:openi].to_i == 1 result ? false : true else if User.current.manager_of_shixun?(shixun) result ? false : true else if shixun.status == 0 || (shixun.use_scope == 1 && !shixun.schools.map(&:name).include?(User.current.school_name)) result ? true : (render_403) end end end end # 判断TPM的代码是否被修改了 # 判断依据是看tpm的最新提交记录和tpi数据库中存储的commit_id是否一致 def repository_is_modified myshixun, shixun_gpid g = Gitlab.client myshixun_commit_id = myshixun.commit_id if myshixun_commit_id.blank? myshixun_commit_id = g.commits(myshixun.gpid).last.try(:id) myshixun.update_column(:commit_id, myshixun_commit_id) end shixun_commit_id = g.commits(shixun_gpid).first.try(:id) Rails.logger.warn("###############shixun_commit_id is #{shixun_commit_id}") Rails.logger.warn("###############myshixun_commit_id is #{myshixun.commit_id}") result = myshixun_commit_id != shixun_commit_id ? true :false return result end # 定义当前关卡是否有权开启下一关 # :实训若发布了,必须通过当前关卡才能查看下一关 # :未发布的实训,除了最后一关,其它的关卡都可以进入下一关 def show_next_stage?(game, shixun_status) if game.is_final_game? || ([2,3].include?(shixun_status.to_i) && game.try(:status) != 2) false else true end end # 适用与已经用url_safe编码后,回调字符串形式 def tran_base64_decode64 str if str.blank? str else s_size = str.size % 4 if s_size != 0 str += "=" * (4 - s_size) end Base64.decode64(str.tr("-_", "+/")).force_encoding("utf-8") end end def challenge_path path cha_path = path.present? ? path.split(";") : [] cha_path = cha_path.reject(&:blank?)[0].try(:strip) cha_path end def open_webssh # 如果我webssh类型, 开启webssh jenkins_shixuns = Redmine::Configuration['jenkins_shixuns'] uri = URI("#{jenkins_shixuns}/jenkins-exec/webssh/getConnectInfo") user_id = User.current.id params = {userID:user_id} res = uri_exec uri, params return [host, port, username, password] end # 中间层启动那种语言容器的类型 # language 语言 exec_path 需要编译的文件路径 def post_tomcat_language language, exec_path if language == "Html" && !exec_path.blank? case exec_path.split(".")[1].downcase when "c" "C" when "cpp" 'C++' when "py" 'Python2.7' else "Java" end elsif exec_path.blank? "Java" else language end end def only_publish_game shixun, type shixun_tomcat = Redmine::Configuration['shixun_tomcat'] gameInfo = shixun.gameInfo uri ="#{shixun_tomcat}/bridge/game/publishGame" params = {:gameInfo => "#{gameInfo}"} logger.info("%%%%%%%%%%%%params is #{params}") res = uri_exec uri, params if res && res['code'].to_i != 0 raise("实训云平台繁忙(繁忙等级:90)") end end def publish_game_and_tpimodify myshixun, type shixun_tomcat = Redmine::Configuration['shixun_tomcat'] git_myshixun_url = gitlab_url myshixun git_myshixun_url = Base64.urlsafe_encode64(git_myshixun_url) params = {tpiID: "#{myshixun.try(:id)}", :tpiGitURL => "#{git_myshixun_url}", :tpmID => "#{myshixun.shixun.try(:id)}"} uri ="#{shixun_tomcat}/bridge/game/resetTpiScript" params = {:gameInfo => "#{gameInfo}"} logger.info("%%%%%%%%%%%%params is #{params}") res = uri_exec uri, params if res && res['code'].to_i != 0 raise("实训云平台繁忙(繁忙等级:98)") end end ## 若实训关卡位置,关卡数等信息发生变化则需要修改脚本内容 def modify_shixun_script shixun, script if script.present? source_class_name = [] challenge_program_name = [] shixun.challenges.map(&:exec_path).each do |exec_path| challenge_program_name << "\"#{exec_path}\"" if shixun.mirror_name.try(:first) == "Java" if exec_path.nil? || exec_path.split("src/")[1].nil? source = "\"\"" else source = "\"#{exec_path.split("src/")[1].split(".java")[0]}\"" end source_class_name << source.gsub("/", ".") if source.present? elsif shixun.mirror_name.try(:first) == "C#" if exec_path.nil? || exec_path.split(".")[1].nil? source = "\"\"" else source = "\"#{exec_path.split(".")[0]}.exe\"" end source_class_name << source if source.present? end end script = if script.include?("sourceClassName") && script.include?("challengeProgramName") script.gsub(/challengeProgramNames=\(.*\)/,"challengeProgramNames=\(#{challenge_program_name.reject(&:blank?).join(" ")}\)").gsub(/sourceClassNames=\(.*\)/, "sourceClassNames=\(#{source_class_name.reject(&:blank?).join(" ")}\)") else script.gsub(/challengeProgramNames=\(.*\)/,"challengeProgramNames=\(#{challenge_program_name.reject(&:blank?).join(" ")}\)").gsub(/sourceClassNames=\(.*\)/, "sourceClassNames=\(#{challenge_program_name.reject(&:blank?).join(" ")}\)") end end return script #shixun.update_column(:evaluate_script, script) end # 若实训有更改,则修改已发不实训的标记为已更改 # shixun_modifies表中1表示已更改,进入myshixun需要强制重置,0表示没有修改 # type 0:表示已经是最新的了;1:表示已经有修改 # res返回结果0表示正确,-1表示有异常 def add_shixun_modify_status shixun, type shixun_tomcat = Redmine::Configuration['shixun_tomcat'] gameInfo = shixun.gameInfo uri ="#{shixun_tomcat}/bridge/game/publishGame" params = {:gameInfo => "#{gameInfo}"} logger.info("%%%%%%%%%%%%params is #{params}") res = uri_exec uri, params if res && res['code'].to_i != 0 raise("实训云平台繁忙(繁忙等级:90)") end end # 判断实训的路径、language是否更改,如果修改在TPI中需要重置脚本 # 目前为止,container为challenge和game类型 # 改工作必须在challenge或者game保存后执行 # type 1:表示既需要提示又需要更新脚本的,0:表示仅仅需要提示 def should_modify_myshixun_script shixun, type if type == 1 shixun.update_column(:reset_time, shixun.try(:updated_at)) else shixun.update_column(:modify_time, shixun.try(:updated_at)) end end def shixun_modify_status_publish shixun, type shixun_tomcat = Redmine::Configuration['shixun_tomcat'] # 更新测试集 gameInfo = shixun.gameInfo uri ="#{shixun_tomcat}/bridge/game/publishGame" # 更新脚本 tpiList =[] myshixuns = shixun.myshixuns if myshixuns.present? myshixuns.each do |myshixun| logger.info("tpiID is #{myshixun.id}") tpiID = myshixun.id instanceGitURL = gitlab_url myshixun logger.info("instanceGitURL is #{instanceGitURL}") tpiList << {:tpiID => tpiID, :instanceGitURL => instanceGitURL} logger.info("###############{tpiList.to_json unless tpiList.blank?}") end end tpiList = Base64.urlsafe_encode64(tpiList.to_json) unless tpiList.blank? params = {:gameInfo => "#{gameInfo}", :tpiList => "#{tpiList}" } logger.info("%%%%%%%%%%%%params is #{params}") # end res = uri_exec uri, params if res && res['code'].to_i != 0 raise("实训云平台繁忙(繁忙等级:90)") end end # 仅仅产生记录,用于已执行publish的方法 # ShixunModify中status 1:表示有更改,开启实训的时候需要重置,0:表示不需要重置或已重置完成 def shixun_modify_status_without_publish shixun, type myshixuns = shixun.myshixuns unless myshixuns.blank? myshixuns.each do |myshixun| shixun_modify = ShixunModify.where(:shixun_id => shixun.id, :myshixun_id => myshixun.id).first if shixun_modify.nil? ShixunModify.create!(:shixun_id => shixun.id, :myshixun_id => myshixun.id, :status => type) else shixun_modify.update_attributes!(:status => type) end end end end # 通关后,把最后一次成功的代码存到数据库 # type 0 创始内容, 1 最新内容 def game_passed_code game_id, path, myshixun_gpid, type g = Gitlab.client rev = rev.nil? ? "master" : rev path = path.strip if path.present? file_content = g.files(myshixun_gpid, path, rev).content if file_content.blank? # gitlab缺陷:forked完成,短暂时间内取不了内容的,所以做一个小轮询,间隔0.1秒 # 超过2秒则失败,需通过页面刷新 for i in 0..30 do sleep(0.1) file_content = g.files(myshixun_gpid, path, rev).content unless file_content.blank? break end end end unless file_content.present? raise("获取文件代码异常") end file_content = tran_base64_decode64(file_content) game_code = GameCode.where(:game_id => game_id, :path => path).first if game_code.nil? GameCode.create!(:game_id => game_id, :new_code => file_content, :path => path) else game_code.update_attributes!(:new_code => file_content) end end def game_code_init game_id, path game_code = GameCode.where(:game_id => game_id, :path => path).first GameCode.create(:game_id => game_id, :path => path) if game_code.blank? end # 判断用户是否认证 def check_authentication # return true # if params[:action] == "on_search" || params[:action] == "apply_trail" # 之所以这样处理是为了避开account页面ajax加载 # return true # end Rails.logger.info("check_authentication start") unless User.current.logged? url = request.original_url redirect_to signin_path(:back_url => url) return end =begin if User.current.created_on.strftime('%Y-%m-%d %H:%M:%S') > "2018-01-01 00:00:00" && User.current.phone.blank? redirect_to change_or_bind_path(:type => "phone") return end =end user_e = UserExtensions.where(:user_id => User.current.id).first if User.current.lastname.blank? || user_e.school_id.blank? || user_e.identity.blank? || User.current.mail.blank? redirect_to user_info_path() Rails.logger.info("check_authentication end") return elsif User.current.certification != 1 day_cer = UserDayCertification.where(:user_id => User.current.id).last unless (Time.now.to_i - day_cer.try(:created_at).to_i) < 86400 redirect_to my_account_path() Rails.logger.info("check_authentication end") return end end end def match_specific_symbol(str) str.gsub(" ", "").gsub(/\r\n$/, "").gsub("\r\n", "
").gsub(/\t/, "").html_safe end # textarea 以/r/n开头时,回车效果会被替换,因此先把\r转换成\r 再添加一个\r(直接添加\r不行) def match_specific_symbol1(str) str.gsub(/\A\r/, "\r\r") end # 积分表中建立记录行为,有过奖励则不重复奖励 def reward_grade(user, container_id, container_type, score) grade = Grade.where(:user_id => user.id, :container_id => container_id, :container_type => container_type).first if grade.nil? Grade.create!(:user_id => user.id, :container_id => container_id, :container_type => container_type, :score => score) user.update_column(:grade, (score.to_i + user.grade.to_i)) end end def reward_experience(user, container_id, container_type, score) experience = Experience.where(:user_id => user.id, :container_id => container_id, :container_type => container_type).first if experience.nil? Experience.create!(:user_id => user.id, :container_id => container_id, :container_type => container_type, :score => score) user.update_column(:experience, (score.to_i + user.experience.to_i)) end end def shixun_name game_id game = Game.where(:id => game_id).first game.nil? ? "---" : game.challenge.shixun.name end def grade_shixun_name shixun_id shixun = Shixun.where(:id => shixun_id).first shixun.nil? ? "---" : shixun.name end def game_position game_id game = Game.where(:id => game_id).first game.nil? ? "---" : game.challenge.position end def managements_navigation_bar_show menu_type, sub_type, grandchild_type={} case menu_type when 2 sub_type == 1 ? "课程列表" : (sub_type == 2? "课堂列表" : (sub_type == 3? "实训作业" : "项目列表")) when 3 case sub_type when 1 "实训列表" when 2 "实训配置列表" when 3 "已发布的实训" when 4 "已关闭的实训" when 5 "镜像管理" when 6 "学员实训列表" when 7 "镜像类别图片" when 8 "TPI实训列表" when 9 "TPI性能测试结果" end when 4 case sub_type when 1 "实训课程列表" when 2 "实训课程配置" when 3 "已发布实训课程" end when 5 case sub_type when 1 "竞赛列表" end when 6 if sub_type == 1 link_to('单位列表', departments_part_managements_path()) + "#{grandchild_type[:next_type] == 1 ? " > #{grandchild_type[:school].name}" : ""}" else "单位部门列表" end when 7 sub_type == 1 ? "用户列表" : (sub_type == 2 ? "试用授权列表" : "自动授权列表") when 8 sub_type == 1 ? "作业回复" : (sub_type == 2 ? "实训反馈" : (sub_type == 3 ? "讨论区" : "课堂讨论区") ) when 9 sub_type == 1 ? "实训留言列表" : "" when 10 sub_type == 1 ? "实名认证" : (sub_type == 2 ? "试用授权" : (sub_type == 3 ? "部门审批" : (sub_type == 4 ? "单位审批" : (sub_type == 5 ? "实训发布" : (sub_type == 6 ? "实训课程发布" : "职业认证") ) ) ) ) when 11 "工程认证+" when 12 sub_type == 1 ? "过关任务模板" : (sub_type == 2 ? "实训简介模板" : (sub_type == 3 ? "背景知识模板" : (sub_type == 4 ? "通用评测模板" : (sub_type == 5 ? "新课导语模板" : (sub_type == 6 ? "实训评分设置" : (sub_type == 7 ? "技术体系" : "升级通知") ) ) ) ) ) end end # codeMirror语言转换 def language_switch language case language when "Java" "text/x-java" when "C" "text/x-csrc" when "C++" "text/x-c++src" when "Python" "text/x-python" when "Ruby" "text/x-ruby" end end # 实训语言的种类 def shixun_language ["Java", "C", "C++", "Python2.7", "Python3.6", "MySQL/Java", "Html", "JFinal", "Docker", "Ethereum", "Dynamips", "MachineLearning", "Verilog","Spark","MySQL/Python3.6","PHP","PHP/Web","Hadoop", "Golang","Android","Matlab","Shell", "Git", 'Perl6', 'Kotlin', 'Elixir', 'JavaScript', 'Ruby'] end # 实训试用专业 def shixun_major_option content = [] content << ["选择实训适用的专业", 0] content << ["计算机科学与技术", 635] content << ["软件工程", 636] content << ["网络工程", 637] content << ["信息安全", 638] content << ["物联网工程", 639] content << ["信息工程", 622] content << ["通信工程", 619] end # 实训面向学员 def shixun_trainee content = [] content << ["初级学员", 1] content << ["中级学员", 2] content << ["高级学员", 3] content << ["顶级学员", 4] end # 班级设置排序中文 def switch_to_chinese word case word when "boards" result = "讨论区" when "news" result = "通知" when "homework" result = "作业" when "exercises" result = "试卷" when "poll" result = "问卷" when "statistics" result = "统计" when "attachment" result ="资源" end return result end def allow_to_view_challenge challenge, shixun # 判断对应关卡的game是否开启,如果开启则允许查看 game_count = Game.where(:challenge_id => challenge, :user_id => User.current, :status => [0,1,2]).count if game_count > 0 return true else return false end end # 已通过的关卡数 def had_passed_changllenge_count shixun, user myshixun = Myshixun.where(:shixun_id => shixun.id, :user_id => user.id).first if myshixun.nil? 0 elsif myshixun.games.select{|game| game.status == 2}.count == 0 -1 elsif myshixun.games.select{|game| game.status == 0}.count > 0 [myshixun.games.select{|game| game.status == 2}.count + 1] else myshixun.games.select{|game| game.status == 2}.count end end # 判断TPM已通过的管卡数 def had_passed_games_count shixun_id, user_id #Game.find_by_sql("select count(*) as unpass_count from games where games.status=2 and user_id=#{user_id} and games.challenge_id in (select id from challenges where shixun_id=#{shixun_id})").first.try(:unpass_count) Game.find_by_sql("SELECT count(*) cnt FROM `games` g join myshixuns m on m.id = g.myshixun_id where m.user_id = #{user_id} and m.shixun_id = #{shixun_id} and g.status = 2;").first.try(:cnt) end # 用户实训评测状态 def user_evaluate_status shixun, user myshixun = shixun.myshixuns.where(:user_id => user.id).first if myshixun.blank? "--" else game_id = myshixun.games.map(&:id) output = Output.where(:game_id => game_id).reorder("updated_at desc").first if output.blank? "--" else if output.try(:code) == -1 time_from_now(output.updated_at).to_s + "评测失败" else time_from_now(output.updated_at).to_s + "评测成功" end end end end def student_work_performance score case score when (90..100) '优秀' when (70...90) '良好' when (60...70) '及格' when (0...60) '不及格' end end # 已通过的关卡数 返回int类型(包含查看参考答案的) def had_passed_changllenge_num myshixun if myshixun.nil? 0 else myshixun.games.select{|game| game.status == 2}.count end end # 已通过的关卡数 返回int类型(未查看参考答案) def had_passed_no_ans_changllenge_num myshixun if myshixun.nil? 0 else myshixun.games.select{|game| game.status == 2 && game.final_score > 0}.count end end # TPI状态 :已通关、未通关、未开启 def my_shixun_status shixun, user status = "" myshixun = Myshixun.where(:shixun_id => shixun.id, :user_id => user.id).first if myshixun.nil? status = "未开启" else status = myshixun.is_complete? ? "已通关" : "未通关" end status end # 定义实训相关方法 def sum_final_score Game.find_by_sql("SELECT sum(final_score) as total_score FROM `games` where user_id=#{User.current.id}").first.try(:total_score) end # 获取某个myshixun的得分 def sum_myshixun_score myshixun_id Game.find_by_sql("SELECT sum(final_score) as total_score FROM `games` where myshixun_id=#{myshixun_id}").first.try(:total_score) end # myshixun 最高分 def top_score shixun, position Game.find_by_sql("SELECT max(final_score) as top_score FROM `games` g, `challenges` c where g.challenge_id = c.id and c.position=#{position} and g.myshixun_id in (SELECT id FROM `myshixuns` ms where ms.shixun_id=#{shixun.id})").first.try(:top_score) end # 实训平均分 def shixun_avg_score shixun, position Game.find_by_sql("SELECT avg(g.final_score) as avg_score FROM `games` g, `challenges` c where g.challenge_id=c.id and c.position=#{position} and g.myshixun_id in (SELECT id FROM `myshixuns` ms where ms.shixun_id=#{shixun.id})").first.try(:avg_score) end # 正在进行中任务 def shixun_running shixun, position Shixun.find_by_sql("SELECT count(*) as count FROM `myshixuns` ms, `games` g, `challenges` c where g.myshixun_id = ms.id and ms.shixun_id =#{shixun.id} and g.challenge_id=c.id and c.position=#{position} and g.status in ('0','1');").first.try(:count) end # 已完成任务 def shixun_done shixun, position Shixun.find_by_sql("SELECT count(*) as count FROM `myshixuns` ms, `games` g, `challenges` c where g.myshixun_id = ms.id and ms.shixun_id =#{shixun.id} and g.challenge_id=c.id and c.position=#{position} and g.status=2;").first.try(:count) end # 测评次数 def shixun_exec_total_count shixun, position Game.find_by_sql("SELECT * FROM `outputs` op, `games` g, `myshixuns` m where op.game_id = g.id and g.stage='#{position}' and m.parent_id = '#{shixun.id}';") end # 平均耗时 def game_avg_day created_at, updated_at time = (updated_at - created_at).to_i day = time / 86400 end # 平均耗时 def game_avg_hour created_at, updated_at time = (updated_at - created_at).to_i hour = time % (24*60*60) / (60*60) end # 平均耗时 def game_avg_min created_at, updated_at time = (updated_at - created_at).to_i min = time % (24*60*60) % (60*60) / 60 end # 耗时:天、小时、分、秒 # 小于1分钟则不显示 def game_spend_time time day = time / 86400 hour = time % (24*60*60) / (60*60) min = time % (24*60*60) % (60*60) / 60 sec = time % (24*60*60) % (60*60) % 60 if day < 1 if hour < 1 if min < 1 if sec < 1 time = "--" else time = "#{sec}秒" end else time = "#{min}分钟 #{sec}秒" end else time = "#{hour}小时 #{min}分钟 #{sec}秒" end else time = "#{day}天 #{hour}小时 #{min}分钟 #{sec}秒" end return time end # 耗时:天、小时、分 # 小于1分钟则不显示 def work_spend_time time if time == 0 time = "0小时" else day = time / 86400 hour = time % (24*60*60) / (60*60) min = (time % (24*60*60) % (60*60) / 60.0).ceil if day < 1 if hour < 1 if min < 1 time = "1分" else time = "#{min}分" end else time = "#{hour}小时#{min}分" end else time = "#{day}天#{hour}小时#{min}分" end end return time end # 耗时:小时、分、秒 00:00:00 # 小于1秒钟则不显示 def com_spend_time time hour = time / (60*60) min = time % (60*60) / 60 sec = time % (60*60) % 60 hour_str = "00" min_str = "00" sec_str = "00" if hour >= 1 && hour < 10 hour_str = "0#{hour}" elsif hour >= 10 hour_str = "#{hour}" end if min >= 1 && min < 10 min_str = "0#{min}" elsif min >= 10 min_str = "#{min}" end if sec >= 1 && sec < 10 sec_str = "0#{sec}" elsif sec >= 10 sec_str = "#{sec}" end time = "#{hour_str} : #{min_str} : #{sec_str}" return time end def consume_time time time.strftime('%Y/%m/%d %H:%M:%S') end def avg_spend_time shixun_id, position Game.find_by_sql("SELECT avg(g.end_time - g.open_time) as avg_time FROM `games` g, `challenges` c where c.id=g.challenge_id and g.status =2 and c.position = #{position} and g.myshixun_id in (SELECT id FROM `myshixuns` where shixun_id= #{shixun_id});").first.try(:avg_time).to_i end # 已闯关 def had_pass shixun_id, position Game.find_by_sql("SELECT count(*) as count FROM `games` g, `challenges` c where c.id=g.challenge_id and g.status =2 and c.position =#{position} and g.myshixun_id in (SELECT id FROM `myshixuns` where shixun_id=#{shixun_id});").first.try(:count) end # 单个game测评次数 def avg_my_pass game Output.where(:game_id => game).count end def shixun_final_score myshixun Game.find_by_sql("SELECT sum(final_score) as final_score FROM `games` where myshixun_id='#{myshixun.id}';").first.try(:final_score) end # def user_blogs_path(resource,parameters={}) # super # end # 复制一个任务 def publish_games challenge, myshixun_id, index game = Game.new game.attributes = challenge.attributes.dup.except("id","shixun_id","user_id","visits") game.myshixun_id = myshixun_id game.user_id = User.current.id game.stage = challenge.position index == 0 ? game.status = 0 : game.status = 3 challenge_samples = challenge.challenge_samples test_sets = challenge.test_sets if game.save unless challenge_samples.blank? challenge_samples.each do |cs| ChallengeSample.create(:game_id => game.id, :input => cs.input, :output => cs.output, :challenge_id => -1) end end unless test_sets.blank? test_sets.each do |ts| TestSet.create(:game_id => game.id, :input => ts.input, :output => ts.output, :challenge_id => -1) end end end end def git_repository_url project, type if type == "Shixun" rep_identify = Repository.where(:shixun_id => project.id, :type => "Repository::Gitlab").first.try(:identifier) elsif type == "Myshixun" rep_identify = Repository.where(:myshixun_id => project.id, :type => "Repository::Gitlab").first.try(:identifier) else rep_identify = Repository.where(:project_id => project.id, :type => "Repository::Gitlab").first.try(:identifier) end gitlab_address = Redmine::Configuration['gitlab_address'] gitUrl = gitlab_address.to_s+"/"+project.owner.to_s+"/"+ rep_identify + "."+"git" end def gitlab_url container g = Gitlab.client url = "#{Redmine::Configuration['gitlab_address_ip']}/#{g.project(container.try(:gpid)).try(:path_with_namespace)}.git" end def gitlab_address_url container g = Gitlab.client url = "#{Redmine::Configuration['gitlab_address']}/#{g.project(container.try(:gpid)).try(:path_with_namespace)}.git" end # paranet_gpid 为fork的源头 # u_gid 为当前用户在gitlab中对应的用户id def sync_gitlab_rep container, parent_gpid, u_gid Rails.logger.info("# sync_gitlab_rep # parent_gpid is #{parent_gpid}, u_gid is #{u_gid}") if container.class == Myshixun gshixun = Gitlab.client.fork(parent_gpid, u_gid) container.update_attribute(:gpid, gshixun.id) end return gshixun.try(:id) end # def git_shixun_url shixun, login # rep_identify = Repository.where(:shixun_id => shixun.id, :type => "Repository::Gitlab").first.try(:identifier) # gitlab_address = Redmine::Configuration['gitlab_address'] # gitUrl = gitlab_address.to_s+"/"+login+"/"+ rep_identify + "."+"git" # end # def git_shixun_url_ip shixun, login # rep_identify = Repository.where(:shixun_id => shixun.id, :type => "Repository::Gitlab").first.try(:identifier) # gitlab_address = Redmine::Configuration['gitlab_address_ip'] # gitUrl = gitlab_address.to_s+"/"+login+"/"+ rep_identify + "."+"git" # end # def git_myshixun_url_ip myshixun, user_id # g = Gitlab.client # login = User.where(:id => user_id).first.try(:login) # rep_identify = g.project(myshixun.gpid).try(:name) # gitlab_address = Redmine::Configuration['gitlab_address_ip'] # gitUrl = gitlab_address.to_s+"/"+login+"/"+ rep_identify + "."+"git" # end # myshixun git url by domain # def git_myshixun_url myshixun, user_id # g = Gitlab.client # login = User.where(:id => user_id).first.try(:login) # rep_identify = g.project(myshixun.gpid).try(:name) # gitlab_address = Redmine::Configuration['gitlab_address'] # gitUrl = gitlab_address.to_s+"/"+login+"/"+ rep_identify + "."+"git" # end def uri_exec uri, params begin Rails.logger.info("@parmas is #{params}, url is #{uri}") uri = URI.parse(URI.encode(uri.strip)) res = Net::HTTP.post_form(uri, params).body res = JSON.parse(res) rescue => e Rails.logger.error("failed to post data to brige! #{e}") raise("实训云平台繁忙(繁忙等级:84)") end end # type 为繁忙等级 # status-> 501:check检查版本库是否有代码异常 # status-> 502:实训评测异常;503实训版本库check异常 def interface_post uri, params, status begin uri = URI.parse(URI.encode(uri.strip)) res = Net::HTTP.post_form(uri, params).body res = JSON.parse(res) if (res && res['code'] != 0) raise(status) end res rescue Exception => e Rails.logger.error("post failed! #{e}") raise("实训云平台繁忙(繁忙等级:#{status})") end end def get_url_exec uri, options={} begin uri = URI.parse(URI.encode(uri.strip)) res = Net::HTTP.get_response(uri).body res = JSON.parse(res) rescue => e logger.error("get response failed ! #{e}") raise("实训云平台繁忙(繁忙等级:84)") end end def uri_json_exec uri, params Net::HTTP.start(uri.hostname, uri.port) {|http| http.post(uri.path, params.to_json) } http = Net::HTTP.new(uri.host, uri.port) res = Net::HTTP.post(uri, params.to_json).body res = JSON.parse(res) end def last_reply_time container_id message = Message.where(:root_id => container_id).order("created_on desc").first time = message.created_on return time end def judge_Chinese_num str cn_reg = /[\u4e00-\u9fa5]{1}/ cn_number = str.scan(cn_reg).size en_number = str.size - cn_number size = 1.9* cn_number + en_number end # homework_common状态 # 0:挂起;1:提交中;2:匿评中;3:评阅中 def new_homework_common_status status case status when 0 "未发布" when 1 "提交中" when 2 "补交中" when 3 "匿评中" when 4 "申诉中" when 5 "评阅中" when 6 "已结束" end end # 作业不同状态的不同样式 def homework_status_color status style = "" case status when '未发布' style = 'edu-filter-btn-no-late' when '提交中', '评阅中', '匿评中', '交叉评阅中' style = 'edu-filter-btn-orange' when '已开启补交' style = 'edu-filter-btn-green' when '已截止', '未开启补交' style = 'edu-filter-btn-red' when '已结束' style = 'edu-filter-btn-end' when '申诉中' style = 'edu-filter-btn-appeal' end end # 有分班权限的课堂 学生提交作品时发送的消息对象 def tiding_teachers course, member if course.teacher_course_groups.count > 0 member_ids = course.teacher_course_groups.where(:course_group_id => member.try(:course_group_id)).pluck(:member_id) teachers = course.teachers.where("members.id not in (#{course.teacher_course_groups.pluck(:member_id).size > 0 ? course.teacher_course_groups.pluck(:member_id).join(',') : -1}) or members.id in (#{member_ids.size > 0 ? member_ids.join(',') : -1})") else teachers = course.teachers end teachers end # 分班管理的老师所看到的成员数 def group_student_count course member = @course.members.where(:user_id => User.current.id).first if User.current.allowed_to?(:as_teacher, course) && member.present? && member.teacher_course_groups.count > 0 student_count = course.members.where(:course_group_id => member.teacher_course_groups.pluck(:course_group_id)).select{|member| member.roles.to_s.include?("Student")}.count else student_count = course.student.count end student_count end # 已提交作品 def late_commit_work_status work, homework if homework.allow_late link_to "补交附件", student_work_path(work, :is_focus => 1), :class => 'edu-filter-btn edu-activity-orange ml15 fl mt5', :title => "可追加作品修订附件" else "未开启补交".html_safe end end # 未提交作品 def un_commit_work_status project, homework if homework.allow_late if homework.homework_type == 3 && project.nil? && homework.homework_detail_group.base_on_project == 1 link_to "补交作品", "javascript:void(0)", :class => 'edu-filter-btn edu-activity-orange ml15 fl mt5', :style => "cursor:not-allowed", :title => '请先关联项目再补交作品' else link_to "补交作品", new_student_work_url_without_domain(homework.id), :class => 'edu-filter-btn edu-activity-orange ml15 fl mt5' end else "未开启补交".html_safe end end # 判断作业有多少人提交了 # def had_commit_studentwork_count homework_common member = homework_common.course.members.where(:user_id => User.current.id).first student_works = homework_common.student_works if member.present? && member.teacher_course_groups.count > 0 group_students = homework_common.course.members.where(:course_group_id => member.teacher_course_groups.pluck(:course_group_id)).map(&:user_id) student_works = student_works.where(:user_id => group_students) end student_works.where("work_status !=?", 0).count end # 实训作业的有效作品数 def effective_shixun_work_count homework_common count = 0 shixun = homework_common.shixuns if shixun homework_common.student_works.where("work_status !=?", 0).each do |work| myshixun = work.myshixun count = count + (myshixun && myshixun.games.select{|game| game.status == 2}.size > 0 ? 1 : 0) end end count end # 实训作业的通关作品数 def tongguan_shixun_work_count homework_common count = 0 shixun = homework_common.shixuns.first if shixun challenge_count = shixun.challenges.count homework_common.student_works.where("work_status !=?", 0).each do |work| myshixun = work.myshixun if myshixun && myshixun.games.select{|game| game.status == 2}.size == challenge_count count = count + 1 end end end count end # 未提交作品数统计 def had_uncommit_studentwork_count homework_common member = homework_common.course.members.where(:user_id => User.current.id).first student_works = homework_common.student_works if member.present? && member.teacher_course_groups.count > 0 group_students = homework_common.course.members.where(:course_group_id => member.teacher_course_groups.pluck(:course_group_id)).map(&:user_id) student_works = student_works.where(:user_id => group_students) end student_works.where("work_status =?", 0).count end # 未评阅 def had_unevaluate_count homework_common #count = StudentWorksScore.find_by_sql("SELECT count(distinct student_work_id) as count FROM student_works_scores sws, student_works sw, homework_commons hc where hc.id =#{homework_common.id} and sw.homework_common_id=hc.id and sw.is_delete = 0 and sws.student_work_id = sw.id and sws.user_id=#{User.current.id};").first.try(:count).to_i member = homework_common.course.members.where(:user_id => User.current.id).first student_works = homework_common.student_works if member.present? && member.teacher_course_groups.count > 0 group_students = homework_common.course.members.where(:course_group_id => member.teacher_course_groups.pluck(:course_group_id)).map(&:user_id) student_works = student_works.where(:user_id => group_students) end has_comment = StudentWorksScore.where(:student_work_id => student_works.map(&:id), :reviewer_role => [1, 2]).group_by(&:student_work_id).count student_count = student_works.count return student_count - has_comment end # 该阶段还有多长时间结束/距下一阶段还有多长时间 def homework_curr_time homework_common result = {} status = "" time = "" if homework_common.course.try(:is_end) status = "已结束" time = format_date homework_common.course.end_date else ho_detail_manual = homework_common.homework_detail_manual if ho_detail_manual case ho_detail_manual.comment_status when 0 status = "未发布" when 1 if homework_common.end_time && homework_common.end_time >= Time.now status = "提交中" time = how_much_time(homework_common.end_time) end when 3 if ho_detail_manual.evaluation_end && ho_detail_manual.evaluation_end > Time.now status = "匿评中" time = how_much_time(ho_detail_manual.evaluation_end) end when 4 if ho_detail_manual.appeal_time && ho_detail_manual.appeal_time > Time.now status = "申诉中" time = how_much_time(ho_detail_manual.appeal_time) end when 5 status = "评阅中" when 6 status = "评阅中" end end end result[:status] = status result[:time] = time result end # 试卷:该阶段还有多长时间结束/距下一阶段还有多长时间 def exercise_curr_time exercise result = {} status = "" time = "" case exercise.exercise_status when 1 status = "未发布" when 2 if exercise.end_time && exercise.end_time >= Time.now status = "提交中" time = how_much_time(exercise.end_time) end when 3 status = "已截止" time = format_time exercise.end_time end result[:status] = status result[:time] = time result end # 问卷:该阶段还有多长时间结束/距下一阶段还有多长时间 def poll_curr_time poll result = {} status = "" time = "" case poll.polls_status when 1 status = "未发布" when 2 if poll.end_time && poll.end_time >= Time.now status = "提交中" time = how_much_time(poll.end_time) end when 3 status = "已截止" time = format_time poll.end_time end result[:status] = status result[:time] = time result end # 公共分页 def paginator_list objs, objs_count, limit, is_remote @is_remote = is_remote @objs_count = objs.count @obj_pages = Paginator.new @objs_count, limit, params['page'] || 1 @offset ||= @obj_pages.offset @objs = paginateHelper @attachments,25 end # 判断当前用户能否对消息进行操作 def allow_to_show applied_message (User.current.id == applied_message.user_id && applied_message.status == 0) ? true : false end # 获取竞赛的管理人员 def contest_managers contest contest.contest_members.select{|cm| cm.roles.to_s.include?("ContestManager")} end # 获取竞赛的评委人员 def contest_judges contest contest.contest_members.select{|cm| cm.roles.to_s.include?("Judge")} end # 获取竞赛的参赛人员 def contest_contestants contest contest.contest_members.select{|cm| cm.roles.to_s.include?("Contestant")} end # 字符串加密 def aes_encrypt(key, encrypted_string) aes = OpenSSL::Cipher::Cipher.new("AES-128-ECB") aes.encrypt aes.key = key txt = aes.update(encrypted_string) << aes.final txt.unpack('H*')[0].upcase end # 字符串解密 def aes_dicrypt(key, dicrypted_string) aes = OpenSSL::Cipher::Cipher.new("AES-128-ECB") aes.decrypt aes.key = key aes.update([dicrypted_string].pack('H*')) << aes.final end # 获取多种类型的user用户名 def user_message_username user user.try(:show_name) end # 超出1w后用k+形式显示 def switch_integer_into_k number number > 10000 ? (number.to_f / 1000).round.to_s + "k" : number end # 判断某个课程是否包含仅对自己可见的作业 def course_has_score_open_common_homework course course.homework_commons.select{|hc| hc.score_open == 0}.count > 0 ? true : false end def welcome_course_message_count course_id board_id = Board.where(:course_id => course_id).first.try(:id) message_count = Message.where(:board_id => board_id).count return message_count end # 可以查看到资源库的资源 def welcome_course_file_count course course.attachments.count end # 超级管理员实训评分设置的横轴 def shixun_quality_show quality lower = quality.lower_limit upper = quality.upper_limit result = "#{quality.name}" if lower.present? && upper.present? result = if(lower > lower.round) "#{result}(#{lower.round}," else "#{result}[#{lower.round}," end result = if(upper >= upper.round) "#{result}#{upper.round}]" else "#{result}#{upper.round})" end end return result end # 管理员实训评分中 "指标"与"标准"的对应 def description_of_quality indicator, position indicator.score_quality_descriptions.where(:position => position).first.try(:name) if indicator.present? end # 获取目录下所有文件,返回一个文件名的数组 type是查看文件的类型image表示图片 # type [[1, "图片"], [2, "apk/exe"], [3, "txt"], [4, "html"]] def get_dir_filename path, type, game_id answer_picture = [] image = ["png", "jpg", "gif", "jpeg", "bmp", "pic"] if File.directory? path Dir.foreach(path) do |file| if file !="." and file !=".." extension = file.split(".")[1].try(:downcase) if image.include?(extension) && type == 1 answer_picture << file @type = "image" elsif extension == "html" && type == 4 answer_picture << file @type = "html" elsif extension == "txt" && type == 3 answer_picture << file @contents = "" f = File.open("#{path}/#{file}", "r") # ... process the file f.each_line do |line| if line.include?("Your score") game = Game.find(game_id) max_query_index = game.query_index - 1 a = line[11, line.length-1].try(:strip) outputs = game.outputs.where(:query_index => max_query_index) outputs.update_all(:text_scor => a) if outputs.present? end @contents += "#{line}" end f.close @type = "txt" end end end end return answer_picture end # 隐藏项目以外的信息 # return: true 显示,false 不显示 def hidden_unproject_infos hidden_info = Setting.find_by_name("hidden_non_project") (hidden_info && hidden_info.value == "1") ? true : false end # 获取当前用户的fork数量 def get_fork_from_project forked_from_project_id Project.find(forked_from_project_id) end # 判断当前用户是否已经fork过当前项目 # project: current_project def has_forked_cur_project project cur_user_projects = Project.where(:user_id => User.current.id) if cur_user_projects.count == 0 false else has_forked = cur_user_projects.select{|cur_user_project| cur_user_project.forked_from_project_id == project.id} has_forked.length > 0 ? true : false end end # 判断当前用户是否已经实训过当前项目 # project: current_project def has_exec_cur_shixun shixun Myshixun.where(:user_id => User.current.id, :shixun_id => shixun.id).count > 0 ? true : false end # 用户必须登录;必须创建了关卡;有实践任务的必须提交了版本库代码 def allow_shixun_exec shixun g = Gitlab.client result = User.current.logged? && shixun.challenges.count > 0 if shixun.challenges.where(:st => 0).count > 0 result = result && g.trees(shixun.gpid).count.to_i > 0 end result end # 判断当前用户是否可以开始实战 def link_to_shixun_exec myshixun, shixun, str is_modify = ShixunModify.where(:myshixun_id => myshixun.try(:id), :shixun_id => shixun.try(:id), :status => 1).first.blank? if User.current.mail.blank? link_to str, "javascript:void(0);", :onclick => "notice_box_redirect('#{security_settings_path}', '开启实训,请先绑定邮箱')", :class => "fr shixun-task-btn task-btn-orange mr15", :target => "_blank" else if is_modify || myshixun.blank? link_to str, shixun_exec_shixun_path(shixun), :class => "fr shixun-task-btn task-btn-orange mr15", :target => "_blank" else link_to str, "javascript:void(0);", :onclick => "sure_box_redirect('#{myshixun_reset_myshixun_path(myshixun)}', '实训已经更新啦,系统正在为您重置')", :class => "fr shixun-task-btn task-btn-orange mr15" end end end # 通过系统外部邮箱查找用户,如果用户不存在则用邮箱替换 def get_user_by_mail mail user = User.find_by_mail(mail) user.nil? ? User.find(2) : user end # 通过登录名查找用户,能查到返回用户姓名,否则返回登录名 def link_to_user_login login, css_class user = User.find_by_login(login) user = user.nil? ? login : user if user.is_a?(User) name = user.show_name link_to name, {:controller=> 'users', :action => 'show', id: user.id}, :class => css_class, :target => "_blank" else "#{h(user.to_s)}".html_safe end end def link_to_user_mail(mail, css_class) user = User.find_by_mail(mail) user = user.nil? ? mail : user if user.is_a?(User) name = user.show_name link_to name, {:controller=> 'users', :action => 'show', id: user.id}, :class => css_class, :target => "_blank" else "#{h(user.to_s)}".html_safe end end # 通过系统外部用户名查找用户,如果用户不存在则用邮箱替换 def get_user_by_login_and login user = User.find_by_login(login) (user.nil? || login == "root") ? User.find(2) : user end # 登录名来自外部系统 # 通过登录名查找用户,如果用户存在则显示用户姓名,否则显示登录名 def get_user_by_login login user = User.find_by_login(login) user.nil? ? login : user.show_name end # 重置user_path,目的是将id转换成用户名 def user_path(resource, parameters = {}) if Fixnum === resource resource = User.find(resource) end super end # 重置user_path,目的是将id转换成用户名 # def shixun_path(resource, parameters = {}) # if Fixnum === resource # resource = Shixun.find(resource) # end # super # end # 历史数据(老版本库数据)处理完则可以修改该放放 def get_rep_identifier_by_project project identifier = Repository.where(:project_id => project.id, :type => "Repository::Gitlab").first.try(:identifier) result = identifier.nil? ? Repository.where(:project_id => project.id).first.try(:identifier) : identifier result end # 项目版本库导出Excel功能 def export_rep_xls(gpid, options = {}) g = Gitlab.client cycle = params[:cycle] rev = params[:rev] if cycle == "week" statics = g.rep_stats_week(gpid, :rev => rev) elsif cycle == "month" statics = g.rep_stats_month(gpid, :rev => rev) end xls_report = StringIO.new book = Spreadsheet::Workbook.new sheet1 = book.create_worksheet :name => l(:project_module_repository) blue = Spreadsheet::Format.new :color => :blue, :weight => :bold, :size => 10 sheet1.row(0).default_format = blue sheet1.row(0).concat([l(:rep_branch),l(:rep_author),l(:rep_changeset),l(:rep_code_add),l(:rep_code_delete),l(:rep_code_modified),l(:rep_sode_time),l(:rep_sode_cycle),l(:rep_author_mail)]) count_row = 1 statics.each do |static| user = User.where(:mail => static.email).first sheet1[count_row,0] = rev sheet1[count_row,1] = user.nil? ? static.uname : user.show_name sheet1[count_row,2] = static.commits_num sheet1[count_row,3] = static.add sheet1[count_row,4] = static.del sheet1[count_row,5] = static.changes sheet1[count_row,6] = Time.now.strftime('%Y-%m-%d %H:%M:%S') sheet1[count_row,7] = cycle == "week" ? "最近1周" : "最近一月" sheet1[count_row,8] = static.email count_row += 1 end book.write xls_report xls_report.string end # 项目issue列表导出Excel功能 def issue_list_xls issues xls_report = StringIO.new book = Spreadsheet::Workbook.new sheet1 = book.create_worksheet :name => "issues" blue = Spreadsheet::Format.new :color => :blue, :weight => :bold, :size => 10 sheet1.row(0).default_format = blue sheet1.row(0).concat([l(:issue_xls_id),l(:issue_xls_tracker_id),l(:issue_xls_title),l(:issue_xls_description),l(:issue_xls_status),l(:issue_xls_assign),l(:issue_xls_priority),l(:issue_xls_author),l(:issue_xls_created_at),l(:milestone),l(:issue_xls_start),l(:issue_xls_due),l(:issue_xls_ratio)]) count_row = 1 issues.each do |issue| sheet1[count_row,0] = issue.id sheet1[count_row,1] = issue_tracker_change(issue.tracker_id) sheet1[count_row,2] = issue.subject sheet1[count_row,3] = (issue.description.gsub(/<\/?.*?>/,"")).html_safe sheet1[count_row,4] = issue_status_change(issue.status_id) sheet1[count_row,5] = issue.assigned_to.try(:show_name) sheet1[count_row,6] = issue_priority_change(issue.priority_id) sheet1[count_row,7] = issue.author.show_name sheet1[count_row,8] = issue.created_on.nil? ? issue.created_on : issue.created_on.strftime('%Y-%m-%d %H:%M:%S') sheet1[count_row,9] = issue.fixed_version.try(:name) sheet1[count_row,10] = issue.start_date.nil? ? issue.start_date : issue.start_date.strftime('%Y-%m-%d') sheet1[count_row,11] = issue.due_date.nil? ? issue.due_date : issue.due_date.strftime('%Y-%m-%d') sheet1[count_row,12] = issue_ratio_change(issue.done_ratio, issue.status_id) count_row += 1 end book.write xls_report xls_report.string end # 用户资料是否完善 def user_data_complete user user_extension = UserExtensions.where(:user_id => user.id).first data = true if user_extension.gender.nil? || user_extension.school_id.nil? || user.lastname.blank? || (user_extension.identity == 3 && user_extension.school_id.nil?) data = false end return data end # 获取用户单位 # 优先获取高校信息,如果改信息不存在则获取occupation def get_occupation_from_user user School.where("id=?",user.user_extensions.school_id).first.try(:name).nil? ? user.user_extensions.try(:occupation) : School.where("id=?",user.user_extensions.school_id).first.try(:name) end def update_visiti_count container container.update_column(:visits, container.visits + 1) end def if_hidden_subdomain field domains = field.sub_domains.select{|domain| domain.hide.to_i == 0} result = domains.length > 0 ? true : false return result end # 判断某个资源是否可以申请 def attach_show_allow attach_id attachment = Attachment.find(attach_id) case attachment.container_type when "Project" User.current.member_of?(attachment.container) ? true : false when "Course" User.current.member_of_course?(attachment.container) ? true : false when "OrgSubfield" User.current.member_of_org?(attachment.container.organization) ? true : false when "Principal" User.current.id == attachment.author_id ? true : false end end # 判断某个私有资源是否可以发送下载权限 # 结果为true不能下载,false可以下载 def private_attachment_allow attachment_id attach = Attachment.find(attachment_id) # 条件取否,result结果为true则不能下载 result = attach.is_public == 0 && attach.author != User.current && !attach.get_apply_resource_status(attach.id, User.current.id) && !attach_show_allow(attach) end # Time 2015-03-24 15:27:29 # Author lizanle # Description 从硬盘上删除对应的资源文件 def delete_kindeditor_assets_from_disk owner_id,owner_type assets = Kindeditor::Asset.where(["owner_id = ? and owner_type = ?",owner_id,owner_type]) if !assets.nil? && !assets.blank? assets.all.each do |asset| next if asset.nil? filepath = File.join(Rails.root,"public","files","uploads", asset[:created_at].to_s.gsub("+0800","").to_datetime.strftime("%Y%m").to_s, asset[:asset].to_s) File.delete(filepath) if File.exist?filepath end end end def link_to_user_version(version, options = {}) return '' unless version && version.is_a?(Version) link_to_if version.visible?, format_version_name(version), { :controller => 'versions', :action => 'show', :id => version }, :class => "linkBlue" end # 判断课程是否为精品课程 def is_excellent_course course (course.is_excellent? or course.excellent_option?) ? true : false end # 判断课程对成员是否可见 def visible_course?(course) (course.is_delete? or (!course.is_public? && !User.current.member_of_course?(course))) ? false : true end # 获取项目/课程总分 # 发布缺陷 4分 回复缺陷 1分 提交一次 4分 讨论帖子 2分 回复帖子 1分 发布新闻 1分 def static_project_score obj score = obj.issue_num * 4 + obj.issue_journal_num + (obj.changeset_num||0) * 4 + obj.board_num * 2 + obj.board_message_num + obj.attach_num * 5 end # 获取组织成员中文名字 def get_org_member_role_name member unless member.roles[0].nil? case member.roles[0].name when 'orgManager' '管理人员' when 'orgMember' '组织成员' end end end # 判断组织左侧展开或者隐藏 def is_hide_org_left obj if obj.nil? return true else if obj.hide == 0 return true else return false end end end # Time 2015-03-24 16:38:05 # Author lizanle # Description after save后需要进行资源记录的更新 # owner_type = 1 对应的是 memo # owner_type = 2 对应的是forum # owner_type = 3 对应的是message # owner_type = 4 对应的是news # owner_type = 5 对应的是comment def update_kindeditor_assets_owner ids,owner_id,owner_type ids.each do |id| asset = Kindeditor::Asset.find(id.to_i) asset.owner_id = owner_id asset.owner_type = owner_type asset.save end end # 更新课程活跃度得分 def course_member_score(course_id,user_id,type) course_contributor_score = CourseContributorScore.where("course_id =? and user_id =?", course_id, user_id).first case type when "HomeworkCommon" if course_contributor_score.nil? CourseContributorScore.create(:course_id => course_id, :user_id => user_id, :homework_journal_num => 1) else score = course_contributor_score.homework_journal_num.to_i + 1 course_contributor_score.update_column(:homework_journal_num, score) end # 课程留言 when "Course" if course_contributor_score.nil? CourseContributorScore.create(:course_id => course_id, :user_id => user_id, :journal_num => 1) else score = course_contributor_score.journal_num.to_i + 1 course_contributor_score.update_column(:journal_num, score) end when "Message" if course_contributor_score.nil? CourseContributorScore.create(:course_id => course_id, :user_id => user_id, :message_num => 1) else score = course_contributor_score.message_num.to_i + 1 course_contributor_score.update_column(:message_num, score) end when "MessageReply" if course_contributor_score.nil? CourseContributorScore.create(:course_id => course_id, :user_id => user_id, :message_reply_num => 1) else score = course_contributor_score.message_reply_num.to_i + 1 course_contributor_score.update_column(:message_reply_num, score) end when "NewReply" if course_contributor_score.nil? CourseContributorScore.create(:course_id => course_id, :user_id => user_id, :news_reply_num => 1) else score = course_contributor_score.news_reply_num.to_i + 1 course_contributor_score.update_column(:news_reply_num, score) end when "News" if course_contributor_score.nil? CourseContributorScore.create(:course_id => course_id, :user_id => user_id, :news_num => 1) else score = course_contributor_score.news_num.to_i + 1 course_contributor_score.update_column(:news_num, score) end when "Attachment" if course_contributor_score.nil? CourseContributorScore.create(:course_id => course_id, :user_id => user_id, :resource_num => 1) else score = course_contributor_score.resource_num.to_i + 1 course_contributor_score.update_column(:resource_num, score) end end end # 删除某条记录相应减少课程统计数 def down_course_score_num (course_id,user_id,type) course_contributor_score = CourseContributorScore.where("course_id =? and user_id =?", course_id, user_id).first case type when "HomeworkCommon" unless course_contributor_score.nil? score = course_contributor_score.homework_journal_num.to_i - 1 course_contributor_score.update_column(:homework_journal_num, score < 0 ? 0 : score) end # 课程留言 when "Course" unless course_contributor_score.nil? score = course_contributor_score.journal_num.to_i - 1 course_contributor_score.update_column(:journal_num, score < 0 ? 0 : score) end when "Message" unless course_contributor_score.nil? score = course_contributor_score.message_num.to_i - 1 course_contributor_score.update_column(:message_num, score < 0 ? 0 : score) end when "MessageReply" unless course_contributor_score.nil? score = course_contributor_score.message_reply_num.to_i - 1 course_contributor_score.update_column(:message_reply_num, score < 0 ? 0 : score) end when "NewReply" unless course_contributor_score.nil? score = course_contributor_score.news_reply_num.to_i - 1 course_contributor_score.update_column(:news_reply_num, score < 0 ? 0 : score) end when "News" unless course_contributor_score.nil? score = course_contributor_score.news_num.to_i - 1 course_contributor_score.update_column(:news_num, score < 0 ? 0 : score) end when "Attachment" unless course_contributor_score.nil? score = course_contributor_score.resource_num.to_i - 1 course_contributor_score.update_column(:resource_num, score < 0 ? 0 : score) end end end # Added by young # Define the course menu's link class # 不是数组的转化成数组,然后判断当前menu_item是否在给定的列表 # REVIEW: 目测menu的机制,貌似不是很需要转换,再说 def link_class(label) labels = label.is_a?(Array) ? label : ([] << label) #a = current_menu_item labels.include?(current_menu_item) ? 'selected' : '' end #Ended by young # Return true if user is authorized for controller/action, otherwise false def authorize_for(controller, action) User.current.allowed_to?({:controller => controller, :action => action}, @project) end # add by nwb def authorize_for_course(controller, action) User.current.allowed_to?({:controller => controller, :action => action}, @course) end def authorize_for_contest(controller, action) User.current.allowed_to?({:controller => controller, :action => action}, @contest) end # Display a link if user is authorized # # @param [String] name Anchor text (passed to link_to) # @param [Hash] options Hash params. This will checked by authorize_for to see if the user is authorized # @param [optional, Hash] html_options Options passed to link_to # @param [optional, Hash] parameters_for_method_reference Extra parameters for link_to def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference) 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_course(name, options = {}, html_options = nil, *parameters_for_method_reference) link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for_course(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) if canShowRealName name = h(user.realname(options[:format])) else name = h(user.name(options[:format])) end #if user.active? || (User.current.admin? && user.logged?) # link_to name, {:controller=> 'users', :action => 'show', id: user.id, host: Setting.host_user}, :class => user.css_classes #else # name #end link_to name, {:controller=> 'users', :action => 'show', id: user.id, host: Setting.host_user}, :class => user.css_classes else h(user.to_s) end end def link_to_isuue_user(user, options={}) if user.is_a?(User) if options[:format] name = h(user.name(options[:format])) else name = h(user.show_name) end link_to name, {:controller=> 'users', :action => 'show', id: user.id, host: Setting.host_user}, :class => "pro_info_p" else h(user.to_s) end end def link_to_settings_user(user, options={}) if user.is_a?(User) name = h(user.name(options[:format])) link_to name, {:controller=> 'users', :action => 'show', id: user.id, host: Setting.host_user}, :class => "w90 c_orange fl" else h(user.to_s) end end #重载上面方法,增加样式显示 def link_to_user_header user,canShowRealName=false,options={} if user.is_a?(User) if canShowRealName name = user.show_name name = user.login if name == "" else name = user.login end link_to name, {:controller=> 'users', :action => 'show', id: user.id, host: Setting.host_user}, :class => options[:class] else h(user.to_s) end end # Displays a link to +issue+ with its subject. # Examples: # # link_to_issue(issue) # => Defect #6: This is the subject # link_to_issue(issue, :truncate => 6) # => Defect #6: This i... # link_to_issue(issue, :subject => false) # => Defect #6 # link_to_issue(issue, :project => true) # => Foo - Defect #6 # link_to_issue(issue, :subject => false, :tracker => false) # => #6 # def link_to_issue(issue, options={}) title = nil subject = nil text = options[:tracker] == false ? "##{issue.id}" : "#{issue.tracker} ##{issue.id}" if options[:subject] == false title = truncate(issue.subject, :length => 60) else subject = issue.subject if options[:truncate] subject = truncate(subject, :length => options[:truncate]) end end s = link_to text, issue_path(issue), :class => issue.css_classes, :title => title s << h(": #{subject}") if subject s = h("#{issue.project} - ") + s if options[:project] s end def link_to_issue_version(issue, options={}) title = nil subject = nil text = options[:tracker] == false ? "##{issue.id}" : "#{issue.tracker} ##{issue.id}" if options[:subject] == false title = truncate(issue.subject, :length => 60) else subject = issue.subject if options[:truncate] subject = truncate(subject, :length => 60) end end # status_id:3、已解决 5、已关闭 if issue.status_id == 3 s = link_to text, issue_path(issue), :class => "text_line_s fl", :title => title elsif issue.status_id == 5 s = link_to text, issue_path(issue), :class => "text_line_s del_line fl", :title => title else s = link_to text, issue_path(issue), :class => "c_blue fl", :title => title end s << h("".html_safe) if subject s = h("#{issue.project} - ") + s if options[:project] s end # Generates a link to an attachment. # Options: # * :text - Link text (default to attachment filename) # * :download - Force download (default: false) def link_to_short_attachment(attachment, options={}) length = options[:length] ? options[:length]:23 text = h(truncate(options.delete(:text) || attachment.filename, length: length, omission: '...')) route_method = options.delete(:download) ? :download_named_attachment_url_without_domain : :named_attachment_url_without_domain html_options = options.slice!(:only_path) url = send(route_method, attachment, attachment.filename, options) link_to text, url, html_options end # Generates a link to an attachment. # Options: # * :text - Link text (default to attachment filename) # * :download - Force download (default: false) def link_to_attachment(attachment, options={}) token = options[:token] if options[:token] text = options.delete(:text) || attachment.filename route_method = options.delete(:download) ? :download_named_attachment_path : :named_attachment_path html_options = options.slice!(:only_path) url = send(route_method, attachment, attachment.filename, options) url << "?token=#{token}" unless token.nil? link_to text, url, html_options end def link_to_attachment_img(attachment, options={}) text = options.delete(:text) || attachment.filename route_method = options.delete(:download) ? :download_named_attachment_path : :named_attachment_path html_options = options.slice!(:only_path) url = send(route_method, attachment, attachment.filename, options) image_tag url, html_options end # Generates a link to a SCM revision # Options: # * :text - Link text (default to the formatted revision) def link_to_revision(revision, repository, options={}) if repository.is_a?(Project) repository = repository.repository end text = options.delete(:text) || format_revision(revision) rev = revision.respond_to?(:identifier) ? revision.identifier : revision link_to( h(text), {:controller => 'repositories', :action => 'revision', :id => repository.project, :repository_id => repository.identifier_param, :rev => rev}, :title => l(:label_revision_id, format_revision(revision)) ) end # Generates a link to a message def link_to_message(message, options={}, html_options = nil) link_to( truncate(message.subject, :length => 60), board_message_path(message.board_id, message.parent_id || message.id, { :r => (message.parent_id && message.id), :anchor => (message.parent_id ? "message-#{message.id}" : nil) }.merge(options)), html_options ) end # Generates a link to a project if active # Examples: # # link_to_project(project) # => link to the specified project overview # link_to_project(project, {:only_path => false}, :class => "project") # => 3rd arg adds html options # link_to_project(project, {}, :class => "project") # => html options with default url (project overview) # def link_to_project(project, options={}, html_options = nil) if project.archived? h(project.name) elsif options.key?(:action) ActiveSupport::Deprecation.warn "#link_to_project with :action option is deprecated and will be removed in Redmine 3.0." url = {:controller => 'projects', :action => 'show', :id => project}.merge(options) link_to project.name, url, html_options else link_to project.name, project_path(project, options), html_options end end def link_to_course(course, options={}, html_options = nil) if course.archived? h(course.name) elsif options.key?(:action) ActiveSupport::Deprecation.warn "#link_to_course with :action option is deprecated and will be removed in Redmine 3.0." url = {:controller => 'courses', :action => 'show', :id => project}.merge(options) link_to course.name, url, html_options else link_to course.name, course_path(course, options), html_options end end # Generates a link to a project settings if active def link_to_project_settings(project, options={}, html_options=nil) if project.active? link_to project.name, settings_project_path(project, options), html_options elsif project.archived? h(project.name) else link_to project.name, project_path(project, options), html_options end end def wiki_page_path(page, options={}) url_for({:controller => 'wiki', :action => 'show', :project_id => page.project, :id => page.title}.merge(options)) end def thumbnail_tag(attachment) link_to image_tag(thumbnail_path(attachment)), named_attachment_path(attachment, attachment.filename), :title => attachment.filename end def thumbnail_issue_tag(attachment) imagesize = attachment.thumbnail(:size => "200*200") imagepath = named_attachment_path(attachment, attachment.filename) if imagesize link_to image_tag(thumbnail_path(attachment), height: '73', width: '100', class: 'issue_attachment_picture'), imagepath, :title => attachment.filename else link_to image_tag(imagepath , height: '73', width: '100', class: 'issue_attachment_picture'), imagepath, :title => attachment.filename end end def thumbnail_challenge_tag(attachment) imagepath = named_attachment_path(attachment, attachment.filename) image_tag(imagepath) end # 图片缩略图链接 def thumbnail_small_tag(attachment) imagesize = attachment.thumbnail(:size => "200*200") imagepath = named_attachment_path(attachment, attachment.filename) if imagesize link_to image_tag(imagesize), imagepath, :title => attachment.filename else link_to image_tag(imagepath , height: '200', width: '250'), imagepath, :title => attachment.filename end end def toggle_link(name, id, options={}) onclick = "$('##{id}').slideToggle(); " onclick << (options[:focus] ? "$('##{options[:focus]}').focus(); " : "this.blur(); ") onclick << "return false;" link_to(name, "javascript:void(0)", :onclick => onclick,:class => options[:class]) end def image_to_function(name, function, html_options = {}) html_options.symbolize_keys! tag(:input, html_options.merge({ :type => "image", :src => image_path(name), :onclick => (html_options[:onclick] ? "#{html_options[:onclick]}; " : "") + "#{function};" })) end def format_activity_title(text) h(truncate_single_line(text, :length => 100)) end def format_activity_day(date) date == User.current.today ? l(:label_today).titleize : format_date(date) end def format_activity_description(text) h(truncate(text.to_s, :length => 120).gsub(%r{[\r\n]*<(pre|code)>.*$}m, '...')).gsub(/[\r\n]+/, "
").html_safe #h(truncate(text.to_s, :length => 120).gsub(/<\/?.*?>/,"")).html_safe end def format_version_name(version) if version.project == @project h(truncate(version.name,:length=>20)) else h("#{version.project} - #{truncate(version.name,:length=>20)}") end end def due_date_distance_in_words(date) if date l((date < Date.today ? :label_roadmap_overdue : :label_roadmap_due_in), distance_of_date_in_words(Date.today, date)) end end # Renders a tree of projects as a nested set of unordered lists # The given collection may be a subset of the whole project tree # (eg. some intermediate nodes are private and can not be seen) #Modified by nie. def render_project_nested_lists(projects) s = '' if projects.any? ancestors = [] original_project = @project #modified by nie projects.each do |project| # set the project environment to please macros. @project = project if (ancestors.empty? || project.is_descendant_of?(ancestors.last)) # s << "\n" * ancestors.size) @project = original_project end s.html_safe end def render_course_nested_lists(courses) s = '' if courses.any? ancestors = [] original_course = @course #modified by nie courses.each do |course| # set the project environment to please macros. @course = course if (ancestors.empty? )#|| course.is_descendant_of?(ancestors.last)) s << "\n" end end classes = (ancestors.empty? ? 'root' : 'child') s << "
  • " s << (render :partial => 'courses/course', :locals => {:course => course}).to_s s << "
    \n" ancestors << course end s << ("
  • \n" * ancestors.size) @course = original_course end s.html_safe end #added by young def render_project_nested_lists_new(projects) s = '' if projects.any? ancestors = [] original_project = @project projects.sort_by(&:lft).each do |project| # set the project environment to please macros. @project = project if (ancestors.empty? || project.is_descendant_of?(ancestors.last)) # s << "\n" * ancestors.size) @project = original_project end s.html_safe end #end def render_page_hierarchy(pages, node=nil, options={}) content = '' if pages[node] content << "\n" end content.html_safe end # Renders flash messages def render_flash_messages s = '' flash.each do |k,v| s << content_tag('div', v.html_safe, :class => "alert alert-orange mb15 mt15", :id => "flash_#{k}") end s.html_safe end # Renders tabs and their content def render_tabs(tabs) if tabs.any? render :partial => 'common/tabs', :locals => {:tabs => tabs} else content_tag 'p', l(:label_no_data), :class => "nodata" end end def render_project_settings_tabs(tabs) if tabs.any? render :partial => 'common/project_tab', :locals => {:tabs => tabs} else content_tag 'p', l(:label_no_data), :class => "nodata" end end # Renders the project quick-jump box def render_project_jump_box return unless User.current.logged? projects = User.current.memberships.collect(&:project).compact.select(&:active?).uniq if projects.any? options = ("" + '').html_safe options << project_tree_options_for_select(projects, :selected => @project) do |p| { :value => project_path(:id => p, :jump => current_menu_item) } end select_tag('project_quick_jump_box', options, :onchange => 'if (this.value != \'\') { window.location = this.value; }') end end def project_tree_options_for_select(projects, options = {}) s = '' project_tree(projects) do |project, level| name_prefix = (level > 0 ? ' ' * 2 * level + '» ' : '').html_safe tag_options = {:value => project.id} tag_options[:title] = project.name if project == options[:selected] || (options[:selected].respond_to?(:include?) && options[:selected].include?(project)) tag_options[:selected] = 'selected' else tag_options[:selected] = nil end tag_options.merge!(yield(project)) if block_given? s << content_tag('option', name_prefix + h(project), tag_options) end s.html_safe end # Yields the given block for each project with its level in the tree # # Wrapper for Project#project_tree def project_tree(projects, &block) Project.project_tree(projects, &block) end # 项目版本库可见权限判断: # modules中设置可见 # 版本库存在 # 版本库设置了隐藏则仅仅项目成员或超级管理员可见(hidden_repo:1 隐藏版本库) # return -> true 可见 def visible_repository?(project) repository = Repository.where(:project_id => project.id, :type => "Repository::Gitlab").first if project.enabled_modules.where("name = 'repository'").empty? || repository.nil? result = false else result = (project.hidden_repo && !User.current.admin && !User.current.member_of?(project)) ? false : true end end # 判断成员在项目中的角色 member_role == Reporter/Manager/Developer 报告人员/管理人员/报告人员; def role_of_members_in_project(project, user_id) member = Member.where(:project_id => project, :user_id => user_id) unless member.blank? member_role = member.first.roles[0].to_s end return member_role end # 判断用户是不是项目成员 def is_project_member?(user_id, project_id) @result = false mem = Member.where("user_id = ? and project_id = ?",user_id, project_id) unless mem.blank? @result = true end return @result end # 更新各类消息为已读 def update_messsages_to_viewed(message_type, forge_message_id) if(message_type == "CourseMessage") query = CourseMessage.where(:course_message_type => ["JoinCourse", "RemoveFromCourse"], :user_id => User.current, :course_id => forge_message_id, :viewed => false) elsif(message_type == "ForgeMessage") query = ForgeMessage.where(:forge_message_type => ["ProjectInvite", "JoinProject", "RemoveFromProject"], :user_id => User.current, :project_id => forge_message_id, :viewed => false) elsif(message_type == "ContestMessage") query = ContestMessage.where(:contest_message_type => ["ContestRequestDealResult", "JoinContest", "RemoveFromContest"], :user_id => User.current, :contest_id => forge_message_id, :viewed => false) elsif(message_type == "BlogMessage") query = BlogMessage.where(:blog_message_type => "BlogComment", :user_id => User.current, :blog_id => forge_message_id, :viewed => false) end query.update_all(:viewed => true) unless query.blank? end def show_attachment_tip container_id, container_type atts = Attachment.where(:container_id => container_id, :container_type => container_type, :is_public => 0) atts.count > 0 ? true :false end # 必须是项目成员,项目必须提交过代码 def allow_pull_request project return 0 if project.gpid.nil? g = Gitlab.client # 之所以这样比较是为了解决gitlab本身的bug commit_count = g.project(project.gpid).try(:commit_count).to_i git_commit_cout = g.user_static(project.gpid, :rev => "master").count count = commit_count > git_commit_cout ? commit_count : git_commit_cout count end # 判断版本库是否初始为gitlab def rep_is_gitlab?(project) rep = project.repositories.where("type =?", "Repository::Gitlab") return rep.blank? ? true :false end # 获取Gitlab版本库提交总数 def commit_count(project, branch) g = Gitlab.client #add by hx if g.commits(project.gpid, :ref_name => @rev , :page=>200).count > 0 count = 4020 elsif g.commits(project.gpid , :page=>25, :ref_name => branch).count==0 count = count_commits(project.gpid , 0 , 25) elsif g.commits(project.gpid , :page=>50, :ref_name => branch).count ==0 count = count_commits(project.gpid , 25 , 50)+ 25 * 20 elsif g.commits(project.gpid , :page=>75, :ref_name => branch).count ==0 count = count_commits(project.gpid , 50 , 75)+ 50 * 20 elsif g.commits(project.gpid , :page=>100, :ref_name => branch).count== 0 count = count_commits(project.gpid , 75 , 100) + 75 * 20 elsif g.commits(project.gpid , :page=>125, :ref_name => branch).count==0 count = count_commits(project.gpid , 100 , 125) + 100 * 20 elsif g.commits(project.gpid , :page=>150, :ref_name => branch).count==0 count = count_commits(project.gpid , 125 , 150) + 125 * 20 else count = count_commits(project.gpid , 150 ,200) + 150 * 20 end end #add by hx def count_commits(project_id , left , right) count = 0 (left..right).each do |page| if $g.commits(project_id,:page => page).count == 0 break else count = count + $g.commits(project_id, :ref_name => @rev, :page => page).count end end return count end # 获取单一gitlab项目 def gitlab_repository(project) rep = Repository.where("project_id =? and type =?", project.id,"Repository::Gitlab" ).first end # 获取单一gitlab项目 def shixun_repository(shixun) rep = Repository.where(:shixun_id => shixun, :type => "Repository::Gitlab" ).first end # 判断当前用户是否为项目管理员 def is_project_manager?(user_id, project_id) @result = false mem = Member.where("user_id = ? and project_id = ?",user_id, project_id) unless mem.blank? @result = mem.first.roles.to_s.include?("Manager") ? true : false end return @result end # 公开项目资源可以引用,admin和管理员和资源上传者拥有设置公开私有权限 def authority_pubilic_for_files(project, file) @result = false if (is_project_manager?(User.current.id, @project.id) && User.current.allowed_to?(:manage_files, project)) || file.author_id == User.current.id || User.current.admin && project_contains_attachment?(project,file) && file.container_id == project.id && file.container_type == "Project" @result = true end return @result end def principals_check_box_tags(name, principals) s = '' principals.each do |principal| s << "\n" end s.html_safe end # 判断模块是否可见 def project_modules_allow project @project.enabled_modules.where("name = 'issue_tracking'").empty? end # 计算Pull Request的请求数目 def pull_request_count project g = Gitlab.client g.merge_requests(project.gpid).count end #项目成员列表复选框生成 def project_member_check_box_tags_ex name, principals s = '' principals.each do |principal| s << "
  • #{ check_box_tag name, principal.id, false, :id => nil} #{h link_to principal.userInfo, user_url_in_org( principal), :target => "_blank"}
  • \n" end s.html_safe end def render_shixun_departments s = '' if params[:q] && params[:q].lstrip.rstrip != "" scope = School.where("name like ?", "%#{params[:q]}%") else scope = [] end scope.each do |name| s << "
  • #{name}
  • \n" end s.html_safe end # REDO:发现搜索列表的功能还是挺多,以前单独写的最好都调用这个方法 # scope:[] def render_mirror_name scope = nil s = '' if scope.present? scope.each do |name| s << "
  • #{name}
  • \n" end end s.html_safe end #缺陷追踪者列表复选框生成 def issue_watcher_check_box_tags_ex name, principals s = '' principals.each do |principal| s << "
  • #{ check_box_tag name, principal.id, false, :id => nil } #{h link_to principal.userInfo, user_path( principal.id)}
  • \n" end s.html_safe end #扩展的checkbox生成 def principals_check_box_tags_ex(name, principals) s = '' principals.each do |principal| s << "\n" end s.html_safe end # li标签checkbos扩展 def principals_check_box_tags_li(name, principals) s = '' principals.each do |principal| s << "
  • #{ check_box_tag name, principal.id, false, :id => nil } #{h link_to principal.userInfo, user_path( principal.id) }
  • \n" end s.html_safe end #扩展的checkbox生成 def principals_radio_box_tags_ex(name, principals) s = '' principals.each do |principal| s << "\n" end s.html_safe end # Returns a string for users/groups option tags def principals_options_for_select(collection, selected=nil) s = '' if collection.include?(User.current) s << content_tag('option', "<< #{l(:label_me)} >>", :value => User.current.id) end groups = '' collection.sort.each do |element| selected_attribute = ' selected="selected"' if option_value_selected?(element, selected) (element.is_a?(Group) ? groups : s) << %() end unless groups.empty? s << %(#{groups}) end s.html_safe end def assigned_options_for_select(collection, selected=nil) conv = Iconv.new("GBK", "utf-8") s = '' s << content_tag('option', "#{l(:label_assiged_tip)}", :value => 0) if collection.include?(User.current) s << content_tag('option', "<< #{l(:label_me)} >>", :value => User.current.id) end groups = '' collection.sort{|x, y| conv.iconv(x.lastname) <=> conv.iconv(y.lastname)}.each do |element| selected_attribute = ' selected="selected"' if option_value_selected?(element, selected) (element.is_a?(Group) ? groups : s) << %() end unless groups.empty? s << %(#{groups}) end s.html_safe end # Options for the new membership projects combo-box def options_for_membership_project_select(principal, projects) options = content_tag('option', "--- #{l(:actionview_instancetag_blank_option)} ---") options << project_tree_options_for_select(projects) do |p| {:disabled => principal.projects.to_a.include?(p)} end options end # Truncates and returns the string as a single line def truncate_single_line(string, *args) truncate(string.to_s, *args).gsub(%r{[\r\n]+}m, ' ') end # Truncates at line break after 250 characters or options[:length] def truncate_lines(string, options={}) length = options[:length] || 250 if string.to_s =~ /\A(.{#{length}}.*?)$/m "#{$1}..." else string end end def anchor(text) text.to_s.gsub(' ', '_') end def html_hours(text) text.gsub(%r{(\d+)\.(\d+)}, '\1.\2').html_safe end def authoring(created, author, options={}) l(options[:label] || :label_added_time_by, :author => link_to_user(author), :age => time_tag(created)).html_safe end def added_time(created) l(:label_added_time, :age => time_tag(created)).html_safe end def user_url_and_time(user_name, user_url, created) unless user_name.nil? || user_name == '' l(:label_added_time_by, :author => link_to(user_name, user_url), :age => time_tag(created)).html_safe else l(:label_added_time, :age => time_tag(created)).html_safe end end #huang def betweentime(enddate) ss=(DateTime.parse("#{enddate.to_date}")-DateTime.parse("#{DateTime.now.to_date}")).to_i return ss end def time_tag(time, *args) options = args.extract_options! text = distance_of_time_in_words(Time.now, time) if @project content_tag('acronym', text, options.reverse_merge(:title => format_time(time))) # link_to(text, {:controller => 'activities', :action => 'index', :id => @project, :from => User.current.time_to_date(time)},options.reverse_merge(:title => format_time(time))) else content_tag('acronym', text, options.reverse_merge(:title => format_time(time))) end end def syntax_highlight_lines(name, content) lines = [] syntax_highlight(name, content).each_line { |line| lines << line } lines end def syntax_highlight(name, content) Redmine::SyntaxHighlighting.highlight_by_filename(content, name) end def to_path_param(path) str = path.to_s.split(%r{[/\\]}).select{|p| !p.blank?}.join("/") str.blank? ? nil : str end def reorder_links(name, url, method = :post) link_to(image_tag('2uparrow.png', :alt => l(:label_sort_highest)), url.merge({"#{name}[move_to]" => 'highest'}), :method => method, :title => l(:label_sort_highest)) + link_to(image_tag('1uparrow.png', :alt => l(:label_sort_higher)), url.merge({"#{name}[move_to]" => 'higher'}), :method => method, :title => l(:label_sort_higher)) + link_to(image_tag('1downarrow.png', :alt => l(:label_sort_lower)), url.merge({"#{name}[move_to]" => 'lower'}), :method => method, :title => l(:label_sort_lower)) + link_to(image_tag('2downarrow.png', :alt => l(:label_sort_lowest)), url.merge({"#{name}[move_to]" => 'lowest'}), :method => method, :title => l(:label_sort_lowest)) end def breadcrumb(*args) elements = args.flatten elements.any? ? content_tag('p', (args.join(" \xc2\xbb ") + " \xc2\xbb ").html_safe, :class => 'wiki_con_tit"') : nil end def other_formats_links(&block) concat('

    '.html_safe + l(:label_export_to)) yield Redmine::Views::OtherFormatsBuilder.new(self) concat('

    '.html_safe) end def page_header_title if @project.nil? || @project.new_record? h(Setting.app_title) else b = [] ancestors = (@project.root? ? [] : @project.ancestors.visible.all) if ancestors.any? root = ancestors.shift b << link_to_project(root, {:jump => current_menu_item}, :class => 'root') if ancestors.size > 2 b << "\xe2\x80\xa6" ancestors = ancestors[-2, 2] end b += ancestors.collect {|p| link_to_project(p, {:jump => current_menu_item}, :class => 'ancestor') } end b << h(@project) b.join(" \xc2\xbb ").html_safe end end def html_title(*args) #點擊項目版本庫 多觸發一次 字符串為"/" #暫時解決方法 直接判斷 if(args == ["/"]) args = [] end # first_page = FirstPage.find_by_page_type('project') if args.empty? title = @html_title || [] if @project title << (@project.name.present? ? @project.name : "项目") elsif params[:controller] == "projects" title << "项目" elsif @welcome title << "创新源于实践" elsif @course title << (@course.name.nil? ? "课堂" : @course.name) elsif params[:controller] == "homework_bank" || params[:controller] == "question_banks" || params[:controller] == "exercise_bank" title << ("题库") elsif params[:controller] == "managements" title << ("后台管理") elsif params[:controller] == "colleges" && params[:action] == "statistics" title << ("#{@school.name}") elsif params[:controller] == "account" && params[:action] == "help" if params[:index] case params[:index] when "1" title << ("关于我们") when "2" title << ("联系我们") when "3" title << ("合作伙伴") when "4" title << ("服务协议") when "5" title << ("帮助中心") when "6" title << ("意见反馈") end else title << ("关于我们") end elsif params[:controller] == "courses" && params[:action] == "index" title << ("翻转课堂") elsif params[:controller] == "competitions" && params[:action] == "index" title << ("竞赛") elsif @competition title << (@competition.name.nil? ? "竞赛" : @competition.name) elsif @contest title << (@contest.name.nil? ? "创新源于实践" : @contest.name) elsif @shixun title << (@shixun.name.nil? ? "开发社区" : @shixun.name) elsif @my_shixun title << ("我的实训") elsif params[:controller] == "shixuns" && params[:action] == "index" title << ("开发社区") elsif @subject title << (@subject.name.nil? ? "实训课程" : @subject.name) elsif params[:controller] == "subjects" && params[:action] == "index" title << ("实训课程") elsif @organization title << (@organization.name.nil? ? "创新源于实践" : @organization.name) elsif @forum || params[:controller] == "forums" title << "讨论区" elsif @my_syllabuses title << "我的课堂" elsif params[:controller] == 'ecs' title << '专业列表' elsif params[:controller] == 'ec_major_schools' name = EcMajorSchool.find(params[:id]).name title << name elsif params[:controller] == 'ec_years' if params[:action] == 'training_objectives' title << '培养目标' elsif params[:action] == 'graduation_requirement' title << '毕业要求' elsif params[:action] == 'requirement_vs_objective' title << '毕业要求 vs 培养目标' elsif params[:action] == 'requirement_vs_standard' title << '毕业要求 vs 通用标准' elsif params[:action] == 'ec_course_setting' || params[:action] == 'completion_calculation' title << '课程体系' else title << '工程认证' end elsif params[:controller] == 'ec_courses' if params[:action] == 'ec_course_support_setting' title << '课程体系 vs 毕业要求' end elsif @user if !@project_community.blank? || !@user_projectlist.blank? title << "项目" elsif !@course_community.blank? || !@user_courselist.blank? title << "课堂" elsif !@contest_community.blank? title << @contest_community elsif !@manage_issues.blank? title << @manage_issues elsif !@receive_issues.blank? title << @receive_issues elsif !@manage_homeworks.blank? title << @manage_homeworks elsif !@receive_homeworks.blank? title << @receive_homeworks else title << @user.show_name end elsif @syllabus title << (@syllabus.title.nil? ? "课堂" : @syllabus.title) else title << (User.current.id == 2 ? "未登录" : User.current.show_name) end # if first_page.nil? || first_page.web_title.nil? # title << Setting.app_title unless Setting.app_title == title.last # else # title << first_page.web_title unless first_page.web_title == title.last # end title.select {|t| !t.blank? }.join(' - ') else @html_title ||= [] @html_title += args end end # Returns the theme, controller name, and action as css classes for the # HTML body. def body_css_classes css = [] if theme = Redmine::Themes.theme(Setting.ui_theme) css << 'theme-' + theme.name end css << 'controller-' + controller_name css << 'action-' + action_name css.join(' ') end def accesskey(s) @used_accesskeys ||= [] key = Redmine::AccessKeys.key_for(s) return nil if @used_accesskeys.include?(key) @used_accesskeys << key key end # Formats text according to system settings. # 2 ways to call this method: # * with a String: textilizable(text, options) # * with an object and one of its attribute: textilizable(issue, :description, options) def textilizable(*args) options = args.last.is_a?(Hash) ? args.pop : {} case args.size when 1 obj = options[:object] text = args.shift when 2 obj = args.shift attr = args.shift text = obj.send(attr).to_s else raise ArgumentError, 'invalid arguments to textilizable' end return '' if text.blank? project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil) only_path = options.delete(:only_path) == false ? false : true text = text.dup macros = catch_macros(text) text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text, :object => obj, :attribute => attr) @parsed_headings = [] @heading_anchors = {} @current_section = 0 if options[:edit_section_links] parse_sections(text, project, obj, attr, only_path, options) text = parse_non_pre_blocks(text, obj, macros) do |text| [:parse_inline_attachments, :parse_wiki_links, :parse_redmine_links].each do |method_name| send method_name, text, project, obj, attr, only_path, options end end parse_headings(text, project, obj, attr, only_path, options) if @parsed_headings.any? replace_toc(text, @parsed_headings) end text.html_safe end # #格式化字符串,不转义html代码 def textAreailizable(*args) options = args.last.is_a?(Hash) ? args.pop : {} case args.size when 1 obj = options[:object] text = args.shift when 2 obj = args.shift attr = args.shift text = obj.send(attr).to_s else raise ArgumentError, 'invalid arguments to textilizable' end return '' if text.blank? project = options[:project] || @project || (obj && obj.respond_to?(:project) ? obj.project : nil) only_path = options.delete(:only_path) == false ? false : true text = text.dup macros = catch_macros(text) #text = Redmine::WikiFormatting.to_html("CKEditor", text, :object => obj, :attribute => attr) @parsed_headings = [] @heading_anchors = {} @current_section = 0 if options[:edit_section_links] parse_sections(text, project, obj, attr, only_path, options) text = parse_non_pre_blocks(text, obj, macros) do |text| [:parse_inline_attachments, :parse_wiki_links, :parse_redmine_links].each do |method_name| send method_name, text, project, obj, attr, only_path, options end end parse_headings(text, project, obj, attr, only_path, options) if @parsed_headings.any? replace_toc(text, @parsed_headings) end text.html_safe end def parse_non_pre_blocks(text, obj, macros) s = StringScanner.new(text) tags = [] parsed = '' while !s.eos? s.scan(/(.*?)(<(\/)?(pre|code)(.*?)>|\z)/im) text, full_tag, closing, tag = s[1], s[2], s[3], s[4] if tags.empty? yield text inject_macros(text, obj, macros) if macros.any? else inject_macros(text, obj, macros, false) if macros.any? end parsed << text if tag if closing if tags.last == tag.downcase tags.pop end else tags << tag.downcase end parsed << full_tag end end # Close any non closing tags while tag = tags.pop parsed << "" end parsed end def parse_inline_attachments(text, project, obj, attr, only_path, options) # when using an image link, try to use an attachment, if possible attachments = options[:attachments] || [] attachments += obj.attachments if obj.respond_to?(:attachments) if attachments.present? text.gsub!(/src="([^\/"]+\.(bmp|gif|jpg|jpe|jpeg|png))"(\s+alt="([^"]*)")?/i) do |m| filename, ext, alt, alttext = $1.downcase, $2, $3, $4 # search for the picture in attachments if found = Attachment.latest_attach(attachments, filename) image_url = download_named_attachment_path(found, found.filename, :only_path => only_path) desc = found.description.to_s.gsub('"', '') if !desc.blank? && alttext.blank? alt = " title=\"#{desc}\" alt=\"#{desc}\"" end "src=\"#{image_url}\"#{alt}" else m end end end end # 判断课程、项目、组织是否有权限删除历史资源 # 项目管理员或者附件的作者可以删除 # (is_project_manager?(User.current.id, @project.id) || User.current.id == history.author_id) def allow_to_delete_attachment history attachment = history.attachment case attachment.try(:container_type) when "Project" result = is_project_manager?(User.current.id, attachment.container_id) || User.current.id == history.author_id || User.current.admin? when "Course" result = User.current.allowed_to?(:as_teacher, attachment.container) || User.current.id == history.author_id || User.current.admin? when "OrgSubfield" result = User.current.id == history.author_id || User.current.admin_of_org?(attachment.container) || User.current.admin? end end # Wiki links # # Examples: # [[mypage]] # [[mypage|mytext]] # wiki links can refer other project wikis, using project name or identifier: # [[project:]] -> wiki starting page # [[project:|mytext]] # [[project:mypage]] # [[project:mypage|mytext]] def parse_wiki_links(text, project, obj, attr, only_path, options) text.gsub!(/(!)?(\[\[([^\]\n\|]+)(\|([^\]\n\|]+))?\]\])/) do |m| link_project = project esc, all, page, title = $1, $2, $3, $5 if esc.nil? if page =~ /^([^\:]+)\:(.*)$/ identifier, page = $1, $2 link_project = Project.find_by_identifier(identifier) || Project.find_by_name(identifier) title ||= identifier if page.blank? end if link_project && link_project.wiki # extract anchor anchor = nil if page =~ /^(.+?)\#(.+)$/ page, anchor = $1, $2 end anchor = sanitize_anchor_name(anchor) if anchor.present? # check if page exists wiki_page = link_project.wiki.find_page(page) url = if anchor.present? && wiki_page.present? && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version)) && obj.page == wiki_page "##{anchor}" else case options[:wiki_links] when :local; "#{page.present? ? Wiki.titleize(page) : ''}.html" + (anchor.present? ? "##{anchor}" : '') when :anchor; "##{page.present? ? Wiki.titleize(page) : title}" + (anchor.present? ? "_#{anchor}" : '') # used for single-file wiki export else wiki_page_id = page.present? ? Wiki.titleize(page) : nil parent = wiki_page.nil? && obj.is_a?(WikiContent) && obj.page && project == link_project ? obj.page.title : nil url_for(:only_path => only_path, :controller => 'wiki', :action => 'show', :project_id => link_project, :id => wiki_page_id, :version => nil, :anchor => anchor, :parent => parent) end end link_to(title.present? ? title.html_safe : h(page), User.current.logged? ? url : signin_url_without_domain, :class => ('wiki-page' + (wiki_page ? '' : ' new'))) else # project or wiki doesn't exist all end else all end end end def select_option_helper option tmp = Hash.new tmp={"" => ""} if option.nil? else option.each do |project| tmp[project.name] = project.id end end tmp end # Redmine links # # Examples: # Issues: # #52 -> Link to issue #52 # Changesets: # r52 -> Link to revision 52 # commit:a85130f -> Link to scmid starting with a85130f # Documents: # document#17 -> Link to document with id 17 # document:Greetings -> Link to the document with title "Greetings" # document:"Some document" -> Link to the document with title "Some document" # Versions: # version#3 -> Link to version with id 3 # version:1.0.0 -> Link to version named "1.0.0" # version:"1.0 beta 2" -> Link to version named "1.0 beta 2" # Attachments: # attachment:file.zip -> Link to the attachment of the current object named file.zip # Source files: # source:some/file -> Link to the file located at /some/file in the project's repository # source:some/file@52 -> Link to the file's revision 52 # source:some/file#L120 -> Link to line 120 of the file # source:some/file@52#L120 -> Link to line 120 of the file's revision 52 # export:some/file -> Force the download of the file # Forum messages: # message#1218 -> Link to message with id 1218 # # Links can refer other objects from other projects, using project identifier: # identifier:r52 # identifier:document:"Some document" # identifier:version:1.0.0 # identifier:source:some/file def parse_redmine_links(text, default_project, obj, attr, only_path, options) text.gsub!(%r{([\s\(,\-\[\>]|^)(!)?(([a-z0-9\-_]+):)?(attachment|document|version|forum|news|message|project|commit|source|export)?(((#)|((([a-z0-9\-_]+)\|)?(r)))((\d+)((#note)?-(\d+))?)|(:)([^"\s<>][^\s<>]*?|"[^"]+?"))(?=(?=[[:punct:]][^A-Za-z0-9_/])|,|\s|\]|<|$)}) do |m| leading, esc, project_prefix, project_identifier, prefix, repo_prefix, repo_identifier, sep, identifier, comment_suffix, comment_id = $1, $2, $3, $4, $5, $10, $11, $8 || $12 || $18, $14 || $19, $15, $17 link = nil project = default_project if project_identifier project = Project.visible.find_by_identifier(project_identifier) end if esc.nil? if prefix.nil? && sep == 'r' if project repository = nil if repo_identifier repository = project.repositories.detect {|repo| repo.identifier == repo_identifier} else repository = project.repository end # project.changesets.visible raises an SQL error because of a double join on repositories if repository && (changeset = Changeset.visible.find_by_repository_id_and_revision(repository.id, identifier)) link = link_to(h("#{project_prefix}#{repo_prefix}r#{identifier}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.revision}, :class => 'changeset', :title => truncate_single_line(changeset.comments, :length => 100)) end end elsif sep == '#' oid = identifier.to_i case prefix when nil if oid.to_s == identifier && issue = Issue.visible.find_by_id(oid, :include => :status) anchor = comment_id ? "note-#{comment_id}" : nil link = link_to("##{oid}", {:only_path => only_path, :controller => 'issues', :action => 'show', :id => oid, :anchor => anchor}, :class => issue.css_classes, :title => "#{truncate(issue.subject, :length => 100)} (#{issue.status.name})") end when 'document' if document = Document.visible.find_by_id(oid) link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document}, :class => 'document' end when 'version' if version = Version.visible.find_by_id(oid) link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version}, :class => 'version' end when 'message' if message = Message.visible.find_by_id(oid, :include => :parent) link = link_to_message(message, {:only_path => only_path}, :class => 'message') end when 'forum' if board = Board.visible.find_by_id(oid) link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project}, :class => 'board' end when 'news' if news = News.visible.find_by_id(oid) link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news}, :class => 'news' end when 'project' if p = Project.visible.find_by_id(oid) link = link_to_project(p, {:only_path => only_path}, :class => 'project') end end elsif sep == ':' # removes the double quotes if any name = identifier.gsub(%r{^"(.*)"$}, "\\1") case prefix when 'document' if project && document = project.documents.visible.find_by_title(name) link = link_to h(document.title), {:only_path => only_path, :controller => 'documents', :action => 'show', :id => document}, :class => 'document' end when 'version' if project && version = project.versions.visible.find_by_name(name) link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version}, :class => 'version' end when 'forum' if project && board = project.boards.visible.find_by_name(name) link = link_to h(board.name), {:only_path => only_path, :controller => 'boards', :action => 'show', :id => board, :project_id => board.project}, :class => 'board' end when 'news' if project && news = project.news.visible.find_by_title(name) link = link_to h(news.title), {:only_path => only_path, :controller => 'news', :action => 'show', :id => news}, :class => 'news' end when 'commit', 'source', 'export' if project repository = nil if name =~ %r{^(([a-z0-9\-_]+)\|)(.+)$} repo_prefix, repo_identifier, name = $1, $2, $3 repository = project.repositories.detect {|repo| repo.identifier == repo_identifier} else repository = project.repository end if prefix == 'commit' if repository && (changeset = Changeset.visible.where("repository_id = ? AND scmid LIKE ?", repository.id, "#{name}%").first) link = link_to h("#{project_prefix}#{repo_prefix}#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project, :repository_id => repository.identifier_param, :rev => changeset.identifier}, :class => 'changeset', :title => truncate_single_line(changeset.comments, :length => 100) end else if repository && User.current.allowed_to?(:browse_repository, project) name =~ %r{^[/\\]*(.*?)(@([^/\\@]+?))?(#(L\d+))?$} path, rev, anchor = $1, $3, $5 link = link_to h("#{project_prefix}#{prefix}:#{repo_prefix}#{name}"), {:controller => 'repositories', :action => (prefix == 'export' ? 'raw' : 'entry'), :id => project, :repository_id => repository.identifier_param, :path => to_path_param(path), :rev => rev, :anchor => anchor}, :class => (prefix == 'export' ? 'source download' : 'source') end end repo_prefix = nil end when 'attachment' attachments = options[:attachments] || (obj && obj.respond_to?(:attachments) ? obj.attachments : nil) if attachments && attachment = Attachment.latest_attach(attachments, name) link = link_to_attachment(attachment, :only_path => only_path, :download => true, :class => 'attachment') end when 'project' if p = Project.visible.where("identifier = :s OR LOWER(name) = :s", :s => name.downcase).first link = link_to_project(p, {:only_path => only_path}, :class => 'project') end end end end (leading + (link || "#{project_prefix}#{prefix}#{repo_prefix}#{sep}#{identifier}#{comment_suffix}")) end end HEADING_RE = /(]+)?>(.+?)<\/h(\d)>)/i unless const_defined?(:HEADING_RE) def parse_sections(text, project, obj, attr, only_path, options) return unless options[:edit_section_links] text.gsub!(HEADING_RE) do heading = $1 @current_section += 1 if @current_section > 1 content_tag('div', link_to(image_tag('edit.png'), options[:edit_section_links].merge(:section => @current_section)), :class => 'contextual', :title => l(:button_edit_section)) + heading.html_safe else heading end end end # Headings and TOC # Adds ids and links to headings unless options[:headings] is set to false def parse_headings(text, project, obj, attr, only_path, options) return if options[:headings] == false text.gsub!(HEADING_RE) do level, attrs, content = $2.to_i, $3, $4 item = strip_tags(content).strip anchor = sanitize_anchor_name(item) # used for single-file wiki export anchor = "#{obj.page.title}_#{anchor}" if options[:wiki_links] == :anchor && (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version)) @heading_anchors[anchor] ||= 0 idx = (@heading_anchors[anchor] += 1) if idx > 1 anchor = "#{anchor}-#{idx}" end @parsed_headings << [level, anchor, item] "\n#{content}" end end MACROS_RE = /( (!)? # escaping ( \{\{ # opening tag ([\w]+) # macro name (\(([^\n\r]*?)\))? # optional arguments ([\n\r].*?[\n\r])? # optional block of text \}\} # closing tag ) )/mx unless const_defined?(:MACROS_RE) MACRO_SUB_RE = /( \{\{ macro\((\d+)\) \}\} )/x unless const_defined?(:MACRO_SUB_RE) # Extracts macros from text def catch_macros(text) macros = {} text.gsub!(MACROS_RE) do all, macro = $1, $4.downcase if macro_exists?(macro) || all =~ MACRO_SUB_RE index = macros.size macros[index] = all "{{macro(#{index})}}" else all end end macros end # Executes and replaces macros in text def inject_macros(text, obj, macros, execute=true) text.gsub!(MACRO_SUB_RE) do all, index = $1, $2.to_i orig = macros.delete(index) if execute && orig && orig =~ MACROS_RE esc, all, macro, args, block = $2, $3, $4.downcase, $6.to_s, $7.try(:strip) if esc.nil? h(exec_macro(macro, obj, args, block) || all) else h(all) end elsif orig h(orig) else h(all) end end end TOC_RE = /

    \{\{([<>]?)toc\}\}<\/p>/i unless const_defined?(:TOC_RE) # Renders the TOC with given headings def replace_toc(text, headings) text.gsub!(TOC_RE) do # Keep only the 4 first levels headings = headings.select{|level, anchor, item| level <= 4} if headings.empty? '' else div_class = 'toc' div_class << ' right' if $1 == '>' div_class << ' left' if $1 == '<' out = "

    ' * (current - root) out << '' end end end # Same as Rails' simple_format helper without using paragraphs def simple_format_without_paragraph(text) text.to_s. gsub(/\r\n?/, "\n"). # \r\n and \r -> \n gsub(/\n\n+/, "

    "). # 2+ newline -> 2 br gsub(/([^\n]\n)(?=[^\n])/, '\1
    '). # 1 newline -> br html_safe end def wiki_simple_format_without_paragraph(text) text.to_s. gsub(/\r\n?/, "\n"). # \r\n and \r -> \n gsub(/\n\n+/, "

    "). # 2+ newline -> 2 br gsub(/([^\n]\n)(?=[^\n])/, '\1
    '). # 1 newline -> br gsub("&nbsp", " "). #gsub(/<\/?.*?>/,""). gsub(/<\/?.*?>/, ""). gsub(""", "'"). html_safe end def lang_options_for_select(blank=true) { 'Chinese简体中文 '=> 'zh', :English => :en} end def label_tag_for(name, option_tags = nil, options = {}) label_text = l(("field_"+field.to_s.gsub(/\_id$/, "")).to_sym) + (options.delete(:required) ? @template.content_tag("span", " *", :class => "required"): "") content_tag("label", label_text) end def labelled_form_for(*args, &proc) args << {} unless args.last.is_a?(Hash) options = args.last if args.first.is_a?(Symbol) options.merge!(:as => args.shift) end options.merge!({:builder => Redmine::Views::LabelledFormBuilder}) form_for(*args, &proc) end def labelled_fields_for(*args, &proc) args << {} unless args.last.is_a?(Hash) options = args.last options.merge!({:builder => Redmine::Views::LabelledFormBuilder}) fields_for(*args, &proc) end def labelled_remote_form_for(*args, &proc) ActiveSupport::Deprecation.warn "ApplicationHelper#labelled_remote_form_for is deprecated and will be removed in Redmine 2.2." args << {} unless args.last.is_a?(Hash) options = args.last options.merge!({:builder => Redmine::Views::LabelledFormBuilder, :remote => true}) form_for(*args, &proc) end def error_messages_for(*objects) html = "" # modified by fq if objects.first.is_a?(Array) objects = objects.first end # end if objects != nil objects = objects.map {|o| o.is_a?(String) ? instance_variable_get("@#{o}") : o}.compact errors = objects.map {|o| o.errors.full_messages}.flatten if errors.any? html << "
    \n" end end html.html_safe end def delete_link(url, options={}) options = { :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => 'icon icon-del' }.merge(options) link_to l(:button_delete), url, options end def update_status_link(user) url = {:controller => 'users', :action => 'update', :id => user, :page => params[:page], :status => params[:status], :tab => nil} if user.locked? link_to "解锁", url.merge(:user => {:status => User::STATUS_ACTIVE}), :method => :put, :class => 'mr10 link-color-blue' elsif user.registered? link_to "激活", url.merge(:user => {:status => User::STATUS_ACTIVE}), :method => :put, :class => 'mr10 link-color-blue' elsif user != User.current link_to "加锁", url.merge(:user => {:status => User::STATUS_LOCKED}), :method => :put, :class => 'mr10 link-color-blue' end end def delete_version_link(url, options={}) options = { :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => 'icon icon-del' }.merge(options) link_to "", url, options end def delete_link_version(url, options={}) options = { :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => 'c_purple' }.merge(options) link_to l(:button_delete), url, options end def delete_new_link(url, options={}) options = { :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => "c_purple" }.merge(options) link_to l(:button_delete), url, options end def preview_link(url, form, target='preview', options={}) content_tag 'a', l(:label_preview), { :href => "#", :onclick => %|submitPreview("#{escape_javascript url_for(url)}", "#{escape_javascript form}", "#{escape_javascript target}"); return false;|, :accesskey => accesskey(:preview) }.merge(options) end def link_to_function(name, function, html_options={}) content_tag(:a, name, {:href => '#', :onclick => "#{function}; return false;"}.merge(:class => "BlueCirBtnMini ml10",:style => "display:inline-block; height:20px; line-height:20px;")) end def link_to_function_none(name, function, html_options={}) content_tag(:a, name, {:href => '#', :onclick => "#{function}; return false;"}.merge(:style => "display:inline-block; height:20px; line-height:20px;")) end # Helper to render JSON in views def raw_json(arg) arg.to_json.to_s.gsub('/', '\/').html_safe end def back_url url = params[:back_url] if url.nil? && referer = request.env['HTTP_REFERER'] url = CGI.unescape(referer.to_s) end url end def back_url_hidden_field_tag url = back_url hidden_field_tag('back_url', url, :id => nil) unless url.blank? end def check_all_links(form_name) link_to_function_none(l(:button_check_all), "checkAll('#{form_name}', true)") + " ".html_safe + " | "+ " ".html_safe + link_to_function_none(l(:button_uncheck_all), "checkAll('#{form_name}', false)") end # 本次修改,修改为只显示关闭的所占%比 def progress_bar(pcts, options={}) pcts = [pcts] unless pcts.is_a?(Array) pcts = pcts.collect(&:round) # pcts[1] = pcts[1] + pcts[0] pcts << (100 - pcts[0]) width = options[:width] || '100px;' legend = options[:legend] || '' content_tag('span', content_tag('tr', (pcts[0] > 0 ? content_tag('span', '', :style => "width: #{pcts[0]}%;", :class => 'roadmap_progressbar_inner', :title => "已关闭:#{pcts[0]}%") : ''.html_safe) #+ # (pcts[1] > 0 ? content_tag('td', '', :style => "width: #{pcts[1]}%;", :class => 'done', :title => "开发中:#{pcts[1]}%") : ''.html_safe) + #(pcts[1] > 0 ? content_tag('span', '', :style => "width: #{pcts[1]}%;", :class => 'roadmap_progressbar ml5', :title => "未完成:#{pcts[1]}%") : ''.html_safe), :style => "width: #{width}" ), :class => 'roadmap_progressbar ml5').html_safe # + content_tag('p', legend, :class => 'percent').html_safe end def checked_image(checked=true) if checked image_tag 'toggle_check.png' end end def context_menu(url) unless @context_menu_included content_for :header_tags do javascript_include_tag('context_menu') + stylesheet_link_tag('context_menu') end if l(:direction) == 'rtl' content_for :header_tags do stylesheet_link_tag('context_menu_rtl') end end @context_menu_included = true end javascript_tag "contextMenuInit('#{ url_for(url) }')" end def calendar_for(field_id,start_day=nil) include_calendar_headers_tags(start_day) javascript_tag("$(function() { $('##{field_id}').datepicker(datepickerOptions); });") end def include_calendar_headers_tags(start_day=nil) if start_day.nil? unless @calendar_headers_tags_included @calendar_headers_tags_included = true content_for :header_tags do start_of_week = Setting.start_of_week start_of_week = l(:general_first_day_of_week, :default => '1') if start_of_week.blank? # Redmine uses 1..7 (monday..sunday) in settings and locales # JQuery uses 0..6 (sunday..saturday), 7 needs to be changed to 0 start_of_week = start_of_week.to_i % 7 tags = javascript_tag( "var datepickerOptions={dateFormat: 'yy-mm-dd', firstDay: #{start_of_week}, " + "showOn: 'button', buttonImageOnly: true, buttonImage: '" + path_to_image('/images/public_icon.png') + "', showButtonPanel: true, showWeek: true, showOtherMonths: true, selectOtherMonths: true};") jquery_locale = l('jquery.locale', :default => current_language.to_s) unless jquery_locale == 'en' tags << javascript_include_tag("i18n/jquery.ui.datepicker-#{jquery_locale}.js") end tags end end else unless @calendar_headers_tags_included @calendar_headers_tags_included = true content_for :header_tags do start_of_week = Setting.start_of_week start_of_week = l(:general_first_day_of_week, :default => '1') if start_of_week.blank? # Redmine uses 1..7 (monday..sunday) in settings and locales # JQuery uses 0..6 (sunday..saturday), 7 needs to be changed to 0 start_of_week = start_of_week.to_i % 7 tags = javascript_tag( "var datepickerOptions={dateFormat: 'yy-mm-dd',minDate: new Date(), firstDay: #{start_of_week}, " + "showOn: 'button', buttonImageOnly: true, buttonImage: '" + path_to_image('/images/public_icon.png') + "', showButtonPanel: true, showWeek: true, showOtherMonths: true, selectOtherMonths: true, onClose: function(dateText, inst) {TimeClose(dateText,inst);}, beforeShow : function(input){TimeBeforeShow(input);} };") jquery_locale = l('jquery.locale', :default => current_language.to_s) unless jquery_locale == 'en' tags << javascript_include_tag("i18n/jquery.ui.datepicker-#{jquery_locale}.js") end tags end end end end # Overrides Rails' stylesheet_link_tag with themes and plugins support. # Examples: # stylesheet_link_tag('styles') # => picks styles.css from the current theme or defaults # stylesheet_link_tag('styles', :plugin => 'foo) # => picks styles.css from plugin's assets # def stylesheet_link_tag(*sources) options = sources.last.is_a?(Hash) ? sources.pop : {} plugin = options.delete(:plugin) sources = sources.map do |source| if plugin "/plugin_assets/#{plugin}/stylesheets/#{source}" elsif current_theme && current_theme.stylesheets.include?(source) current_theme.stylesheet_path(source) else source end end super sources, options end # Overrides Rails' image_tag with themes and plugins support. # Examples: # image_tag('image.png') # => picks image.png from the current theme or defaults # image_tag('image.png', :plugin => 'foo) # => picks image.png from plugin's assets # def image_tag(source, options={}) if plugin = options.delete(:plugin) source = "/plugin_assets/#{plugin}/images/#{source}" elsif current_theme && current_theme.images.include?(source) source = current_theme.image_path(source) end super source, options end # Overrides Rails' javascript_include_tag with plugins support # Examples: # javascript_include_tag('scripts') # => picks scripts.js from defaults # javascript_include_tag('scripts', :plugin => 'foo) # => picks scripts.js from plugin's assets # def javascript_include_tag(*sources) options = sources.last.is_a?(Hash) ? sources.pop : {} @sources ||= [] sources = sources.delete_if do|source| @sources.include?(source) end @sources += sources if plugin = options.delete(:plugin) sources = sources.map do |source| if plugin "/plugin_assets/#{plugin}/javascripts/#{source}" else source end end end if sources && !sources.empty? super(sources, options) else '' end end def content_for(name, content = nil, &block) @has_content ||= {} @has_content[name] = true super(name, content, &block) end def has_content?(name) (@has_content && @has_content[name]) || false end def sidebar_content? has_content?(:sidebar) || view_layouts_base_sidebar_hook_response.present? end def view_layouts_base_sidebar_hook_response @view_layouts_base_sidebar_hook_response ||= call_hook(:view_layouts_base_sidebar) end def email_delivery_enabled? !!ActionMailer::Base.perform_deliveries end # Returns the avatar image tag for the given +user+ if avatars are enabled # +user+ can be a User or a string that will be scanned for an email address (eg. 'joe ') def avatar(user, options = { }) if Setting.gravatar_enabled? options.merge!({:ssl => (request && request.ssl?), :default => Setting.gravatar_default}) email = nil if user.respond_to?(:mail) email = user.mail elsif user.to_s =~ %r{<(.+?)>} email = $1 end return gravatar(email.to_s.downcase, options) unless email.blank? rescue nil #options ={"class" => ["avatar2"],"width" =>["80px"],"height" =>["80px"]} #return image_tag url_to_avatar(user), options else '' end end def sanitize_anchor_name(anchor) if ''.respond_to?(:encoding) || RUBY_PLATFORM == 'java' anchor.gsub(%r{[^\s\-\p{Word}]}, '').gsub(%r{\s+(\-+\s*)?}, '-') else # TODO: remove when ruby1.8 is no longer supported anchor.gsub(%r{[^\w\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-') end end # Returns the javascript tags that are included in the html layout head def javascript_heads tags = javascript_include_tag('jquery-1.8.3-ui-1.9.2-ujs-2.0.3', 'application', 'jquery.colorbox-min', 'baiduTemplate') unless User.current.pref.warn_on_leaving_unsaved == '0' tags << "\n".html_safe + javascript_tag("$(window).load(function(){ warnLeavingUnsaved('#{escape_javascript l(:text_warn_on_leaving_unsaved)}'); });") end tags end def javascript_edu_index_heads tags = javascript_include_tag('jquery-1.8.3-ui-1.9.2-ujs-2.0.3', 'application') unless User.current.pref.warn_on_leaving_unsaved == '0' tags << "\n".html_safe + javascript_tag("$(window).load(function(){ warnLeavingUnsaved('#{escape_javascript l(:text_warn_on_leaving_unsaved)}'); });") end tags end def hubspot_head tags = javascript_include_tag('hubspot/messenger.min', 'hubspot/messenger-theme-future') tags << stylesheet_link_tag('hubspot/messenger', 'hubspot/messenger-theme-future', 'hubspot/messenger-theme-flat') end def bootstrap_head tags = stylesheet_link_tag('bootstrap/bootstrap.min', 'bootstrap/bootstrap-theme.min') tags << javascript_include_tag('bootstrap/affix') tags << javascript_include_tag('bootstrap/alert') tags << javascript_include_tag('bootstrap/button') tags << javascript_include_tag('bootstrap/carousel') tags << javascript_include_tag('bootstrap/collapse') tags << javascript_include_tag('bootstrap/dropdown') tags << javascript_include_tag('bootstrap/modal') tags << javascript_include_tag('bootstrap/popover') tags << javascript_include_tag('bootstrap/scrollspy') tags << javascript_include_tag('bootstrap/tab') tags << javascript_include_tag('bootstrap/tooltip') tags << javascript_include_tag('bootstrap/transition') tags end def favicon "".html_safe end def robot_exclusion_tag ''.html_safe end # Returns true if arg is expected in the API response def include_in_api_response?(arg) unless @included_in_api_response param = params[:include] @included_in_api_response = param.is_a?(Array) ? param.collect(&:to_s) : param.to_s.split(',') @included_in_api_response.collect!(&:strip) end @included_in_api_response.include?(arg.to_s) end # Returns options or nil if nometa param or X-Redmine-Nometa header # was set in the request def api_meta(options) if params[:nometa].present? || request.headers['X-Redmine-Nometa'] # compatibility mode for activeresource clients that raise # an error when unserializing an array with attributes nil else options end end # Add by Tao def url_to_avatar(source) source = nil if source.kind_of?(String) get_avatar(source) end # Endof Tao's code # cxt # 获取认证照片 def url_to_auth_img(user_id, type) if File.exist?(disk_auth_filename("UserAuthentication",user_id,type)) File.join(relative_path,avatar_directory("UserAuthentication"), auth_filename(user_id,type)) else File.join(relative_path,avatar_directory("UserAuthentication"),type) end end def url_to_coop_img(type) File.join(relative_path,avatar_directory('type'),"*") end # 讨论区的平台icon ["Java", "C", "C++", "Python2.7", "Python3.6", "MySQL/Java", "Html", "JFinal", "Docker", "Ethereum", "Dynamips", "MachineLearning", "Verilog","Spark","MySQL/Python3.6","PHP","PHP/Web","Hadoop", "Golang","Android","Matlab","Shell"] def url_to_platform_icon language case language when 'Python2.7', 'Python3.6' File.join(relative_path,avatar_directory("Platform"), 'Python') when 'MySQL/Java', 'MySQL/Python3.6' File.join(relative_path,avatar_directory("Platform"), 'MySQL') when 'PHP/Web' File.join(relative_path,avatar_directory("Platform"), 'PHP') when 'C#' File.join(relative_path,avatar_directory("Platform"), 'Cxp') when 'C/C++' File.join(relative_path,avatar_directory("Platform"), 'Cjia') when 'Angular2+' File.join(relative_path,avatar_directory("Platform"), 'Angular2jia') else File.join(relative_path,avatar_directory("Platform"), language.nil? ? "" : language) end end def identity_authentication_status user authorization = user.apply_actions.where(:container_type => "TrialAuthorization").last case user.try(:certification) when 0 if authorization.try(:status) == 0 "处理中" else "未授权" end when 1 "已授权" when 2 "被拒绝" end end def user_certification_status user status = "" if user.authentication status = "已实名认证" else apply_auth = ApplyUserAuthentication.where(:user_id => user.id, :auth_type => 1).last if apply_auth && apply_auth.status == 0 status = "实名认证中" elsif apply_auth && apply_auth.status == 2 status = "实名认证未通过" else status = "未实名认证" end end end def pro_certification_status user status = "" if user.professional_certification status = "已职业认证" else apply_auth = ApplyUserAuthentication.where(:user_id => user.id, :auth_type => 2).last if apply_auth && apply_auth.status == 0 status = "职业认证中" elsif apply_auth && apply_auth.status == 2 status = "职业认证未通过" else status = "未职业认证" end end end def shixun_authentication_status shixun case shixun.try(:status) when 0,nil "编辑中" when 1 "待审核" when 2 "已发布" when 3 "已关闭" end end def date_format_local(time) date = time.strftime("%Y年%m月%d日") end #当TAG数量过多时,更多链接 #1代表是user类型 2代表是project类型 3代表是issue类型 4代表需求 9代表课程 def more_tags id,object_flag a= 1 case object_flag when "1" s = link_to l(:label_more_tags),:controller => "users", :action => "show", :id => id when "2" s = link_to l(:label_more_tags),:controller => "projects", :action => "show", :id => id when "3" s = link_to l(:label_more_tags),:controller => "issues", :action => "show", :id => id when "4" s = link_to l(:label_more_tags),:controller => "bids", :action => "show", :id => id when "9" s = link_to l(:label_more_tags),:controller => "courses", :action => "show", :id => id end s end def get_user_identity identity s = "" case identity when 0 s = '教师' when 1 s = '学生' when 2 s = '组织' when 3 s= '开发者' else s = '学生' end s end # 获取issue类型 def get_issue_type_new tracker_id case tracker_id when 1 "缺陷" when 2 "功能" when 3 "支持" when 4 "任务" when 5 "周报" end end def get_memo @new_memo = Memo.new @public_forum = Forum.find(1) rescue ActiveRecord::RecordNotFound end #获取用户未过期的课程 def get_user_course user courses_doing = [] user.courses.select("courses.*,(SELECT MAX(created_at) FROM `course_activities` WHERE course_activities.course_id = courses.id) AS a").order("a desc").each do |course| if !course_endTime_timeout?(course) courses_doing.push course end end courses_doing end def attachment_history_candown attachment_history if attachment_history.container_type == "Course" course = Course.find(attachment_history.container_id) candown = User.current.member_of_course?(course) || (course.is_public && attachment_history.is_public == 1) elsif attachment_history.container_type == "Project" project = Project.find(attachment_history.container_id) candown = User.current.member_of?(project) || (project.is_public && attachment_history.is_public == 1) elsif attachment_history.container_type == "OrgSubfield" org = OrgSubfield.find(attachment_history.container_id).organization candown = User.current.member_of_org?(org) || (org.organization.is_public && attachment_history.is_public == 1 && (User.current.logged? || org.organization.allow_guest_download?)) end end def resource_bank_candown resource,type candown = false if resource.is_public candown = true end if type == 'syllabus' candown = syllabus_course_member(User.current, resource.course) || User.current.admin? end candown end # 课程某个班级的成员 def syllabus_course_member user, course result = false syllabus = course.syllabus if syllabus syllabus.courses.each do |course| if user.member_of_course?(course) result = true return result end end end result end def attachment_candown attachment candown = false if attachment.container if attachment.container.class.to_s=="PhoneAppVersion" candown = true elsif attachment.container.class.to_s != "HomeworkAttach" && attachment.container.class.to_s != "StudentWork" && attachment.container.class.to_s != "ContestantWork" && (attachment.container.has_attribute?(:project) || attachment.container.has_attribute?(:project_id)) && attachment.container.project project = attachment.container.project candown= User.current.member_of?(project) || (project.is_public && attachment.is_public == 1) elsif attachment.container.is_a?(Project) project = attachment.container candown = User.current.member_of?(project) || (attachment.is_public == 1) || attachment.get_status_by_attach(User.current.id) == 2 elsif (attachment.container.has_attribute?(:board) || attachment.container.has_attribute?(:board_id)) && attachment.container.board && attachment.container.board.project project = attachment.container.board.project candown = User.current.member_of?(project) || (project.is_public && attachment.is_public == 1) elsif (attachment.container.has_attribute?(:course) ||attachment.container.has_attribute?(:course_id) ) && attachment.container.course course = attachment.container.course candown = User.current.member_of_course?(course) || (attachment.is_public == 1) || attachment.get_status_by_attach(User.current.id) == 2 elsif attachment.container.is_a?(Course) course = attachment.container candown= User.current.member_of_course?(course) || (attachment.is_public == 1) || attachment.get_status_by_attach(User.current.id) == 2 elsif attachment.container.is_a?(OrgSubfield) org = attachment.container.organization candown = User.current.member_of_org?(org) || ((attachment.is_public == 1 || attachment.get_status_by_attach(User.current.id) == 2) && org.allow_guest_download == true) elsif attachment.container.is_a?(OrgDocumentComment) org = attachment.container.organization candown = org.allow_guest_download || User.current.member_of_org?(org) || (org.is_public && attachment.is_public == 1) elsif (attachment.container.has_attribute?(:board) || attachment.container.has_attribute?(:board_id)) && attachment.container.board && attachment.container.board.course course = attachment.container.board.course candown= User.current.member_of_course?(course) || (course.is_public==1 && attachment.is_public == 1) elsif attachment.container.class.to_s=="Organization" candown = true elsif attachment.container.class.to_s=="HomeworkAttach" candown = true elsif attachment.container.class.to_s=="StudentWorksScore" candown = true elsif attachment.container.class.to_s=="StudentWork" candown = true elsif attachment.container.class.to_s=="Contest" candown = true elsif attachment.container.class.to_s=="Work" candown = true elsif attachment.container.class.to_s=="ContestantWork" candown = true elsif attachment.container.class.to_s=="HomeworkBank" candown = true elsif attachment.container.class.to_s=="BlogComment" #博客资源允许下载 candown = true elsif attachment.container.class.to_s=="Memo" #论坛资源允许下载 candown = true elsif attachment.container.class.to_s=="Syllabus" #论坛资源允许下载 candown = true elsif attachment.container.class.to_s=="Competition" #竞赛资源允许下载 candown = true elsif attachment.container.class.to_s=="Career" #职业路径资源允许下载 candown = true elsif attachment.container_type == "Inform" #竞赛通知公告允许下载 candown = true elsif attachment.container.class.to_s == "User" candown = (attachment.is_public == 1 || attachment.is_public == true || attachment.author_id == User.current.id) elsif attachment.container_type == "Bid" && attachment.container && attachment.container.courses course = attachment.container.courses.first candown = User.current.member_of_course?(attachment.container.courses.first) || (course.is_public == 1 && attachment.is_public == 1) else candown = (attachment.is_public == 1 || attachment.is_public == true) end else if attachment.container_type == "MarkDown" || attachment.container_type == "Shixun" || attachment.container_type == "Memo" || attachment.container_type == "Career" || attachment.container_type == "Exercise" || attachment.container_type == "ExerciseBank" candown = true end end candown end def project_type_link(text, value) if value == 1 link_to "#{text}".html_safe,"javascript:void(0)" ,:onClick => "show_window();", :class => "pr_join_a",:id => "setting_project_type" elsif value == 2 link_to "#{text}".html_safe,"javascript:void(0)" ,:onClick => "show_window();", :class => "pr_join_a",:id => "setting_project_type" else link_to "#{text}".html_safe,"javascript:void(0)" ,:onClick => "show_window();", :class => "pr_join_a",:id => "setting_project_type" end end #如果学生作品被打分后修改,应该给老师提示 def send_message_to_teacher student_work if StudentWork === student_work student_work_scores = student_work.student_works_scores.where("reviewer_role != 3") if student_work_scores.any? student_work.update_column('re_commit', 1) course = student_work.homework_common.course course.teachers.where(:user_id => student_work_scores.map(&:user_id).uniq).each do|mem| student_work.tidings << Tiding.new(:user_id => mem.user_id, :trigger_user_id => student_work.user_id, :container_id => student_work.id, :container_type => "StudentWork", :parent_container_id => student_work.homework_common_id, :parent_container_type => "HomeworkCommon", :belong_container_id => course.id, :belong_container_type => "Course", :viewed => 0, :tiding_type => "HomeworkCommon", :extra => "resubmit") end end end end private def wiki_helper helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting) extend helper return self end def link_to_content_update(text, url_params = {}, html_options = {}) link_to(text, url_params, html_options) end #added by nie # Display watcher picture def show_more_watchers?(obj) if User.watched_by(obj.id).count > 6 return true else return false end end def show_watcher_profile(obj) count = 0 html = '' if User.watched_by(obj.id).count == 0 html << (content_tag "span", l(:label_no_current_watchers)) end for user in User.watched_by(obj.id) html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => "#{user.name}") count = count + 1 if count >= 12 break end end html.html_safe end #display bid project def show_more_bid_project?(bid) if bid.projects.where('is_public = 1').count > 12 return true else return false end end def show_bid_project(bid) html = '' if bid.projects.where('is_public = 1').count == 0 html << (content_tag "p", l(:label_no_bid_project), :class => "font_lighter") else bid.projects.where('is_public = 1').take(12).each do |project| html << (link_to image_tag(url_to_avatar(project), :class => "avatar", :title => project.name), project_path(project), :class => "avatar") end end html.html_safe end def show_bid_fans_picture(obj) html = '' if obj.watcher_users.count == 0 html << (content_tag "span", l(:label_project_no_follow)) else obj.watcher_users.take(12).each do |user| html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => user.name) end end html.html_safe end #display contest project def show_more_contest_project?(contest) if contest.projects.where('is_public = 1').count > 12 return true else return false end end def show_more_contest_softapplication?(contest) if contest.softapplications.where('is_public = 1').count > 12 return true else return false end end def show_contest_project(bid) html = '' if contest.projects.where('is_public = 1').count == 0 html << (content_tag "p", l(:label_no_bid_project), :class => "font_lighter") else contest.projects.where('is_public = 1').take(12).each do |project| html << (link_to image_tag(url_to_avatar(project), :class => "avatar", :title => project.name), project_path(project), :class => "avatar") end end html.html_safe end def show_contest_project(contest) html = '' if contest.projects.where('is_public = 1').count == 0 html << (content_tag "p", l(:label_no_bid_project), :class => "font_lighter") else contest.projects.where('is_public = 1').take(12).each do |project| html << (link_to image_tag(url_to_avatar(project), :class => "avatar", :title => project.name), project_path(project), :class => "avatar") end end html.html_safe end def show_contest_softapplication(contest) html = '' if contest.softapplications.where('is_public = 1').count == 0 html << (content_tag "p", l(:label_no_contest_softapplication), :class => "font_lighter") else contest.softapplications.where('is_public = 1').take(12).each do |softapplication| html << (link_to image_tag(url_to_avatar(project), :class => "avatar", :title => project.name), project_path(project), :class => "avatar") end end html.html_safe end def show_contest_fans_picture(obj) html = '' if obj.watcher_users.count == 0 html << (content_tag "span", l(:label_project_no_follow)) else obj.watcher_users.take(12).each do |user| html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => user.name) end end html.html_safe end #display fans picture def show_more_fans?(obj) if obj.watcher_users.count > 12 return true else return false end end def show_fans_picture(obj) html = '' if obj.watcher_users.count == 0 html << (content_tag "span", l(:label_no_current_fans)) else obj.watcher_users.take(12).each do |user| html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => user.name) end end html.html_safe end # added by bai def show_more_participate?(obj) if obj.join_in_contests.count > 12 return true else return false end end def show_participate_picture(obj) html = '' count = 0 if obj.join_in_contests.count == 0 html << (content_tag "span", l(:label_no_current_participate)) end for temp in obj.join_in_contests html << (link_to image_tag(url_to_avatar(temp.user), :class => "avatar"), user_path(temp.user), :class => "avatar", :title => "#{temp.user.name}") count = count + 1 if count >= 12 break end end html.html_safe end #end # add by huang def show_watcher_list(user) html = '' count = 0 for user in User.watched_by(user.id) html << (link_to image_tag(url_to_avatar(user), :class => "avatar"), user_path(user), :class => "avatar", :title => "#{user.name}") count = count + 1 if count >= 12 break end end html.html_safe end # end #added by william def get_fans_num(user) user.watcher_users.count end #end def hadcommittedhomework(cur,curb) bid = Bid.find_by_id(curb) return true if bid.nil? case bid.homework_type when Bid::HomeworkFile attaches = HomeworkAttach.where(bid_id: curb) attaches.map(&:user_id).include? cur when Bid::HomeworkProject attaches = BidingProject.where(user_id: User.current, bid_id: bid) attaches.count > 0 # > 0 则有提交记录 else true end end def render_dynamic_nav home_link = link_to l(:field_homepage), {:controller => 'welcome', :action => 'index'} home_link = "
  • " << home_link << "
  • " # bootstrap_render_dynamic_nav content_tag :ul, (home_link.html_safe+bootstrap_render_dynamic_nav) end def bootstrap_render_dynamic_nav hidden_non_project = Setting.find_by_name("hidden_non_project") visiable = !(hidden_non_project && hidden_non_project.value == "0") main_course_link = link_to l(:label_course_practice), {:controller => 'welcome', :action => 'index', :host => Setting.host_course} main_project_link = link_to l(:label_project_deposit), {:controller => 'welcome', :action => 'index', :host => Setting.host_name} main_contest_link = link_to l(:label_contest_innovate), {:controller => 'welcome', :action => 'index', :host => Setting.host_contest} # course_all_course_link = link_to l(:label_course_all), {:controller => 'courses', :action => 'index'} course_teacher_all_link = link_to l(:label_teacher_all), {:controller => 'users', :action => 'index', :role => 'teacher', :host => Setting.host_course} # courses_link = link_to l(:label_course_practice), {:controller => 'courses', :action => 'index'} #users_link = link_to l(:label_software_user), {:controller => 'users', :action => 'index', :host => Setting.host_user} # contest_link = link_to l(:label_contest_innovate), {:controller => 'contests', :action => 'index'} # bids_link = link_to l(:label_requirement_enterprise), {:controller => 'bids', :action => 'index'} forum_link = link_to l(:label_forum_all), {:controller => "forums", :action => "index"} stores_link = link_to l(:label_stores_index), {:controller => 'stores', :action=> 'index'} school_all_school_link = link_to l(:label_school_all), {:controller => 'school', :action => 'index'} project_new_link = link_to l(:label_project_new), {:controller => 'projects', :action => 'new', :host => Setting.host_name} # project_mine_link = link_to l(:label_my_project), {:controller => 'users', :action => 'user_projects', :host => Setting.host_name} #@nav_dispaly_project_label nav_list = Array.new nav_list.push(school_all_school_link) if @nav_dispaly_course_all_label && @show_course == 1 && visiable # nav_list.push(course_all_course_link) if @nav_dispaly_course_all_label && @show_course == 1 nav_list.push(course_teacher_all_link) if @nav_dispaly_teacher_all_label && @show_course == 1 && visiable nav_list.push(main_project_link) if @nav_dispaly_main_project_label nav_list.push(main_course_link) if @nav_dispaly_main_course_label && @show_course == 1 && visiable nav_list.push(main_contest_link) if @nav_dispaly_main_contest_label && @show_contest == 1 && visiable nav_list.push(courses_link) if @nav_dispaly_course_label && @show_course == 1 && visiable nav_list.push(project_new_link) if @nav_dispaly_project_label # nav_list.push(project_mine_link) if @nav_dispaly_main_project_label # nav_list.push(projects_link) if @nav_dispaly_project_label #nav_list.push(users_link) if @nav_dispaly_user_label # nav_list.push(contest_link) if @nav_dispaly_contest_label && @show_contest == 1 nav_list.push(bids_link) if @nav_dispaly_bid_label && visiable nav_list.push(forum_link) if @nav_dispaly_forum_label && visiable nav_list.push(stores_link) if @nav_dispaly_store_all_label && visiable content_li = '' nav_list.collect do |nav_item| content_li << content_tag(:li, nav_item, :class => 'topnav_a fl') end content_li.html_safe end def current_user User.current end # def hadcommittedforcontest(curu) # message = JournalsForMessage.find_by_sql("select * from journals_for_messages where jour_type = 'Softapplication' ") # message.each do |createmessage| # if createmessage.user_id == curu # return true # end # end # end # 获取用户的认证状态 def get_authentication_status user result = '' if user.authentication result += '
  • ' else apply_auth = ApplyUserAuthentication.where(:user_id => user.id, :auth_type => 1).last if apply_auth && apply_auth.status == 0 result += '
  • ' else result += '
  • ' end end if user.professional_certification result += '
  • ' else apply_auth = ApplyUserAuthentication.where(:user_id => user.id, :auth_type => 2).last if apply_auth && apply_auth.status == 0 result += '
  • ' else result += '
  • ' end end return result.html_safe end def footer_logo(ul_class=nil, li_class=nil) logos = [] logos.push(link_to image_tag('/images/footer_logo/nudt.png',:alt=>"nudt"),"http://www.nudt.edu.cn/special.asp?classid=12" ) logos.push(link_to image_tag('/images/footer_logo/peking_eecs.png', :alt=>"peking_eecs"), "http://www.sei.pku.edu.cn/" ) logos.push(link_to image_tag('/images/footer_logo/buaa_scse.png', :alt=>"buaa_scse"), "http://scse.buaa.edu.cn/" ) logos.push(link_to image_tag('/images/footer_logo/iscas.png', :alt=>"iscas"), "http://www.iscas.ac.cn" ) logos.push(link_to image_tag('/images/footer_logo/inforbus.png', :alt=>"inforbus"), "http://www.inforbus.com" ) logos.collect! { |logo| content_tag(:li, logo.html_safe, :class => li_class.to_s) } content_tag(:ul, logos.join("").html_safe, :class => ul_class.to_s).html_safe end def sort_homework_path(bid, sort, direction) case self.action_name when 'show_courseEx' get_not_batch_homework_homework_attach_index_path(bid_id: bid.id, sort: sort, direction: 'asc') when 'get_not_batch_homework' get_not_batch_homework_homework_attach_index_path(bid_id: bid.id, sort: sort, direction: direction) when 'get_batch_homeworks' get_batch_homeworks_homework_attach_index_path(bid_id: bid.id, sort: sort, direction: direction) when 'get_homeworks' get_homeworks_homework_attach_index_path(bid_id: bid.id, sort: sort, direction: direction) else '#' end end def anonymous_comment_link(bid, course) link = case bid.comment_status when 0 confirm_info = "开启匿评后学生将不能对作品进行提交、修改、删除等操作\n" confirm_info += anonymous_comment_notice(bid,course) confirm_info += '是否确定开启匿评?' link_to '启动匿评', start_anonymous_comment_bid_path(bid), id: "#{bid.id}_start_anonymous_comment", remote: true, :confirm => confirm_info, disable_with: '加载中...' when 1 confirm_info = "关闭匿评后所有同学将不能继续进行匿评,且将公开已提交作品列表\n" confirm_info += anonymous_comment_notice(bid,course) confirm_info += '是否确定关闭匿评?' link_to '关闭匿评', stop_anonymous_comment_bid_path(bid), id: "#{bid.id}_stop_anonymous_comment", remote: true, :confirm => confirm_info when 2 '匿评结束' end content_tag('span', link, id: "#{bid.id}_anonymous_comment") end def anonymous_comment_notice(bid, course) case bid.comment_status when 0 @student_size ||= searchStudent(course).size @homework_size = bid.homeworks.size percent = @homework_size.to_f / (@student_size == 0 ? 1 : @student_size) confirm_info = "目前#{@student_size}个学生,总共提交了#{@homework_size}份作品,占#{number_to_percentage(percent * 100, precision: 1)}\n" when 1 @homework_evaluations = 0 bid.homeworks.map { |homework| @homework_evaluations += homework.homework_evaluations.count} teachers = "(" teacher_members = searchTeacherAndAssistant(course) teacher_members.each do |member| if member == teacher_members.last teachers += member.user_id.to_s + ")" else teachers += member.user_id.to_s + "," end end @has_evaluations = 0 bid.homeworks.map { |homework| @has_evaluations += homework.rates(:quality).where("seems_rateable_rates.rater_id not in #{teachers}").count} percent = @has_evaluations.to_f / (@homework_evaluations == 0 ? 1 : @homework_evaluations) confirm_info = "目前总共分配了#{@homework_evaluations}份匿评作品,已评价#{@has_evaluations}份作品,占#{number_to_percentage(percent * 100, precision: 1)}\n" end confirm_info end def get_technical_title user if user.user_extensions.technical_title == "Professor" || user.user_extensions.technical_title == "教授" technical_title = l(:label_technicl_title_professor) elsif user.user_extensions.technical_title == "Associate professor" || user.user_extensions.technical_title == "副教授" technical_title = l(:label_technicl_title_associate_professor) elsif user.user_extensions.technical_title == "Lecturer" || user.user_extensions.technical_title == "讲师" technical_title = l(:label_technicl_title_lecturer) elsif user.user_extensions.technical_title == "Teaching assistant" || user.user_extensions.technical_title == "助教" technical_title = l(:label_technicl_title_teaching_assistant) end technical_title end # 用户竞赛总数 def user_contest_count @user.favorite_contests.visible.where("is_delete =?", 0).count end # 用户项目总数 def user_project_count @my_projects = @user.projects.visible.where("status != 9") @my_project_total = @my_projects.count end # 用户的课程总数 def user_course_count @my_course_count = @user.syllabuses.count sy_courses = @user.courses.visible.not_deleted syllabus_ids = sy_courses.empty? ? '(-1)' : "(" + sy_courses.map{|course| !course.syllabus_id.nil? && course.syllabus_id}.join(",") + ")" syllabus_members = SyllabusMember.where("user_id = #{@user.id}") syllabus_member_ids = syllabus_members.empty? ? "(-1)" : "(" + syllabus_members.map{|syl_mem| syl_mem.syllabus_id}.join(',') + ")" @join_syllabuses = Syllabus.where("(id in #{syllabus_ids} or id in #{syllabus_member_ids}) and user_id != #{@user.id}") @my_joined_course_count = @join_syllabuses.count @user_course_total = @my_joined_course_count + @my_course_count end # 用户发布的作业数 def user_manage_homework_count tea_courses = @user.courses.visible.not_deleted.select{|course| @user.has_teacher_role(course)} tea_course_ids = tea_courses.map{|course| course.id} @manage_homeworks = HomeworkCommon.where(:course_id => tea_course_ids).count end # 用户收到的作业数 def user_receive_homework_count stu_courses = @user.courses.visible.not_deleted.select{|course| @user.has_student_role(course)} stu_course_ids = stu_courses.empty? ? "(-1)" : "(" + stu_courses.map{|course| course.id}.join(',') + ")" @homeworks = HomeworkCommon.where("course_id in #{stu_course_ids} and publish_time <= '#{Time.now}'").count end # 用户发布的issue数 def issues_author_is_self_count Issue.where(:author_id => @user.id).count end # 用户收到的issue数 def issues_assigned_is_self_count Issue.where( :assigned_to_id => @user.id ).count end def get_user_roll user technical_title = "" case user.user_extensions.identity.to_s when "0" technical_title = get_technical_title user when "1" technical_title = l(:label_account_identity_student) when "2" technical_title = l(:label_account_identity_enterprise) when "3" technical_title = l(:label_account_identity_developer) end technical_title end def ie8? request.env["HTTP_USER_AGENT"] =~ /MSIE 8.0/ end #获取指定资源列表的TAG的集合以及每个TAG的数量,降序排序 def attachment_tag_list attachments tag_list = Hash.new attachments.each do |attachment| attachment.tag_list.map{|tag| tag_list.has_key?(tag) ? tag_list[tag] = tag_list[tag] + 1 : tag_list[tag] = 1} end tag_list.sort {|a,b| b[1]<=>a[1]} end #获取课程资源的TAG云 def get_course_tag_list course all_attachments = course.attachments if User.current.admin? || User.current.allowed_to?(:as_teacher, course) all_attachments = all_attachments.reorder("created_on desc") elsif User.current.member_of_course?(course) member = course.members.where(:user_id => User.current.id).first if member.try(:course_group_id).to_i == 0 all_attachments = all_attachments.where("is_publish = 1 and unified_setting = 1") else not_atta_ids = course.attachment_group_settings.where("course_group_id = #{member.try(:course_group_id)} and publish_time > '#{Time.now}'") not_atta_ids = not_atta_ids.blank? ? "(-1)" : "(" + not_atta_ids.map(&:attachment_id).join(",") + ")" all_attachments = all_attachments.where("is_publish = 1 and attachments.id not in #{not_atta_ids}") end else all_attachments = all_attachments.where("is_publish = 1 and unified_setting = 1") end tag_list = attachment_tag_list all_attachments tag_list end # 获取项目资源的Tag云 def get_project_tag_list project all_attachments = project.attachments.select{|attachment| attachment.is_public? || (attachment.container_type == "Project" && User.current.member_of?(project))|| attachment.author_id == User.current.id } tag_list = attachment_tag_list all_attachments tag_list end # 获取项目fork成员数 def project_fork_count @forked_projects = Project.where(:forked_from_project_id => @project.id) @forked_count = @forked_projects.count end def get_org_subfield_tag_list org_subfield all_attachments = org_subfield.attachments.select{|attachment| attachment.is_public? || (attachment.container_type == "OrgSubfield" && User.current.member_of_org?(org_subfield.organization))|| attachment.author_id == User.current.id } tag_list = attachment_tag_list all_attachments tag_list end #获取匿评相关连接代码 def homework_anonymous_comment (homework, hw_status, user_activity_id = -1) if homework.homework_detail_manual.comment_status == 0 || homework.end_time >= Time.now link = link_to "启动匿评","javascript:void(0)", :class => "wpostOptionLink", :title => "作业截止日期之前不可以启动匿评" elsif homework.student_works.has_committed.count >= 2 && homework.homework_detail_manual#作业份数大于2 case homework.homework_detail_manual.comment_status when 1 link = link_to '启动匿评', Setting.protocol + "://" + Setting.host_name + "/homework_common/" + homework.id.to_s + "/alert_anonymous_comment?hw_status=" + hw_status.to_s + "&user_activity_id=" + user_activity_id.to_s, id: "#{homework.id}_start_anonymous_comment", remote: true, disable_with: '加载中...',:class => 'wpostOptionLink' when 2 link = link_to '关闭匿评', Setting.protocol + "://" + Setting.host_name + "/homework_common/" + homework.id.to_s + "/alert_anonymous_comment?hw_status=" + hw_status.to_s + "&user_activity_id=" + user_activity_id.to_s, id: "#{homework.id}_stop_anonymous_comment", remote: true,:class => 'wpostOptionLink' when 3 # link = link_to "匿评结束","javascript:void(0)", :class => "postOptionLink", :title => "匿评结束" end else link = link_to "启动匿评","javascript:void(0)", :class => "wpostOptionLink", :title => "学生提交作业数大于等于2时才可以启动匿评" end link end #学生根据传入作业确定显示为编辑作品还是新建作品 def student_new_homework homework work = cur_user_works_for_homework homework if work.nil? link_to "提交作品", new_student_work_path(:homework => homework.id),:class => 'fr mr10 work_edit' else if homework.homework_type == 1 && homework.homework_detail_manual && homework.homework_detail_manual.comment_status != 1 #匿评作业,且作业状态不是在开启匿评之前 link_to "作品已交", "javascript:void(0);", :class => 'fr mr10 pr_join_span c_white', :title => "开启匿评后不可修改作品" elsif homework.homework_type == 2 #编程作业修改作品 if homework.homework_detail_manual && homework.homework_detail_manual.comment_status != 1 link_to "作品已交", "javascript:void(0);", :class => 'fr mr10 pr_join_span c_white', :title => "开启匿评后不可修改作品" else link_to "修改作品", new_student_work_path(:homework => homework.id),:class => 'fr mr10 work_edit' end else link_to "修改作品", edit_student_work_path(work.id),:class => 'fr mr10 work_edit' end end end #动态列表中,确定学生是该提交还是进列表 def student_work_activity_submit_status(opt={}) default_opt = {class: 'c_blue'}.merge(opt) is_teacher = User.current.user_extensions && User.current.user_extensions.identity == 0 && User.current.allowed_to?(:add_course, nil, :global => true) homework = default_opt[:homework] work = cur_user_works_for_homework homework if work.nil? && !is_teacher link_to "提交("+homework.student_works.count.to_s+")", new_student_work_path(:homework => homework.id,:host=> Setting.host_course), :class=> default_opt[:class] else link_to "提交("+homework.student_works.count.to_s+")", student_work_index_path(:homework => homework.id,:host=> Setting.host_course), :class=> default_opt[:class] end end # 试卷动态的按钮 def user_for_exercise exercise,is_teacher count = exercise.exercise_users.where(:commit_status => 1, :user_id => exercise.course.student.map(&:student_id)).count if User.current.logged? if User.current.member_of_course?(exercise.course) if is_teacher #老师显示作品数量 link_to "作品 (#{count})".html_safe, student_exercise_list_exercise_path(exercise), :class => "c_blue homepagePostSubmit" else #学生显示提交作品、修改作品等按钮 work = exercise.exercise_users.where("user_id = ?",User.current).first member = exercise.course.members.where(:user_id => User.current.id).first setting_time = exercise_group_setting exercise, member.try(:course_group) if work if work.commit_status > 0 link_to "查看答题(#{count})", exercise.exercise_status < 3 ? exercise_path(exercise,:user_id => User.current.id) : show_student_result_exercise_path(exercise,:user_id => User.current.id), :class => "c_blue homepagePostSubmit" else if setting_time.publish_time < Time.now && setting_time.end_time > Time.now link_to (work.start_at.nil? ? "开始答题(#{count})" : "继续答题(#{count})"), exercise_path(exercise,:user_id => User.current.id), :class => "c_blue homepagePostSubmit" else link_to "查看作品(#{count})".html_safe, student_exercise_list_exercise_path(exercise), :class => "c_blue homepagePostSubmit" end end else if setting_time.publish_time < Time.now && setting_time.end_time > Time.now link_to "开始答题(#{count})", exercise_path(exercise,:user_id => User.current.id), :class => "c_blue homepagePostSubmit" else link_to "查看作品(#{count})".html_safe, student_exercise_list_exercise_path(exercise), :class => "c_blue homepagePostSubmit" end end end else link_to "作品 (#{count})".html_safe, "javascript:void(0)", :class => "c_blue homepagePostSubmit", :onclick => "notice_sure_box('您不是班级成员,不能答题
    请先从老师处获取邀请码后加入班级,再答题')" end else link_to "作品 (#{count})".html_safe, "javascript:void(0)", :class => "c_blue homepagePostSubmit", :onclick => "login_notice_box('#{signin_url_without_domain}');" end end # 问卷动态的按钮 def user_for_poll poll,is_teacher count = poll.poll_users.where(:commit_status => 1, :user_id => poll.course.student.map(&:student_id)).count if User.current.logged? if User.current.member_of_course?(poll.course) if is_teacher #老师显示作品数量 link_to "作品 (#{count})".html_safe, student_poll_list_poll_path(poll), :class => "c_blue homepagePostSubmit" else #学生显示提交作品、修改作品等按钮 work = poll.poll_users.where("user_id = ?",User.current).first member = poll.course.members.where(:user_id => User.current.id).first setting_time = poll_group_setting poll, member.try(:course_group) if work if work.commit_status > 0 link_to "查看答题(#{count})", poll_path(poll,:user_id => User.current.id), :class => "c_blue homepagePostSubmit" elsif setting_time.publish_time < Time.now && setting_time.end_time > Time.now link_to (work.start_at.nil? ? "开始答题(#{count})" : "继续答题(#{count})"), poll_path(poll,:user_id => User.current.id), :class => "c_blue homepagePostSubmit" else link_to "查看作品(#{count})".html_safe, student_poll_list_poll_path(poll), :class => "c_blue homepagePostSubmit" end else if setting_time.publish_time < Time.now && setting_time.end_time > Time.now link_to "开始答题(#{count})", poll_path(poll,:user_id => User.current.id), :class => "c_blue homepagePostSubmit" else link_to "查看作品(#{count})".html_safe, student_poll_list_poll_path(poll), :class => "c_blue homepagePostSubmit" end end end else link_to "作品 (#{count})".html_safe, "javascript:void(0)", :class => "c_blue homepagePostSubmit", :onclick => "notice_sure_box('您不是班级成员,不能答题
    请先从老师处获取邀请码后加入班级,再答题')" end else link_to "作品 (#{count})".html_safe, "javascript:void(0)", :class => "c_blue homepagePostSubmit", :onclick => "login_notice_box('#{signin_url_without_domain}');" end end #根据传入作业确定显示为编辑作品还是新建作品,或者显示作品数量 def user_for_homework_common homework,work if User.current.logged? project = cur_user_projects_for_homework homework if homework.homework_type == 3 member = homework.course.members.where(:user_id => User.current.id).first setting_time = homework_group_setting homework, member.try(:course_group_id) if homework.homework_type == 4 if work.nil? link_to "开始实战", shixun_path(homework.homework_commons_shixuns.shixun), :class => 'edu-default-btn user_bluebg_btn fr mr20 pl7 pr7',:target => "_blank" else myshixun = Myshixun.where(:id => work.myshixun_id).first # is_modify = ShixunModify.where(:myshixun_id => myshixun.try(:id), :shixun_id => myshixun.shixun.try(:id), :status => 1).first link_to "继续实战", shixun_path(myshixun.shixun), :class => "edu-default-btn user_orangebg_btn fr mr20 pl7 pr7", :target => "_blank" # if myshixun && is_modify.blank? # link_to "继续实战", myshixun_game_path(myshixun.current_task, :myshixun_id => myshixun), :class => "edu-default-btn user_orangebg_btn fr mr20 pl7 pr7", :target => "_blank" # elsif myshixun # link_to "继续实战", 'javascript:void(0);', :onclick => "sure_box_redirect('#{myshixun_reset_myshixun_path(myshixun)}', '实训已经更新啦,系统正在为您重置');", :class => "edu-default-btn user_orangebg_btn fr mr20 pl7 pr7" # end end elsif work.nil? && setting_time.end_time >= Time.now if homework.homework_type ==3 && project.nil? && homework.homework_detail_group.base_on_project == 1 link_to "提交作品", "javascript:void(0)", :class => 'edu-default-btn user_bluebg_btn fr mr20 pl7 pr7',:style=>"cursor:not-allowed",:title => '请先关联项目再提交作品' else link_to "提交作品", new_student_work_url_without_domain(homework.id),:class => 'edu-default-btn user_bluebg_btn fr mr20 pl7 pr7' end elsif work.nil? && setting_time.end_time < Time.now if homework.allow_late && !homework.course.is_end if homework.homework_type ==3 && project.nil? && homework.homework_detail_group.base_on_project == 1 link_to "补交作品", "javascript:void(0)", :class => 'edu-default-btn user_orangebg_btn fr mr20 pl7 pr7',:style=>"cursor:not-allowed",:title => '请先关联项目再补交作品' else link_to "补交作品", new_student_work_url_without_domain(homework.id),:class => 'edu-default-btn user_orangebg_btn fr mr20 pl7 pr7' end end elsif work work_ids = "(" + homework.student_works.has_committed.map(&:id).join(",") + ")" if homework.homework_detail_manual && homework.homework_detail_manual.comment_status == 3 && User.current.student_works_evaluation_distributions.where("student_work_id IN #{work_ids}").count > 0 #匿评作业,且作业状态不是在开启匿评之前 link_to "作品匿评", student_work_index_path(:homework => homework.id), :class => 'edu-default-btn user_orangebg_btn fr mr20 pl7 pr7', :title => "开启匿评后不可修改作品" elsif homework.homework_detail_manual && homework.homework_detail_manual.comment_status > 3 link_to "查看作品",student_work_path(work), :class => 'edu-default-btn user_greybg_btn fr mr20 pl7 pr7', :title => "匿评已结束" elsif setting_time.end_time >= Time.now && work.user_id == User.current.id link_to "修改作品", edit_student_work_url_without_domain(work.id),:class => 'edu-default-btn user_orangebg_btn fr mr20 pl7 pr7' else link_to "查看作品", student_work_path(work), :class => 'edu-default-btn user_greybg_btn fr mr20 pl7 pr7', :title => "作业截止后不可修改作品" end end else link_to "作品".html_safe, "javascript:void(0)", :class => "edu-default-btn user_greybg_btn fr mr20 pl7 pr7", :onclick => "login_notice_box('#{signin_url_without_domain}');" end end #根据传入作业确定显示为编辑作品还是新建作品,或者显示作品数量 def user_for_contest_work homework,is_contestant,work count = homework.contestant_works.has_committed.count if User.current.logged? if User.current.member_of_contest?(homework.contest) || User.current.admin? if !is_contestant #老师显示作品数量 link_to "作品(#{count})", contestant_works_path(:work =>homework.id, :tab => 2), :class => "c_blue" else #学生显示提交作品、修改作品等按钮 work = cur_user_works_for_work homework project = cur_user_projects_for_work homework if work.nil? && homework.work_status == 1 if homework.work_type ==3 && project.nil? && homework.work_detail_group.base_on_project link_to "提交作品(#{count})","javascript:void(0)", :class => 'c_grey',:style=>"cursor:not-allowed",:title => '请先关联项目再提交作品' else link_to "提交作品(#{count})", new_contestant_work_path(:work => homework.id),:class => 'c_blue' end elsif work.nil? && homework.work_status > 1 if homework.work_type ==3 && project.nil? && homework.work_detail_group.base_on_project link_to "补交作品(#{count})","javascript:void(0)", :class => 'c_grey',:style=>"cursor:not-allowed",:title => '请先关联项目再补交作品' else link_to "补交作品(#{count})", new_contestant_work_path(:work => homework.id),:class => 'c_blue' end else if homework.work_status == 1 && work.user_id == User.current.id link_to "修改作品(#{count})", edit_contestant_work_path(work.id),:class => 'c_blue' else link_to "查看作品(#{count})", contestant_works_path(:work =>homework.id, :tab => 2), :class => 'c_blue', :title => "不可修改作品" end end end else link_to "作品(#{count})", "javascript:void(0)", :class => "c_blue", :onclick => "notice_sure_box('您不是参赛者,不能提交作品
    请加入竞赛,待审批通过后再提交作品')" end else link_to "作品(#{count})", "javascript:void(0)", :class => "c_blue", :onclick => "login_notice_box('#{signin_url_without_domain}');" end end #根据传入作业确定显示为提交作品、补交作品、查看作品等 def student_for_homework_common homework if User.current.allowed_to?(:as_teacher, homework.course) link_to "查看作品", student_work_index_url_in_org(homework.id, 2), :class => 'hw_btn_green fr mt5', :title => "查看作品", :target => '_blank' else User.current.member_of_course?(homework.course) work = cur_user_works_for_homework homework project = cur_user_projects_for_homework homework if work.nil? && homework.end_time >= Time.now if homework.homework_type ==3 && project.nil? && homework.homework_detail_group.base_on_project == 1 link_to "关联项目", student_work_index_url_in_org(homework.id, 1), :class => 'hw_btn_green fr mt5',:title => '查看分组作业详情', :target => '_blank' else link_to "提交作品", new_student_work_url_without_domain(homework.id),:class => 'hw_btn_green fr mt5', :target => '_blank' end elsif work.nil? && homework.end_time < Time.now if homework.homework_type ==3 && project.nil? && homework.homework_detail_group.base_on_project == 1 link_to "关联项目", student_work_index_url_in_org(homework.id, 1), :class => 'hw_btn_green fr mt5',:title => '查看分组作业详情', :target => '_blank' else link_to "补交作品", new_student_work_url_without_domain(homework.id),:class => 'btn_orange_big fr mt5', :target => '_blank' end else if homework.homework_detail_manual && homework.homework_detail_manual.comment_status == 2 #匿评作业,且作业状态不是在开启匿评之前 link_to "作品匿评", student_work_index_url_in_org(homework.id, 2), :class => 'hw_btn_green fr mt5', :title => "开启匿评后不可修改作品", :target => '_blank' elsif homework.homework_detail_manual && homework.homework_detail_manual.comment_status == 3 link_to "查看作品",student_work_index_url_in_org(homework.id, 2), :class => 'hw_btn_green fr mt5', :title => "匿评已结束", :target => '_blank' elsif homework.homework_type == 2 && homework.end_time >= Time.now#编程作业不能修改作品 link_to "修改作品", new_student_work_url_without_domain(homework.id),:class => 'hw_btn_green fr mt5', :target => '_blank' elsif homework.end_time >= Time.now && work.user_id == User.current.id link_to "修改作品", edit_student_work_url_without_domain(work.id),:class => 'hw_btn_green fr mt5', :target => '_blank' else link_to "查看作品", student_work_index_url_in_org(homework.id, 2), :class => 'hw_btn_green fr mt5', :title => "作业截止后不可修改作品", :target => '_blank' end end end end def relate_project homework,is_teacher,is_in_course,user_activity_id,course_activity if User.current.member_of_course?(homework.course) if is_teacher #link_to "已关联(#{homework.student_work_projects.count})",student_work_index_path(:homework => homework.id),:class => "c_blue" else projects = cur_user_projects_for_homework homework works = cur_user_works_for_homework homework if works.nil? && projects.nil? link_to "关联项目",new_student_work_project_student_work_index_path(:homework => homework.id,:is_in_course=>is_in_course,:user_activity_id=>user_activity_id,:course_activity=>course_activity),remote: true,:class=> 'c_blue', :title=> '请选择分组作业关联的项目' elsif works.nil? link_to "取消关联",cancel_relate_project_student_work_index_path(:homework => homework.id,:is_in_course=>is_in_course,:user_activity_id=>user_activity_id,:course_activity=>course_activity), :confirm => "您确定要取消关联吗?", remote: true,:class => "c_blue", :title=> '取消关联项目' else #link_to "已关联(#{homework.student_work_projects.count})",student_work_index_path(:homework => homework.id),:class => "c_blue" end end end end def student_anonymous_comment homework if homework.homework_detail_manual case homework.homework_detail_manual.comment_status when 1 "未开启匿评".html_safe when 2 "正在匿评中".html_safe when 3 "匿评已结束".html_safe end end end #获取当前用户在指定作业下提交的作业的集合 def cur_user_works_for_homework homework work = homework.student_works.where("user_id = ? && work_status != 0",User.current).first # if homework.homework_type == 3 # pro = homework.student_work_projects.where("user_id = #{User.current.id}").first # if pro.nil? || pro.student_work_id == "" || pro.student_work_id.nil? # work = nil # else # work = StudentWork.find pro.student_work_id # end # end work end #获取当前用户在指定作业下关联的项目的集合 def cur_user_projects_for_homework homework homework.student_works.where("user_id = ? and project_id != 0",User.current).first end #获取当前用户在指定题目下提交的作业的集合 def cur_user_works_for_work homework work = homework.contestant_works.where("user_id = ? && work_status != 0",User.current).first if homework.work_type == 3 pro = homework.contestant_work_projects.where("user_id = #{User.current.id}").first if pro.nil? || pro.contestant_work_id == "" || pro.contestant_work_id.nil? work = nil else work = ContestantWork.find pro.contestant_work_id end end work end #获取当前用户在指定题目下关联的项目的集合 def cur_user_projects_for_work work work.contestant_work_projects.where("user_id = ?",User.current).first end #获取当前作业的提交截止时间/互评截止时间 def cur_homework_end_time homework str = "" if homework.anonymous_comment == 0 && homework.end_time && homework.end_time < Time.now && homework.homework_detail_manual str = "互评截止:#{format_date homework.homework_detail_manual.evaluation_end}" else str = "提交截止:#{homework.end_time ? (format_date homework.end_time) : '       --       '}" end str end def file_preview_tag(file, html_options={}) if %w(pdf pptx doc docx xls xlsx).any?{|x| file.filename.downcase.end_with?(x)} link_to '预览', download_named_attachment_path(file.id, file.filename, preview: true),html_options end end def file_preview_eye(file, html_options={}) if %w(pdf pptx doc docx xls xlsx).any?{|x| file.filename.downcase.end_with?(x)} link_to '', User.current.logged? ? download_named_attachment_path(file.id, file.filename, preview: true) : signin_url_without_domain, html_options end end #将文本内的/n转换为
    def text_format text text.gsub("&","&").gsub("<","<").gsub(">",">").gsub("\n","
    ").html_safe end #评分规则显示 def scoring_rules late_penalty,homework_id,is_teacher,absence_penalty=nil if absence_penalty if late_penalty.to_i == 0 && absence_penalty.to_i == 0 notice = "尚未设置评分规则" if is_teacher notice += ",请 " + link_to("设置",edit_homework_common_path(homework_id),:class => "c_green") end elsif late_penalty.to_i != 0 && absence_penalty.to_i == 0 notice = "迟交扣#{late_penalty}分,缺评扣分未设置" elsif late_penalty.to_i == 0 && absence_penalty.to_i != 0 notice = "迟交扣分未设置,缺评一个作品扣#{absence_penalty}分" elsif late_penalty.to_i != 0 && absence_penalty.to_i != 0 notice = "迟交扣#{late_penalty}分,缺评一个作品扣#{absence_penalty}分" end else if late_penalty.to_i == 0 notice = "尚未设置评分规则" if is_teacher notice += ",请 " + link_to("设置",edit_homework_common_path(homework_id),:class => "c_green") end else notice = "迟交扣#{late_penalty}分" end end notice.html_safe end #老师C语言的标准代码 def c_stantard_code_teacher "// 老师您好!这是一个C语言的样例程序 // 程序功能:输入两个整数,输出两者之和 // 测试集合:老师可以给出多组测试集,例如: // 输入1和2,输出3 // 输入3和4,输出7 // ... ... // 系统将根据您给出的测试集对学生代码进行自动评分 // 特别提醒:程序采用命令行传参方式,输入通过argv传入 // 否则您的作业标准代码将不能通过测试 #include //引用必须头文件 int main(int argc, char** argv) { int a = atoi(argv[1]); //将第一个输入转成整型 int b = atoi(argv[2]); //将第二个输入转换为整型 printf(\"%d\",a+b); //输出a+b return 0; }".html_safe end #老师C++语言的标准代码 def c_stantard_code_teacher_ "// 老师您好!这是一个C++语言的样例程序 // 程序功能:输入两个整数,输出两者之和 // 测试集合:老师可以给出多组测试集,例如: // 输入1和2,输出3 // 输入3和4,输出7 // ... ... // 系统将根据您给出的测试集对学生代码进行自动评分 // 特别提醒:程序采用命令行传参方式,输入通过argv传入 // 否则您的作业标准代码将不能通过测试 #include //引用必须头文件 #include using namespace std; int main(int argc, char** argv){ int a = atoi(argv[1]); //将第一个输入转成整型 int b = atoi(argv[2]); //将第二个输入转换为整型 cout< //引用必须头文件 int main(int argc, char** argv) { int a = atoi(argv[1]); //将第一个输入转成整型 int b = atoi(argv[2]); //将第二个输入转换为整型 printf(\"%d\",a+b); //输出a+b return 0; }".html_safe end #学生C++语言的标准代码 def c_stantard_code_student_ "// 同学好!这是一个C++语言的样例程序 // 程序功能:输入两个整数,输出两者之和 // 测试集合:老师可以给出多组测试集,例如: // 输入1和2,输出3 // 输入3和4,输出7 // ... ... // 系统将根据您给出的测试集对学生代码进行自动评分 // 特别提醒:程序采用命令行传参方式,输入通过argv传入 // 否则您的作业标准代码将不能通过测试 #include //引用必须头文件 #include using namespace std; int main(int argc, char** argv){ int a = atoi(argv[1]); //将第一个输入转成整型 int b = atoi(argv[2]); //将第二个输入转换为整型 cout<&1 | base64) if [ -z \"$compileResult\" ]; then compileResult=$(echo -n \"compile successfully\" | base64) fi } compile $1" end def execute_command "execute(){ #执行命令 executeCommand=\"EXECUTECOMMAND\" #执行文件名 sourceClassName=${sourceClassNames[$1 - 1]} challengeStage=$1 output='' i=0 while [[ i -lt ${#ins[*]} ]]; do #执行,并拼接执行结果 result=$(echo \"${ins[$i]}\" | base64 -d | $executeCommand $sourceClassName 2>&1 | base64) #拼接输出结果 output=$output\\\"$result\\\", let i++ done output=\"[${output%?}]\" } execute $1 " end def challenge_file_path "#用户打开的文件名,之所以传过来这个,是因为可以从这个里面提取出来执行文件名 challengeProgramNames=(CHALLENGEPROGRAMNAMES)" end def import_ke(default_opt={}) opt = {enable_at: false, prettify: false, init_activity: false}.merge default_opt ss = '' unless Setting.at_enabled? opt[:enable_at] = false end ss += javascript_include_tag("/assets/kindeditor/kindeditor",'/assets/kindeditor/pasteimg') if opt[:enable_at] ss += javascript_include_tag('/assets/kindeditor/at/jquery.caret.min.js', '/assets/kindeditor/at/jquery.atwho.js', '/assets/kindeditor/at/config.js') ss += stylesheet_link_tag("/assets/kindeditor/at/jquery.atwho.css") end if opt[:prettify] ss += javascript_include_tag 'prettify' ss += stylesheet_link_tag 'prettify' end if opt[:init_activity] ss += javascript_include_tag "create_kindeditor" end ss.html_safe end #竞赛动态的更新 def update_contest_activity type, id contest_activity = ContestActivity.where("contest_act_type=? and contest_act_id =?", type.to_s, id).first if contest_activity contest_activity.updated_at = Time.now contest_activity.save end end #课程动态的更新 def update_course_activity type, id course_activity = CourseActivity.where("course_act_type=? and course_act_id =?", type.to_s, id).first if course_activity course_activity.updated_at = Time.now course_activity.save end end #首页动态更新 def update_user_activity type, id =begin user_activity = UserActivity.where("act_type=? and act_id =?", type.to_s, id).first if user_activity user_activity.updated_at = Time.now user_activity.save end =end end #项目动态更新 def update_forge_activity type, id forge_activity = ForgeActivity.where("forge_act_type=? and forge_act_id=?", type.to_s, id).first if forge_activity forge_activity.updated_at = Time.now forge_activity.save end end #组织动态更新 def update_org_activity type , id =begin org_activity = OrgActivity.where("org_act_type=? and org_act_id =?", type.to_s, id).first if org_activity org_activity.updated_at = Time.now org_activity.save end =end end #个人动态更新 def update_principal_activity type, id =begin principal_activity = PrincipalActivity.where("principal_act_type=? and principal_act_id =?", type.to_s, id).first if principal_activity principal_activity.updated_at = Time.now principal_activity.save end =end end #项目按更新时间排序 def project_sort_update projects unless projects.empty? project_ids = '('+projects.map{|pro|pro.project_id}.join(',')+')' sort_projects = ForgeActivity.find_by_sql("SELECT MAX(updated_at) AS updated_at,user_id, project_id FROM forge_activities WHERE project_id IN #{project_ids} GROUP BY project_id ORDER BY MAX(updated_at) DESC") #sort_projects = sort_projects.sort_by{|sp| (!sp.project.project_score.nil? && !sp.project.project_score.commit_time.nil?) ? '' : sp.project.project_score.commit_time} return sort_projects end end def project_sort_first projects unless projects.empty? project_ids = '('+projects.map{|pro|pro.project_id}.join(',')+')' sort_projects = ForgeActivity.find_by_sql("SELECT updated_at,user_id, project_id FROM forge_activities WHERE project_id IN #{project_ids} ORDER BY updated_at DESC limit 1") return sort_projects end end end def user_url_in_org(user_id) Setting.protocol + "://" + Setting.host_name + "/users/" + user_id.to_s end def project_issues_url_in_org(project_id) Setting.protocol + "://" + Setting.host_name + "/projects/" + project_id.to_s + "/issues" end def issue_url_in_org(id) Setting.protocol + "://" + Setting.host_name + "/issues/" + id.to_s end def project_boards_url_in_org(id) Setting.protocol + "://" + Setting.host_name + "/projects/" + id.to_s + "/boards" end def board_message_url_in_org(board_id, message_id) Setting.protocol + "://" + Setting.host_name + "/boards/" + board_id.to_s + "/topics/" + message_id.to_s end def project_url_in_org(id) Setting.protocol + "://" + Setting.host_name + "/projects/" + id.to_s end def homework_common_index_url_in_org(course_id) Setting.protocol + "://" + Setting.host_name + "/homework_common?course=" + course_id.to_s end def student_work_index_url_in_org(homework_id, tab = 1, is_focus = '', show_work_id = '') if is_focus != '' Setting.protocol + "://" + Setting.host_name + "/student_work?homework=" + homework_id.to_s + "&tab=" + tab.to_s + "&is_focus=" + is_focus.to_s elsif show_work_id != '' Setting.protocol + "://" + Setting.host_name + "/student_work?homework=" + homework_id.to_s + "&tab=" + tab.to_s + "&show_work_id=" + show_work_id.to_s else Setting.protocol + "://" + Setting.host_name + "/student_work?homework=" + homework_id.to_s + "&tab=" + tab.to_s end end def contestant_work_index_url_in_org(work_id, tab = 1, is_focus = '', show_work_id = '') if is_focus != '' Setting.protocol + "://" + Setting.host_name + "/contestant_work?work=" + work_id.to_s + "&tab=" + tab.to_s + "&is_focus=" + is_focus.to_s elsif show_work_id != '' Setting.protocol + "://" + Setting.host_name + "/contestant_work?work=" + work_id.to_s + "&tab=" + tab.to_s + "&show_work_id=" + show_work_id.to_s else Setting.protocol + "://" + Setting.host_name + "/contestant_work?work=" + work_id.to_s + "&tab=" + tab.to_s end end def course_url_in_org(course_id) Setting.protocol + "://" + Setting.host_name + "/courses/" + course_id.to_s end def user_watchlist_url_in_org(id) Setting.protocol + "://" + Setting.host_name + "/users/" + id.to_s + "/user_watchlist" end def user_fanslist_url_in_org(id) Setting.protocol + "://" + Setting.host_name + "/users/" + id.to_s + "/user_fanslist" end def user_blogs_url_in_org(user_id) Setting.protocol + "://" + Setting.host_name + "/users/" + user_id.to_s + "/blogs" end def feedback_url_in_org(user_id) Setting.protocol + "://" + Setting.host_name + "/users/" + user_id.to_s + "/user_newfeedback" end def user_activities_url_in_org(user_id) Setting.protocol + "://" + Setting.host_name + "/users/" + user_id.to_s + "/user_activities" end def course_news_index_url_in_org(course_id) Setting.protocol + "://" + Setting.host_name + "/courses/" + course_id.to_s + "/news" end def news_url_in_org(news_id) Setting.protocol + "://" + Setting.host_name + "/news/" + news_id.to_s end def course_boards_url_in_org(course_id) Setting.protocol + "://" + Setting.host_name + "/courses/" + course_id.to_s + "/boards" end def logout_url_without_domain Setting.protocol + "://" + Setting.host_name + "/logout" end def signin_url_without_domain Setting.protocol + "://" + Setting.host_name + "/login?login=true" end def register_url_without_domain Setting.protocol + "://" + Setting.host_name + "/login?login=false" end def new_student_work_url_without_domain(homework_id) Setting.protocol + "://" + Setting.host_name + "/student_work/new?homework=" + homework_id.to_s end def edit_student_work_url_without_domain(homework_id) Setting.protocol + "://" + Setting.host_name + "/student_work/" + homework_id.to_s + "/edit" end def download_named_attachment_url_without_domain(id, filename, option={}) attachment_id = (Attachment === id ? id.id : id) Setting.protocol + "://" + Setting.host_name + "/attachments/download/" + attachment_id.to_s + "/" + filename end def named_attachment_url_without_domain(id, filename, option={}) attachment_id = (Attachment === id ? id.id : id) Setting.protocol + "://" + Setting.host_name + "/attachments/" + attachment_id.to_s + "/" + filename end #判断是否为默认的组织栏目 def is_default_field? field (field.name == 'activity' || field.name == 'course' || field.name == 'project' ) && field.field_type == 'default' end def host_with_protocol return Setting.protocol + "://" + Setting.host_name end def secdomain_with_protocol secdomain return Setting.protocol + "://" + secdomain + ".trustie.net" end #根据回复类型获取回复 def get_reply_by_type type, reply_id reply = nil case type when 'HomeworkCommon', 'Work', 'GraduationTopic', 'GraduationTask' reply = JournalsForMessage.find reply_id when 'JournalsForMessage' reply = JournalsForMessage.find reply_id when 'Message' reply = Message.find reply_id when 'BlogComment' reply = BlogComment.find reply_id when 'OrgDocumentComment' reply = OrgDocumentComment.find reply_id when 'News','Comment' reply = Comment.find reply_id when 'Issue', 'TrainingTask' reply = Journal.find reply_id when 'Journal' reply = Journal.find reply_id when 'Syllabus' reply = JournalsForMessage.find reply_id when 'Memo' reply = Memo.find reply_id when 'Challenge' reply = Discuss.find reply_id end reply end #获取不包含子节点的回复(前三个) def get_no_children_comments comments result = {} no_children_comments = [] count = 0 three_more = false comments.each do |comment| if comment.children.blank? count = count + 1 if count > 3 three_more = true end break if count > 3 no_children_comments << comment end end result[:three_more] = three_more result[:no_children_comments] = no_children_comments result end #获取不包含子节点的回复(所有) def get_no_children_comments_all comments no_children_comments = [] comments.each do |comment| if comment.children.blank? no_children_comments << comment end end no_children_comments end #获取回复的所有父节点 def get_reply_parents parents_rely, comment unless comment.parent.nil? parents_rely << comment.parent get_reply_parents parents_rely, comment.parent end parents_rely end #获取回复的所有父节点(不包括根节点) def get_reply_parents_no_root parents_rely, comment if !comment.parent.nil? && !comment.parent.parent.nil? parents_rely << comment.parent get_reply_parents_no_root parents_rely, comment.parent end parents_rely end def get_all_children_ex result, jour if jour.kind_of? Message jour.children.includes(:author, :praise_tread_cache).each do |jour_child| result << jour_child get_all_children_ex result, jour_child end elsif (jour.kind_of? JournalsForMessage) || (jour.kind_of? BlogComment) || (jour.kind_of? OrgDocumentComment) jour.children.each do |jour_child| result << jour_child get_all_children_ex result, jour_child end end result end #获取所有子节点 def get_all_children result, jour if jour.kind_of? Message jour.children.includes(:author, :praise_tread_cache).each do |jour_child| result << jour_child get_all_children_ex result, jour_child end elsif (jour.kind_of? JournalsForMessage) || (jour.kind_of? BlogComment) || (jour.kind_of? OrgDocumentComment) jour.children.each do |jour_child| result << jour_child get_all_children_ex result, jour_child end end if jour.respond_to?(:created_on) result.sort! { |a,b| b.created_on <=> a.created_on } elsif jour.respond_to?(:created_at) result.sort! { |a,b| b.created_at <=> a.created_at } end result end #获取该节点所在的帖子 def get_root_parent comment while comment.parent comment = comment.parent end comment end #将有置顶属性的提到数组前面 def sort_by_sticky topics tmpTopics = [] tmpIndex = 0 topics.each do |topic| if topic.sticky == 1 tmpTopics[tmpIndex] = topic tmpIndex = tmpIndex + 1 end end topics.each do |topic| if topic.sticky == 0 tmpTopics[tmpIndex] = topic tmpIndex = tmpIndex + 1 end end return tmpTopics end #按人气排序的时候 相同的人气必须按某种时间顺序排序 有置顶属性 def sortby_time_countcommon_hassticky topics,sortstr tmpTopics = [] tmpTopics = topics tStart = -1 tEnd = -1 tmpTopics_1 = [] tmpIndex = 0 tmpTopics.each_with_index do |topic,index| if topic.sticky == 0 if tStart == -1 if (index != tmpTopics.count-1) && (topic[:infocount] == tmpTopics[index+1][:infocount]) tStart = index end else if ((topic[:infocount] == tmpTopics[index-1][:infocount]) && ((index != tmpTopics.count-1) && (topic[:infocount] == tmpTopics[index+1][:infocount]))) tEnd = index else if (topic[:infocount] == tmpTopics[index-1][:infocount]) tEnd = index end if tEnd > tStart for i in tStart..tEnd tmpTopics_1[tmpIndex] = tmpTopics[i] tmpIndex = tmpIndex + 1 end if sortstr == "created_at" tmpTopics_1 = tmpTopics_1.sort{|x,y| y[:created_at].to_i <=> x[:created_at].to_i } elsif sortstr == "created_on" tmpTopics_1 = tmpTopics_1.sort{|x,y| y[:created_on].to_i <=> x[:created_on].to_i } elsif sortstr == "updated_at" tmpTopics_1 = tmpTopics_1.sort{|x,y| y[:updated_at].to_i <=> x[:updated_at].to_i } elsif sortstr == "updated_on" tmpTopics_1 = tmpTopics_1.sort{|x,y| y[:updated_on].to_i <=> x[:updated_on].to_i } end tmpIndex = 0 for i in tStart..tEnd tmpTopics[i] = tmpTopics_1[tmpIndex] tmpIndex = tmpIndex + 1 end end tStart = -1 tEnd = -1 tmpTopics_1 = [] tmpIndex = 0 end end end end return tmpTopics end #按人气排序的时候 相同的人气必须按某种时间顺序排序 无置顶属性 def sortby_time_countcommon_nosticky topics,sortstr tmpTopics = [] tmpTopics = topics tStart = -1 tEnd = -1 tmpTopics_1 = [] tmpIndex = 0 tmpTopics.each_with_index do |topic,index| if tStart == -1 if (index != tmpTopics.count-1) && (topic[:infocount] == tmpTopics[index+1][:infocount]) tStart = index end else if ((topic[:infocount] == tmpTopics[index-1][:infocount]) && ((index != tmpTopics.count-1) && (topic[:infocount] == tmpTopics[index+1][:infocount]))) tEnd = index else if (topic[:infocount] == tmpTopics[index-1][:infocount]) tEnd = index end if tEnd > tStart for i in tStart..tEnd tmpTopics_1[tmpIndex] = tmpTopics[i] tmpIndex = tmpIndex + 1 end if sortstr == "created_at" tmpTopics_1 = tmpTopics_1.sort{|x,y| y[:created_at].to_i <=> x[:created_at].to_i } elsif sortstr == "created_on" tmpTopics_1 = tmpTopics_1.sort{|x,y| y[:created_on].to_i <=> x[:created_on].to_i } elsif sortstr == "updated_at" tmpTopics_1 = tmpTopics_1.sort{|x,y| y[:updated_at].to_i <=> x[:updated_at].to_i } elsif sortstr == "updated_on" tmpTopics_1 = tmpTopics_1.sort{|x,y| y[:updated_on].to_i <=> x[:updated_on].to_i } end tmpIndex = 0 for i in tStart..tEnd tmpTopics[i] = tmpTopics_1[tmpIndex] tmpIndex = tmpIndex + 1 end end tStart = -1 tEnd = -1 tmpTopics_1 = [] tmpIndex = 0 end end end return tmpTopics end def strip_html(text,len=0,endss="...") ss = "" if !text.nil? && text.length>0 ss=text.gsub(/<\/?.*?>/, '').strip ss = ss.gsub(/ */, ' ') if len > 0 && ss.length > len ss = ss[0, len] + endss elsif len > 0 && ss.length <= len ss = ss #ss = truncate(ss, :length => len) end end return ss end def message_content content content = (strip_html content).strip content = content.gsub(/\s+/, " ") if content.gsub(" ", "") == "" content = "[非文本消息]" end content end def get_work_index(hw,is_teacher) if is_teacher works = hw.contest.works.order("created_at asc") else works = hw.contest.works.where("publish_time <= '#{Date.today}'").order("created_at asc") end hw_ids = works.map{|hw| hw.id} if !works.empty? index = hw_ids.index(hw.id).to_i return index end def get_poll_index(poll, course, is_teacher) if is_teacher polls = course.polls.order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC") elsif User.current.member_of_course?(course) member = course.members.where(:user_id => User.current.id).first if member.try(:course_group_id).to_i == 0 polls = course.polls.where("publish_time <= '#{Time.now}' and unified_setting = 1").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC") else not_poll_ids = course.poll_group_settings.where("course_group_id = #{member.try(:course_group_id)} and (publish_time > '#{Time.now}' or publish_time is null)") not_poll_ids = not_poll_ids.blank? ? "(-1)" : "(" + not_poll_ids.map(&:poll_id).join(",") + ")" polls = course.polls.where("publish_time <= '#{Time.now}' and id not in #{not_poll_ids}").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC") end else polls = course.polls.where("publish_time <= '#{Time.now}'").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC") end poll_ids = polls.map{|poll| poll.id} if !polls.blank? index = poll_ids.length - 1 - poll_ids.index(poll.id).to_i return index end def get_ex_index(exercise, course, is_teacher) if is_teacher exercises = course.exercises.order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC") elsif User.current.member_of_course?(course) member = course.members.where(:user_id => User.current.id).first if member.try(:course_group_id).to_i == 0 exercises = course.exercises.where("publish_time <= '#{Time.now}' and unified_setting = 1").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC") else not_exercise_ids = course.exercise_group_settings.where("course_group_id = #{member.try(:course_group_id)} and (publish_time > '#{Time.now}' or publish_time is null)") not_exercise_ids = not_exercise_ids.blank? ? "(-1)" : "(" + not_exercise_ids.map(&:exercise_id).join(",") + ")" exercises = course.exercises.where("publish_time <= '#{Time.now}' and id not in #{not_exercise_ids}").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC") end else exercises = course.exercises.where("publish_time <= '#{Time.now}'").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC") end ex_ids = exercises.map{|ex| ex.id} if !exercises.blank? index = ex_ids.length - 1 - ex_ids.index(exercise.id).to_i return index end def get_task_index task, is_teacher if is_teacher tasks = task.course.graduation_tasks.order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC") else tasks = task.course.graduation_tasks.where("publish_time <= '#{Time.now}'").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC") end task_ids = tasks.pluck(:id) index = task_ids.length - task_ids.index(task.id).to_i return index end def get_hw_index(hw,is_teacher,type=0) homework_commons = hw.course.homework_commons course = hw.course category_str = hw.course_homework_category_id.nil? ? "is null" : "= #{hw.course_homework_category_id}" if is_teacher if type != 0 homeworks = homework_commons.where("homework_commons.homework_type = #{type} and course_homework_category_id #{category_str}").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC") else homeworks = homework_commons.where("course_homework_category_id #{category_str}").order("publish_time desc") end elsif User.current.member_of_course?(course) member = course.members.where(:user_id => User.current.id).first if member.try(:course_group_id).to_i == 0 if type != 0 homeworks = homework_commons.where("course_homework_category_id #{category_str} and homework_commons.homework_type = #{type} and publish_time <= '#{Time.now}' and unified_setting = 1").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC") else homeworks = homework_commons.where("course_homework_category_id #{category_str} and publish_time <= '#{Time.now}' and unified_setting = 1").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC") end else not_homework_ids = course.homework_group_settings.where("course_group_id = #{member.try(:course_group_id)} and (publish_time > '#{Time.now}' or publish_time is null)") not_homework_ids = not_homework_ids.blank? ? "(-1)" : "(" + not_homework_ids.map(&:homework_common_id).join(",") + ")" if type != 0 homeworks = homework_commons.where("course_homework_category_id #{category_str} and homework_commons.homework_type = #{type} and publish_time <= '#{Time.now}' and id not in #{not_homework_ids}").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC") else homeworks = homework_commons.where("course_homework_category_id #{category_str} and publish_time <= '#{Time.now}' and id not in #{not_homework_ids}").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC") end end else if type != 0 homeworks = homework_commons.where("course_homework_category_id #{category_str} and homework_commons.homework_type = #{type} and publish_time <= '#{Time.now}'").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC") else homeworks = homework_commons.where("course_homework_category_id #{category_str} and publish_time <= '#{Time.now}'").order("IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC") end end hw_ids = homeworks.map{|hw| hw.id} if !homeworks.blank? index = hw_ids.blank? ? 1 : (hw_ids.length - 1 - hw_ids.index(hw.id).to_i) return index end def get_hw_status homework_common str = "" if homework_common.homework_detail_manual if homework_common.homework_detail_manual.comment_status == 0 && homework_common.publish_time.nil? str += '未发布' elsif homework_common.homework_detail_manual.comment_status == 0 str += '未发布' elsif homework_common.homework_detail_manual.comment_status == 1 if homework_common.anonymous_comment == 0 str += '未开启匿评' else str += '匿评已禁用' end if homework_common.end_time >= Time.now str += '作品提交中' elsif homework_common.end_time < Time.now && homework_common.anonymous_comment == 1 && User.current.allowed_to?(:as_teacher, homework_common.course) str += '教师评阅中' else str += '作品补交中' end elsif homework_common.homework_detail_manual.comment_status == 2 if homework_common.anonymous_comment == 0 str += '匿评中' else str += '匿评已禁用' end str += '教师评阅中' elsif homework_common.homework_detail_manual.comment_status == 3 if homework_common.anonymous_comment == 0 str += '匿评已结束' else str += '匿评已禁用' end str += '教师评阅中' end end str end def get_cw_status contest_work str = "" if contest_work.work_status == 0 && contest_work.publish_time.nil? str += '挂起' elsif contest_work.work_status == 0 str += '未发布' elsif contest_work.work_status == 1 if Time.parse(contest_work.end_time.to_s).strftime("%Y-%m-%d") >= Time.now.strftime("%Y-%m-%d") str += '作品提交中' else str += '作品补交中' end elsif contest_work.work_status == 2 str += '提交已截止' elsif contest_work.work_status == 3 str += '在线评审中' elsif contest_work.work_status == 4 str += '评审已截止' end str end def get_group_member_names user_ids result = "" user_ids.each do |user_id| user = User.where(:id => user_id).first unless user.nil? if result != "" result += "、#{user.show_name}" else result += user.show_name end end end result end def get_contest_group_member_names work result = "" unless work.nil? work.contestant_work_projects.each do |member| user = User.where(:id => member.user_id).first unless user.nil? if result != "" result += "、#{user.show_name}" else result += user.show_name end end end end result end def course_syllabus_option syllabus_id = nil syllabus_members = SyllabusMember.where("user_id = #{User.current.id}") syllabus_ids = syllabus_members.map{|mem| mem.syllabus_id} if syllabus_id && !syllabus_ids.include?(syllabus_id) syllabus_ids << syllabus_id end syllabus_ids = syllabus_ids.empty? ? "(-1)" : "(" + syllabus_ids.join(',') + ")" syllabuses = Syllabus.where("id in #{syllabus_ids}") type = [] option1 = [] option1 << "请选择课程" option1 << 0 type << option1 unless syllabuses.empty? syllabuses.each do |syllabus| option = [] option << syllabus.title option << syllabus.id type << option end end type end def create_polls_tiding poll, members tid_str = "" if poll.tidings.where(:parent_container_type => "PollPublish", :user_id => poll.course.teachers.map(&:user_id)).count == 0 poll.course.teachers.find_each do |member| tid_str += "," if tid_str != "" tid_str += "(#{member.user_id}, #{poll.user_id}, #{poll.id}, 'Poll', #{poll.id}, 'PollPublish', #{poll.course.id}, 'Course', 0, 'Poll', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')" end end members.find_each do |student| tid_str += "," if tid_str != "" tid_str += "(#{student.user_id}, #{poll.user_id}, #{poll.id}, 'Poll', #{poll.id}, 'PollPublish', #{poll.course_id}, 'Course', 0, 'Poll', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')" end if tid_str != "" tid_sql = "insert into tidings (user_id, trigger_user_id, container_id, container_type, parent_container_id, parent_container_type, belong_container_id, belong_container_type, viewed, tiding_type, created_at, updated_at) values" + tid_str ActiveRecord::Base.connection.execute tid_sql end end def create_polls_list poll str = "" poll.course.student.find_each do |student| str += "," if str != "" str += "(#{student.user_id},#{poll.id}, 0, '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')" end if str != "" sql = "insert into poll_users (user_id, poll_id, commit_status, created_at, updated_at) values" + str ActiveRecord::Base.connection.execute sql end end def create_exercises_tiding exercise, members tid_str = "" if exercise.tidings.where(:parent_container_type => "ExercisePublish", :user_id => exercise.course.teachers.map(&:user_id)).count == 0 exercise.course.teachers.find_each do |member| tid_str += "," if tid_str != "" tid_str += "(#{member.user_id}, #{exercise.user_id}, #{exercise.id}, 'Exercise', #{exercise.id}, 'ExercisePublish', #{exercise.course.id}, 'Course', 0, 'Exercise', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')" end end members.find_each do |student| tid_str += "," if tid_str != "" tid_str += "(#{student.user_id}, #{exercise.user_id}, #{exercise.id}, 'Exercise', #{exercise.id}, 'ExercisePublish', #{exercise.course_id}, 'Course', 0, 'Exercise', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')" end if tid_str != "" tid_sql = "insert into tidings (user_id, trigger_user_id, container_id, container_type, parent_container_id, parent_container_type, belong_container_id, belong_container_type, viewed, tiding_type, created_at, updated_at) values" + tid_str ActiveRecord::Base.connection.execute tid_sql end end def create_exercises_list exercise str = "" exercise.course.student.find_each do |student| str += "," if str != "" str += "(#{student.user_id}, #{exercise.id}, 0, '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')" end if str != "" sql = "insert into exercise_users (user_id, exercise_id, commit_status, created_at, updated_at) values" + str ActiveRecord::Base.connection.execute sql end end def create_works_tiding homework, members tid_str = "" if homework.tidings.where(:parent_container_type => "HomeworkPublish", :user_id => homework.course.teachers.map(&:user_id)).count == 0 homework.course.teachers.find_each do |member| tid_str += "," if tid_str != "" tid_str += "(#{member.user_id}, #{homework.user_id}, #{homework.id}, 'HomeworkCommon', #{homework.id}, 'HomeworkPublish', #{homework.course.id}, 'Course', 0, 'HomeworkCommon', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')" end end members.find_each do |student| tid_str += "," if tid_str != "" tid_str += "(#{student.user_id}, #{homework.user_id}, #{homework.id}, 'HomeworkCommon', #{homework.id}, 'HomeworkPublish', #{homework.course_id}, 'Course', 0, 'HomeworkCommon', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')" end if tid_str != "" tid_sql = "insert into tidings (user_id, trigger_user_id, container_id, container_type, parent_container_id, parent_container_type, belong_container_id, belong_container_type, viewed, tiding_type, created_at, updated_at) values" + tid_str ActiveRecord::Base.connection.execute tid_sql end end def create_works_list homework if homework.course.present? && homework.course.student.count > 0 str = "" name = homework.name name_str = name + "的作品提交" homework.course.student.each do |student| str += "," if str != "" str += "('#{name_str}',#{homework.id},#{student.user_id}, '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')" end if str != "" sql = "insert into student_works (name, homework_common_id, user_id, created_at, updated_at) values" + str ActiveRecord::Base.connection.execute sql end end end def add_to_homework_bank_f homework homework_bank = HomeworkBank.new(:name => homework.name, :description => homework.description, :user_id => User.current.id, :homework_type => homework.homework_type, :quotes => 1, :is_public => 0, :applicable_syllabus => homework.course.course_list_name, :homework_common_id => homework.id, :reference_answer => homework.reference_answer, :course_list_id => homework.course.course_list_id) if homework.homework_type == 2 && homework.homework_detail_programing homework_bank.language = homework.homework_detail_programing.language homework.homework_tests.each_with_index do |homework_test| homework_bank.homework_bank_tests << HomeworkBankTest.new( input: homework_test.input, output: homework_test.output ) end homework.homework_samples.each_with_index do |homework_test| homework_bank.homework_bank_samples << HomeworkBankSample.new( input: homework_test.input, output: homework_test.output ) end elsif homework.homework_type == 3 && homework.homework_detail_group homework_bank.min_num = homework.homework_detail_group.min_num homework_bank.max_num = homework.homework_detail_group.max_num homework_bank.base_on_project = homework.homework_detail_group.base_on_project end homework.attachments.each do |attachment| att = attachment.copy att.container_id = nil att.container_type = nil att.author_id = homework_bank.user_id att.copy_from = attachment.id att.save homework_bank.attachments << att end homework_bank end # 获取项目动态更新时间 def get_forge_act_message(act, type) forge_act = ForgeActivity.where(:forge_act_id => act.id, :forge_act_type => type).first format_time(forge_act.nil? ? act.created_on : forge_act.try(:updated_at)) end #作业类型 def homework_type_option type = [] option0 = [] option0 << "请选择作业类型" option0 << 0 option1 = [] option1 << "普通作业" option1 << 1 option2 = [] option2 << "编程作业" option2 << 2 option3 = [] option3 << "分组作业" option3 << 3 type << option0 type << option1 type << option2 type << option3 type end # 竞赛题目类型 def work_type_option type = [] option0 = [] option0 << "请选择竞赛类型" option0 << 0 option1 = [] option1 << "普通竞赛" option1 << 1 # option2 = [] # option2 << "编程作业" # option2 << 2 option3 = [] option3 << "团队竞赛" option3 << 3 type << option0 type << option1 #type << option2 type << option3 type end # 当前用户可见的某竞赛下的作品数 def visable_contest_work contest if User.current.admin? || User.current.admin_of_contest?(contest) work_num = contest.works.count else work_num = contest.works.where("work_status > 0").count end work_num end def searchstudent_by_name users, name mems = [] if name != "" name = name.to_s.downcase users.each do |m| username = m.lastname.to_s.downcase + m.firstname.to_s.downcase if(m.login.to_s.downcase.include?(name) || m.user_extensions[:student_id].to_s.downcase.include?(name) || username.include?(name)) mems << m end end else mems = users end mems end def contest_feedback_count @contest.journals_for_messages.where('m_parent_id IS NULL').count end def add_reply_adapter obj, options #modify by nwb #添加对课程留言的支持 #留言回复应该不关系其所属的Class,而关心的是其所属的父留言 case obj.jour_type when 'Principal' obj.jour.add_jour(nil, nil, nil, options) when 'Project' Project.add_new_jour(nil, nil, obj.jour_id, options) when 'Course' Course.add_new_jour(nil, nil, obj.jour_id, options) when 'Contest' Contest.add_new_jour(nil, nil, obj.jour_id, options) #when 'Bid' # obj.jour.add_jour(nil, nil, nil, options) #when 'Contest' # obj.jour.add_jour(nil, nil, obj.jour_id, options) #when 'Softapplication' # obj.jour.add_jour(nil, nil, obj.jour_id, options) #when 'HomeworkAttach' # obj.jour.add_jour(nil, nil, obj.jour_id, options) end # obj = obj_distinguish_url_origin || User.find_by_id(2) # if obj.kind_of? User # obj.add_jour(nil, nil, nil, options) # elsif obj.kind_of? Project # Project.add_new_jour(nil, nil, obj.id, options) # elsif obj.kind_of? Course # Course.add_new_jour(nil, nil, obj.id, options) # elsif obj.kind_of? Bid # obj.add_jour(nil, nil, nil, options) # elsif obj.kind_of? Contest # obj.add_jour(nil, nil, obj.id, options) #new added # elsif obj.kind_of? Softapplication # obj.add_jour(nil, nil, obj.id, options) #new added # elsif obj.kind_of? HomeworkAttach # obj.add_jour(nil, nil, obj.id, options) #new added # else # raise "create reply obj unknow type.#{obj.class}" # end end def sy_resources syllabus courses = syllabus.courses.not_deleted attachments = Attachment.where(:container_type => 'Course', :container_id => courses.map(&:id)) resources = ResourceBank.where(:id => attachments.map(&:resource_bank_id)) resources end def sy_homeworks syllabus courses = syllabus.courses.not_deleted homeworks = HomeworkCommon.where(:course_id => courses.map(&:id)) homeworks = HomeworkBank.where(:id => homeworks.map(&:homework_bank_id)) homeworks end # 课堂学生的评测次数 def course_eval_count course Output.find_by_sql("select sum(g.evaluate_count) as evaluating_count from games g inner join (select myshixun_id from student_works sw inner join homework_commons hc on sw.homework_common_id=hc.id and sw.myshixun_id !=0 and hc.course_id=#{course.id} and homework_type=4) aa on g.myshixun_id=aa.myshixun_id").first.try(:evaluating_count).to_i end # 可以查看到资源库的资源 def visable_attachemnts_incourse course return[] unless course result = [] course.attachments.each do |attachment| if attachment.unified_setting if attachment.is_public? && attachment.is_publish == 1 || User.current == attachment.author || User.current.allowed_to?(:as_teacher,course) || (User.current.member_of_course?(course) && attachment.is_publish == 1) || User.current.admin? result << attachment end else if attachment.is_public? && attachment.is_publish == 1 && !User.current.member_of_course?(course) || User.current == attachment.author || User.current.allowed_to?(:as_teacher,course) || User.current.admin? result << attachment elsif User.current.member_of_course?(course) && attachment.is_publish == 1 member = course.members.where(:user_id => User.current.id).first if member.try(:course_group_id).to_i == 0 && attachment.unified_setting result << attachment elsif attachment.attachment_group_settings.where("course_group_id = #{member.try(:course_group_id)} and publish_time > '#{Time.now}'").count == 0 result << attachment end end end end result end def visable_course_poll course, is_teacher if is_teacher poll_num = course.polls.count elsif User.current.member_of_course?(course) member = course.members.where(:user_id => User.current.id).first if member.try(:course_group_id).to_i == 0 poll_num = course.polls.where("publish_time <= '#{Time.now}' and unified_setting = 1").count else not_poll_ids = course.poll_group_settings.where("course_group_id = #{member.try(:course_group_id)} and (publish_time > '#{Time.now}' or publish_time is null)") not_poll_ids = not_poll_ids.blank? ? "(-1)" : "(" + not_poll_ids.map(&:poll_id).join(",") + ")" poll_num = course.polls.where("publish_time <= '#{Time.now}' and id not in #{not_poll_ids}").count end else poll_num = course.polls.where("publish_time <= '#{Time.now}' and unified_setting = 1").count end poll_num end def visable_course_exercise course, is_teacher if is_teacher exercise_num = course.exercises.count elsif User.current.member_of_course?(course) member = course.members.where(:user_id => User.current.id).first if member.try(:course_group_id).to_i == 0 exercise_num = course.exercises.where("publish_time <= '#{Time.now}' and unified_setting = 1").count else not_exercise_ids = course.exercise_group_settings.where("course_group_id = #{member.try(:course_group_id)} and (publish_time > '#{Time.now}' or publish_time is null)") not_exercise_ids = not_exercise_ids.blank? ? "(-1)" : "(" + not_exercise_ids.map(&:exercise_id).join(",") + ")" exercise_num = course.exercises.where("publish_time <= '#{Time.now}' and id not in #{not_exercise_ids}").count end else exercise_num = course.exercises.where("publish_time <= '#{Time.now}' and unified_setting = 1").count end exercise_num end def visable_course_homework course, type=0, is_teacher, category_id category_str = category_id.nil? ? "is null" : "= #{category_id}" if is_teacher if type != 0 homework_num = course.homework_commons.where("homework_type = #{type} and course_homework_category_id #{category_str}").count else homework_num = course.homework_commons.where(:homework_type => [1,3,4]).count end elsif User.current.member_of_course?(course) member = course.members.where(:user_id => User.current.id).first if member.try(:course_group_id).to_i == 0 if type != 0 homework_num = course.homework_commons.where("homework_commons.homework_type = #{type} and publish_time <= '#{Time.now}' and unified_setting = 1 and course_homework_category_id #{category_str}").count else homework_num = course.homework_commons.where("homework_type in (1, 3, 4) and publish_time <= '#{Time.now}' and unified_setting = 1").count end else not_homework_ids = course.homework_group_settings.where("course_group_id = #{member.try(:course_group_id)} and (publish_time > '#{Time.now}' or publish_time is null)") not_homework_ids = not_homework_ids.blank? ? "(-1)" : "(" + not_homework_ids.map(&:homework_common_id).join(",") + ")" if type != 0 homework_num = course.homework_commons.where("homework_commons.homework_type = #{type} and publish_time <= '#{Time.now}' and id not in #{not_homework_ids} and course_homework_category_id #{category_str}").count else homework_num = course.homework_commons.where("homework_type in (1, 3, 4) and publish_time <= '#{Time.now}' and id not in #{not_homework_ids}").count end end else if type != 0 homework_num = course.homework_commons.where("homework_type = #{type} and publish_time <= '#{Time.now}' and unified_setting = 1 and course_homework_category_id #{category_str}").count else homework_num = course.homework_commons.where("homework_type in (1, 3, 4) and publish_time <= '#{Time.now}' and unified_setting = 1").count end end homework_num end def visible_task_count course, is_teacher task_count = 0 if is_teacher task_count = course.graduation_tasks.count else task_count = course.graduation_tasks.where("publish_time <= '#{Time.now}'").count end task_count end #成绩计算 def set_final_score homework,student_work if homework && homework.homework_detail_manual && !student_work.ultimate_score if !homework.homework_detail_manual.final_mode tea_ass_proportion = homework.homework_detail_manual.ta_proportion tea_proportion = homework.homework_detail_manual.te_proportion if homework.homework_type != 2 #非编程作业 if student_work.teacher_score if student_work.teaching_asistant_score.nil? if student_work.student_score.nil? student_work.final_score = student_work.teacher_score else te_proportion = tea_proportion + tea_ass_proportion / 2 final_te_score = BigDecimal.new("#{student_work.teacher_score}") * BigDecimal.new("#{te_proportion}") final_s_score = BigDecimal.new("#{student_work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{te_proportion}")) final_score = final_te_score + final_s_score student_work.final_score = format("%.2f",final_score.to_f) end else if student_work.student_score.nil? te_proportion = tea_proportion + (1.0 - tea_proportion - tea_ass_proportion) / 2 final_te_score = BigDecimal.new("#{student_work.teacher_score}") * BigDecimal.new("#{te_proportion}") final_ta_score = BigDecimal.new("#{student_work.teaching_asistant_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{te_proportion}")) final_score = final_te_score + final_ta_score student_work.final_score = format("%.2f",final_score.to_f) else final_te_score = BigDecimal.new("#{student_work.teacher_score}") * BigDecimal.new("#{tea_proportion}") final_ta_score = BigDecimal.new("#{student_work.teaching_asistant_score}") * BigDecimal.new("#{tea_ass_proportion}") final_s_score = BigDecimal.new("#{student_work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{tea_proportion}") - BigDecimal.new("#{tea_ass_proportion}")) final_score = final_te_score + final_ta_score + final_s_score student_work.final_score = format("%.2f",final_score.to_f) end end else if student_work.teaching_asistant_score.nil? student_work.final_score = student_work.student_score elsif student_work.student_score.nil? student_work.final_score = student_work.teaching_asistant_score else ta_proportion = tea_ass_proportion + tea_proportion / 2 final_ta_score = BigDecimal.new("#{student_work.teaching_asistant_score}") * BigDecimal.new("#{ta_proportion}") final_s_score = BigDecimal.new("#{student_work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{ta_proportion}")) final_score = final_ta_score + final_s_score student_work.final_score = format("%.2f",final_score.to_f) end end elsif homework.homework_type == 2 && homework.homework_detail_programing #编程作业-----设定:系统评分必定不为空 #if homework.teacher_priority == 1 #教师优先 sy_proportion = homework.homework_detail_programing.ta_proportion if student_work.teacher_score if student_work.teaching_asistant_score.nil? #教辅未评分 if student_work.student_score.nil? ta_proportion = tea_proportion + (1 - tea_proportion - sy_proportion) / 2 final_te_score = BigDecimal.new("#{student_work.teacher_score}") * BigDecimal.new("#{ta_proportion}") final_sy_score = BigDecimal.new("#{student_work.system_score || 0}") * (BigDecimal.new('1.0') - BigDecimal.new("#{ta_proportion}")) final_score = final_sy_score + final_te_score student_work.final_score = format("%.2f",final_score.to_f) else rest_proportion = tea_ass_proportion / 3 final_sy_score = BigDecimal.new("#{student_work.system_score || 0}") * BigDecimal.new("#{sy_proportion + rest_proportion}") final_te_score = BigDecimal.new("#{student_work.teacher_score}") * BigDecimal.new("#{tea_proportion + rest_proportion}") final_st_score = BigDecimal.new("#{student_work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{sy_proportion + rest_proportion}") - BigDecimal.new("#{tea_proportion + rest_proportion}")) final_score = final_sy_score + final_te_score + final_st_score student_work.final_score = format("%.2f",final_score.to_f) end elsif student_work.student_score.nil? #学生未评分 rest_proportion = (1 - tea_proportion - sy_proportion - tea_ass_proportion) / 3 final_sy_score = BigDecimal.new("#{student_work.system_score || 0}") * BigDecimal.new("#{sy_proportion + rest_proportion}") final_te_score = BigDecimal.new("#{student_work.teacher_score}") * BigDecimal.new("#{tea_proportion + rest_proportion}") final_ta_score = BigDecimal.new("#{student_work.teaching_asistant_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{sy_proportion + rest_proportion}") - BigDecimal.new("#{tea_proportion + rest_proportion}")) final_score = final_sy_score + final_te_score + final_ta_score student_work.final_score = format("%.2f",final_score.to_f) else final_sy_score = BigDecimal.new("#{student_work.system_score || 0}") * BigDecimal.new("#{sy_proportion}") final_te_score = BigDecimal.new("#{student_work.teacher_score}") * BigDecimal.new("#{tea_proportion}") final_ta_score = BigDecimal.new("#{student_work.teaching_asistant_score}") * BigDecimal.new("#{tea_ass_proportion}") final_s_score = BigDecimal.new("#{student_work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{sy_proportion}") - BigDecimal.new("#{tea_proportion}") - BigDecimal.new("#{tea_ass_proportion}")) final_score = final_sy_score + final_ta_score + final_te_score + final_st_score student_work.final_score = format("%.2f",final_score.to_f) end else if student_work.teaching_asistant_score.nil? #教辅未评分 if student_work.student_score.nil? student_work.final_score = student_work.system_score else ta_proportion = sy_proportion + (tea_ass_proportion + tea_proportion) / 2 final_sy_score = BigDecimal.new("#{student_work.system_score || 0}") * BigDecimal.new("#{ta_proportion}") final_st_score = BigDecimal.new("#{student_work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{ta_proportion}")) final_score = final_sy_score + final_st_score student_work.final_score = format("%.2f",final_score.to_f) end elsif student_work.student_score.nil? #学生未评分 if student_work.teaching_asistant_score.nil? student_work.final_score = student_work.system_score else ta_proportion = sy_proportion + (1.0 - tea_ass_proportion - sy_proportion) / 2 final_sy_score = BigDecimal.new("#{student_work.system_score || 0}") * BigDecimal.new("#{ta_proportion}") final_ts_score = BigDecimal.new("#{student_work.teaching_asistant_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{ta_proportion}")) final_score = final_sy_score + final_ts_score student_work.final_score = format("%.2f",final_score.to_f) end else rest_proportion = tea_proportion / 3 final_sy_score = BigDecimal.new("#{student_work.system_score || 0}") * BigDecimal.new("#{sy_proportion + rest_proportion}") final_ts_score = BigDecimal.new("#{student_work.teaching_asistant_score}") * BigDecimal.new("#{tea_ass_proportion + rest_proportion}") final_st_score = BigDecimal.new("#{student_work.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{sy_proportion + rest_proportion}") - BigDecimal.new("#{tea_ass_proportion + rest_proportion}")) final_score = final_sy_score + final_ts_score + final_st_score student_work.final_score = format("%.2f",final_score.to_f) end end end else if homework.homework_type != 2 if student_work.teacher_score student_work.final_score = student_work.teacher_score else if student_work.teaching_asistant_score.nil? student_work.final_score = student_work.student_score else student_work.final_score = student_work.teaching_asistant_score end end elsif homework.homework_type == 2 && homework.homework_detail_programing if student_work.teacher_score student_work.final_score = student_work.teacher_score else if student_work.teaching_asistant_score student_work.final_score = student_work.teaching_asistant_score else if student_work.system_score student_work.final_score = student_work.system_score else student_work.final_score = student_work.student_score end end end end end if student_work.final_score score = student_work.final_score - student_work.absence_penalty - student_work.late_penalty - student_work.appeal_penalty student_work.work_score = format("%.2f",(score < 0 ? 0 : score).to_f) if score else student_work.work_score = nil end end end # 计算实训作品学生的效率分 def update_student_eff_score homework if homework.work_efficiency && homework.max_efficiency != 0 homework.student_works.where("compelete_status != 0").each do |student_work| eff_score = student_work.efficiency / homework.max_efficiency * homework.eff_score student_work.eff_score = format("%.2f", eff_score) unless student_work.ultimate_score work_score = student_work.final_score + student_work.eff_score - student_work.late_penalty student_work.work_score = format("%.2f", work_score < 0 ? 0 : work_score) end student_work.save end else homework.student_works.where("compelete_status != 0").each do |student_work| student_work.eff_score = 0 unless student_work.ultimate_score work_score = student_work.final_score + student_work.eff_score - student_work.late_penalty student_work.work_score = format("%.2f", work_score < 0 ? 0 : work_score) end student_work.save end end end # 实训作业的评分 def set_shixun_final_score student_work, answer_open_evaluation, homework_challenge_settings unless student_work.work_status == 0 myshixun = student_work.myshixun final_score = 0 compelete = true max_endtime = "" user_total_score = 0 pass_consume_time = 0 homework_challenge_settings.each do |setting| game = myshixun.games.where(:challenge_id => setting.challenge_id, :status => 2).first unless game.nil? pass_consume_time += (game.cost_time / 60.0).to_f user_total_score += game.final_score.to_i < 0 ? 0 : game.challenge.score.to_i adjust_score = student_work.challenge_work_scores.where(:challenge_id => setting.challenge_id).last final_score += adjust_score.present? ? adjust_score.score : (answer_open_evaluation ? setting.score : (game.final_score >= 0 ? setting.score : 0)) max_endtime = max_endtime == "" ? game.end_time : (game.end_time > max_endtime ? game.end_time : max_endtime) else compelete = false end end efficiency = (pass_consume_time == 0 ? 0 : Math.log((user_total_score / pass_consume_time.to_f) + 1.0)) student_work.efficiency = efficiency < 0 ? 0 : format("%.2f", efficiency) if compelete && max_endtime != "" homework = student_work.homework_common member = Member.find_by_sql("select course_group_id from members where course_id = #{homework.course_id} and user_id = #{student_work.user_id}").first setting_time = homework_group_setting homework, member.try(:course_group_id) if setting_time.publish_time.present? && setting_time.end_time.present? if max_endtime < setting_time.publish_time student_work.compelete_status = 2 else if max_endtime < setting_time.end_time || (homework.allow_late && (homework.course.end_date.nil? || max_endtime < homework.course.end_date.end_of_day)) student_work.compelete_status = 1 student_work.cost_time = max_endtime.to_i - setting_time.publish_time.to_i else student_work.compelete_status = 0 end end end if homework.work_efficiency if homework.max_efficiency < student_work.efficiency homework.max_efficiency = student_work.efficiency homework.update_column("max_efficiency", homework.max_efficiency) end eff_score = homework.max_efficiency == 0 ? 0 : student_work.efficiency / homework.max_efficiency * homework.eff_score student_work.eff_score = format("%.2f", eff_score) else student_work.eff_score = 0 end elsif !compelete student_work.compelete_status = 0 end student_work.final_score = format("%.2f", final_score.to_f) score = student_work.final_score + student_work.eff_score - student_work.late_penalty student_work.work_score = format("%.2f", score < 0 ? 0 : score.to_f) unless student_work.ultimate_score student_work.save! end end # 用户评测时更新实训作业成绩 def update_myshixun_work_score myshixun student_works = myshixun.student_works #logger.info("#############student_works_count: #{student_works.count}") if student_works.count > 0 student_works.each do |work| homework = work.homework_common member = Member.find_by_sql("select course_group_id from members where course_id = #{homework.course_id} and user_id = #{User.current.id}").first #logger.info("#############member_course_group_id: #{member.try(:course_group_id)}") setting_time = homework_group_setting homework, member.try(:course_group_id) if setting_time.end_time.present? && (setting_time.end_time > Time.now || (homework.allow_late && !homework.course.is_end)) #logger.info("#############setting_time: #{setting_time.end_time}") user_total_score = 0 pass_consume_time = 0 final_score = 0 homework.homework_challenge_settings.each do |setting| game = myshixun.games.where(:challenge_id => setting.challenge_id, :status => 2).first unless game.nil? pass_consume_time += (game.cost_time / 60.0).to_f user_total_score += game.final_score.to_i < 0 ? 0 : game.challenge.score.to_i adjust_score = work.challenge_work_scores.where(:challenge_id => setting.challenge_id).last final_score += adjust_score.present? ? adjust_score.score : (homework.homework_detail_manual.answer_open_evaluation ? setting.score : (game.final_score >= 0 ? setting.score : 0)) end end if work.work_status == 0 is_complete = myshixun.is_complete? && (myshixun.done_time < setting_time.end_time) work.work_status = setting_time.end_time > Time.now ? 1 : (is_complete ? 1 : 2) work.late_penalty = setting_time.end_time > Time.now ? 0 : (is_complete ? 0 : homework.late_penalty) work.commit_time = myshixun.created_at > setting_time.publish_time ? setting_time.publish_time : myshixun.created_at work.myshixun_id = myshixun.id end efficiency = (pass_consume_time == 0 ? 0 : Math.log((user_total_score / pass_consume_time.to_f) + 1.0)) work.efficiency = format("%.2f", efficiency) games = myshixun.games.where(:challenge_id => homework.homework_challenge_settings.map(&:challenge_id)) myshixun_endtime = games.select{|game| game.status == 2}.size == games.size ? games.map(&:end_time).max : nil if myshixun_endtime.present? min_efficiency_changed = min_efficiency_changed.present? ? min_efficiency_changed : false work.compelete_status = 1 work.cost_time = myshixun_endtime.to_i - setting_time.publish_time.to_i # 计算作品的效率分(已完成才计算) if homework.work_efficiency # 如果作业的最大效率值有变更则更新所有作品的效率分 if homework.max_efficiency < work.efficiency homework.max_efficiency = work.efficiency homework.update_column("max_efficiency", homework.max_efficiency) update_student_eff_score homework end eff_score = homework.max_efficiency == 0 ? 0 : work.efficiency / homework.max_efficiency * homework.eff_score work.eff_score = format("%.2f", eff_score) end end work.update_time = Time.now # 为迁移的数据做特殊处理, 若分数小于当前通关分数则不更新 work.final_score = final_score if work.final_score.nil? || final_score > work.final_score score = work.final_score + work.eff_score - work.late_penalty work.work_score = format("%.2f",(score < 0 ? 0 : score).to_f) unless work.ultimate_score #logger.info("#############work_score: #{score}") work.save! end end end end # 用户开启实训时更新作品状态 def update_myshixun_work_status myshixun student_works = StudentWork.find_by_sql("SELECT sw.* FROM student_works sw, homework_commons_shixuns hcs WHERE sw.user_id = #{User.current.id} AND sw.`homework_common_id` = hcs.`homework_common_id` AND hcs.`shixun_id` = #{myshixun.shixun_id} and sw.work_status = 0") logger.info("#############student_works_count: #{student_works.count}") if student_works.count > 0 student_works.each do |work| homework = work.homework_common member = Member.find_by_sql("select course_group_id from members where course_id = #{homework.course_id} and user_id = #{User.current.id}").first setting_time = homework_group_setting homework, member.try(:course_group_id) if setting_time.end_time.present? && (setting_time.end_time > Time.now || (homework.allow_late && !homework.course.is_end)) logger.info("#############setting_time: #{setting_time.end_time}") work.work_status = setting_time.end_time > Time.now ? 1 : 2 work.late_penalty = setting_time.end_time > Time.now ? 0 : homework.late_penalty work.update_time = Time.now work.commit_time = Time.now work.myshixun_id = myshixun.id work.save end end end end def quote_resource_bank resource, course atta = Attachment.new(:filename => resource.filename, :disk_filename => resource.disk_filename, :filesize => resource.filesize, :digest => resource.digest, :downloads => 0, :is_publish => 0, :author_id => User.current.id, :description => resource.description, :disk_directory => resource.disk_directory, :is_public => 0, :copy_from => resource.copy_from.nil? ? resource.id : resource.copy_from, :quotes => 0, :resource_bank_id => resource.id, :created_on => Time.now, :content_type =>resource.content_type) if course.attachments << atta # 更新引用次数 quotes = resource.quotes.to_i + 1 resource.update_attribute(:quotes, quotes) end end def quote_homework_bank homework, course new_homework = HomeworkCommon.new(:name => homework.name, :user_id => User.current.id, :description => homework.description, :homework_type => homework.homework_type, :late_penalty => 5, :course_id => course.id, :teacher_priority => 1, :anonymous_comment => 1, :quotes => 0, :is_open => 0, :homework_bank_id => homework.id, :score_open => 1, :anonymous_appeal => 0, :is_public => 0, :reference_answer => homework.reference_answer, :answer_public => 1, :allow_late => 1) new_homework.homework_detail_manual = HomeworkDetailManual.new new_homework_detail_manual = new_homework.homework_detail_manual new_homework_detail_manual.te_proportion = 1.0 new_homework_detail_manual.ta_proportion = 0 new_homework_detail_manual.comment_status = 0 new_homework_detail_manual.evaluation_num = 0 new_homework_detail_manual.absence_penalty = 0 if new_homework.homework_type == 2 new_homework.homework_detail_programing = HomeworkDetailPrograming.new new_homework.homework_detail_programing.ta_proportion = 0 new_homework.homework_detail_programing.language = homework.language homework.homework_bank_tests.each_with_index do |homework_test| new_homework.homework_tests << HomeworkTest.new( input: homework_test.input, output: homework_test.output ) end homework.homework_bank_samples.each_with_index do |homework_test| new_homework.homework_samples << HomeworkSample.new( input: homework_test.input, output: homework_test.output ) end end if new_homework.homework_type == 3 new_homework.homework_detail_group = HomeworkDetailGroup.new new_homework.homework_detail_group.min_num = homework.min_num new_homework.homework_detail_group.max_num = homework.max_num new_homework.homework_detail_group.base_on_project = homework.base_on_project end homework.attachments.each do |attachment| att = attachment.copy att.container_id = nil att.container_type = nil att.author_id = homework.user_id att.copy_from = attachment.id att.save new_homework.attachments << att end if new_homework.save if new_homework.homework_type == 4 HomeworkCommonsShixuns.create(:homework_common_id => new_homework.id, :shixun_id => homework.homework_bank_shixun.shixun_id) end new_homework_detail_manual.save if new_homework_detail_manual new_homework.homework_detail_programing.save if new_homework.homework_detail_programing new_homework.homework_detail_group.save if new_homework.homework_detail_group create_works_list new_homework homework.update_column(:quotes, homework.quotes+1) QuestionBank.where(:container_id => homework.id, :container_type => ["Common", "Shixun", "Group"]).update_all(:quotes => homework.quotes) end return new_homework end def quote_exercise_bank exercise, course new_exercise = Exercise.new(:exercise_name => exercise.name, :exercise_description => exercise.description, :user_id => User.current.id, :is_public => 0, :exercise_status => 1, :show_result => 1, :course_id => course.id, :time => -1, :exercise_bank_id => exercise.id) exercise.exercise_bank_questions.each do |q| option = { :question_title => q[:question_title], :question_type => q[:question_type] || 1, :question_number => q[:question_number], :question_score => q[:question_score], :shixun_id => q[:shixun_id] } exercise_question = new_exercise.exercise_questions.new option if q.question_type != 5 for i in 1..q.exercise_bank_choices.count choice_option = { :choice_position => i, :choice_text => q.exercise_bank_choices[i-1][:choice_text] } exercise_question.exercise_choices.new choice_option end for i in 1..q.exercise_bank_standard_answers.count standard_answer_option = { :exercise_choice_id => q.exercise_bank_standard_answers[i-1][:exercise_bank_choice_id], :answer_text => q.exercise_bank_standard_answers[i-1][:answer_text] } exercise_question.exercise_standard_answers.new standard_answer_option end else for i in 1..q.exercise_bank_shixun_challenges.count challenge_option = { :position => i, :challenge_id => q.exercise_bank_shixun_challenges[i-1][:challenge_id], :shixun_id => q.exercise_bank_shixun_challenges[i-1][:shixun_id], :question_score => q.exercise_bank_shixun_challenges[i-1][:question_score] } exercise_question.exercise_shixun_challenges.new challenge_option end end end if new_exercise.save create_exercises_list new_exercise exercise.update_column(:quotes, exercise.quotes+1) QuestionBank.where(:container_id => exercise.id, :container_type => "Exercise").update_all(:quotes => exercise.quotes) end return new_exercise end def quote_poll_bank poll, course new_poll = Poll.new(:polls_name => poll.name, :polls_description => poll.description, :user_id => User.current.id, :is_public => 0, :polls_status => 1, :show_result => 1, :polls_type => 'Course', :course_id => course.id, :exercise_bank_id => poll.id) poll.exercise_bank_questions.each do |q| option = { :question_title => q[:question_title], :question_type => q[:question_type] || 1, :is_necessary => q[:is_necessary], :question_number => q[:question_number], :max_choices => q[:max_choices], :min_choices => q[:min_choices] } poll_question = new_poll.poll_questions.new option for i in 1..q.exercise_bank_choices.count choice_option = { :answer_position => i, :answer_text => q.exercise_bank_choices[i-1][:choice_text] } poll_question.poll_answers.new choice_option end end if new_poll.save create_polls_list new_poll poll.update_column(:quotes, poll.quotes+1) QuestionBank.where(:container_id => poll.id, :container_type => "Poll").update_all(:quotes => poll.quotes) end return new_poll end def major_level_option content = [] option0 = [] option0 << "选择课程所属专业层级" option0 << 0 option1 = [] option1 << "专科" option1 << 3 option2 = [] option2 << "本科" option2 << 2 option3 = [] option3 << "研究生" option3 << 1 content << option0 content << option1 content << option2 content << option3 content end def discipline_category_option major_level = 3 content = [] option0 = [] option0 << "选择课程所属学科门类" option0 << 0 content << option0 DisciplineCategory.where(:major_level => major_level).each do |dis| option = [] option << dis.name.to_s option << dis.id content << option end content end def first_level_discipline_option disc_ca = 27 content = [] option0 = [] option0 << "选择课程所属一级学科" option0 << 0 content << option0 FirstLevelDiscipline.where(:discipline_category_id => disc_ca).each do |fir_dis| option = [] option << fir_dis.name.to_s option << fir_dis.id content << option end content end def syllabus_major_option fir_dis = 213 content = [] option0 = [] option0 << "选择课程所属专业" option0 << 0 content << option0 Major.where(:first_level_discipline_id => fir_dis).each do |major| option = [] option << major.name.to_s option << major.id content << option end content end def convert_to_char(str) result = "" length = str.length unless str.nil? if length === 1 result += (str.to_i + 64).chr return result elsif length > 1 for i in 0...length result += (str[i].to_i + 64).chr end return result end end return result end def convert_to_chi_num num result = "" case num.to_i when 1 result = '一' when 2 result = '二' when 3 result = '三' when 4 result = '四' when 5 result = '五' when 6 result = '六' when 7 result = '七' when 8 result = '八' when 9 result = '九' end return result end #根据条件过滤作业结果 def search_work_member works,name if name == "" select_works = works else name = name.downcase select_works = works.select{ |work| work.user.user_extensions[:student_id].to_s.downcase.include?(name) || (work.user[:lastname].to_s.downcase + work.user[:firstname].to_s.downcase).include?(name) } end select_works end # 作业的分班设置时间 def homework_group_setting homework, group_id setting = nil if homework.homework_group_settings.where(:course_group_id => group_id).first setting = homework.homework_group_settings.where(:course_group_id => group_id).first else setting = homework end setting end # 试卷的分班设置时间 def exercise_group_setting exercise, group setting = nil if exercise.exercise_group_settings.where(:course_group_id => group.try(:id)).first setting = exercise.exercise_group_settings.where(:course_group_id => group.id).first else setting = exercise end setting end # 问卷的分班设置时间 def poll_group_setting poll, group setting = nil if poll.poll_group_settings.where(:course_group_id => group.try(:id)).first setting = poll.poll_group_settings.where(:course_group_id => group.id).first else setting = poll end setting end # 资源的分班设置时间 def attacment_group_setting attachment, group setting = nil if attachment.attachment_group_settings.where(:course_group_id => group.try(:id)).first setting = attachment.attachment_group_settings.where(:course_group_id => group.id).first else setting = attachment end setting end #统计答题百分比,统计结果保留两位小数 def statistics_result_percentage(e, t) e = e.to_f t = t.to_f t == 0 ? 0 : format("%.1f", e*100/t) end def subject_data subject result = {} subject_choices = 0 subject_shixuns = 0 subject_score = 0 subject.stage_shixuns.each do |stage_shixun| shixun = stage_shixun.shixun subject_choices += shixun.challenges.where(:st => [1, 2]).count subject_shixuns += shixun.challenges.where(:st => 0).count subject_score += shixun.shixun_score end result[:subject_choices] = subject_choices result[:subject_shixuns] = subject_shixuns result[:subject_score] = subject_score result end def tiding_url tiding case tiding.container_type when "ApplyUserAuthentication" if tiding.tiding_type == "Apply" tiding.container.auth_type == 1 ? identity_authentication_managements_path : professional_authentication_managements_path else tiding.container.auth_type == 1 ? authentication_account_path : professional_certification_account_path end when "CancelUserAuthentication" authentication_account_path when "CancelUserProCertification" professional_certification_account_path when "ApplyAddDepartment" tiding.tiding_type == "Apply" ? depart_managements_path() : my_account_path() when "ApplyAddSchools" tiding.tiding_type == "Apply" ? unit_managements_path() : my_account_path() when "ApplyAction" tiding.tiding_type == "System" ? (tiding.parent_container_type == "ApplyShixun" ? shixun_path(Shixun.find(tiding.parent_container_id).identifier):(tiding.parent_container_type == "TrialAuthorization" ? user_path(tiding.user_id) : subject_path(tiding.parent_container_id))):(tiding.parent_container_type == "ApplyShixun" ? shixun_authorization_managements_path():(tiding.parent_container_type == "TrialAuthorization"? trial_authorization_managements_path(): subject_authorization_managements_path())) when 'JoinCourse' course_path(tiding.container_id, :type => "JoinCourse") when 'StudentJoinCourse', 'DealCourse', 'TeacherJoinCourse' course_path(tiding.container_id) when 'Course', 'ArchiveCourse' course_path(tiding.container_id) when 'Shixun' '/shixuns/' + tiding.container.identifier when 'Subject' '/paths/' + tiding.container_id.to_s when 'JournalsForMessage' case tiding.parent_container_type when "Principal" feedback_path(tiding.parent_container_id) when "HomeworkCommon" student_work_index_path(:homework => tiding.parent_container_id, :tab => 2) when "GraduationTopic" graduation_topic_path(tiding.parent_container_id, :tab => 2) when "StudentWorksScore" student_work_path(:id => tiding.container.try(:jour).try(:student_work_id)) end when 'Message' board_message_path(tiding.container.board_id, tiding.parent_container_id) when 'Memo' forum_path(tiding.parent_container_id) when 'Watcher' user_path(tiding.trigger_user_id) when 'PraiseTread' try = tiding.parent_container_type.constantize object = try.find(tiding.parent_container_id) case tiding.parent_container_type when "Challenge" myshixun_id = Myshixun.where(:user_id => tiding.trigger_user_id, :shixun_id => Challenge.find(tiding.parent_container_id).shixun_id).first myshixun_game_path(Game.where(:myshixun_id => myshixun_id.id, :challenge_id => tiding.parent_container_id).first, :myshixun_id => myshixun_id) when "Discuss" myshixun_game_path(object.user_game, :myshixun_id => object.user_myshixun) when "Message" object.parent.present? ? board_message_path(object.board_id, object.root_id) : board_message_path(object.board_id, object) when "Memo" object.parent.present? ? forum_path(object.root_id) : forum_path(object) when "JournalsForMessage" case object.jour_type when "Principal" feedback_path(object.jour_id) when "HomeworkCommon" student_work_index_path(:homework => object.jour_id, :tab => 2) when "StudentWorksScore" student_work_path(:id => object.try(:jour).try(:student_work_id)) end when "HomeworkCommon" student_work_index_path(:homework => tiding.parent_container_id, :tab => 2) when "Issue" issue_path(tiding.parent_container_id) when "Journal" issue_path(object.journalized_id) end when 'Discuss' shixun_discuss_shixun_path(tiding.container.dis) when 'Grade' user_grade_user_path(User.current) when 'JoinProject' project_path(tiding.container_id, :type => "applied_project") when 'ReporterJoinProject', 'DealProject', 'ManagerJoinProject' project_path(tiding.container_id) when 'Poll' case tiding.parent_container_type when 'CommitPoll' student_poll_list_poll_path(tiding.container, :tab => 2) else student_poll_list_poll_path(tiding.container) end when 'Exercise' case tiding.parent_container_type when 'CommitExercise', 'ExerciseScore' show_student_result_exercise_path(tiding.container,:user_id => tiding.trigger_user_id) else student_exercise_list_exercise_path(tiding.container) end when 'StudentGraduationTopic', 'DealStudentTopicSelect' graduation_topic_path(tiding.parent_container_id) when 'GraduationTask' graduation_task_path(tiding.container_id) when 'GraduationWork' graduation_work_path(tiding.container_id) when 'GraduationWorkScore' graduation_work_path(tiding.parent_container_id) when 'HomeworkCommon' case tiding.parent_container_type when 'AnonymousCommentFail' student_work_index_path(:homework => tiding.container_id, :tab => 4) when 'HomeworkPublish' student_work_index_path(:homework => tiding.container_id, :tab => 2) when 'AnonymousAppeal' work = tiding.container.student_works(:user_id => User.current.id).first work.present? ? student_work_path(work.try(:id)) : "javascript:void(0)" else student_work_index_path(:homework => tiding.container_id) end when 'StudentWork' student_work_path(tiding.container_id) when 'StudentWorksScore', 'StudentWorksScoresAppeal' student_work_path(tiding.parent_container_id) when 'ChallengeWorkScore' homework_common_path(tiding.container.try(:student_work).try(:homework_common_id)) when 'SendMessage' mirror_repository_managements_path when 'Journal' issue_path(tiding.parent_container_id) when 'Issue' issue_path(tiding.container_id) when 'PullRequest' project_pull_requests_path(tiding.parent_container_id) when 'Department' my_account_path end end def create_shixun_homework_cha_setting homework, shixun if shixun.present? sum_score = 0 total_score = 100.0 - homework.eff_score shixun.challenges.each_with_index do |challeng, index| if index < shixun.challenges.length - 1 score = ((total_score / shixun.challenges.length) * total_score).floor / total_score sum_score += score else score = total_score - sum_score end HomeworkChallengeSetting.create(:homework_common_id => homework.id, :challenge_id => challeng.id, :shixun_id => shixun.id, :score => score) end end end