socialforge/app/helpers/application_helper.rb

3379 lines
131 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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'
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
# def user_blogs_path(resource,parameters={})
# super
# end
# 通过系统外部邮箱查找用户,如果用户不存在则用邮箱替换
def get_user_by_mail mail
user = User.find_by_mail(mail)
user.nil? ? User.find(2) : user
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
# 获取用户单位
# 优先获取高校信息如果改信息不存在则获取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.news_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)
name = h(user.name(options[:format]))
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_id3、已解决 5、已关闭
if issue.status_id == 3
s = link_to text, issue_path(issue), :class => "text_line_s", :title => title
elsif issue.status_id == 5
s = link_to text, issue_path(issue), :class => "text_line_s del_line", :title => title
else
s = link_to text, issue_path(issue), :class => "c_blue", :title => title
end
s << h(": #{subject}") 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_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]+/, "<br />").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 << "<ul class='projects #{ ancestors.empty? ? 'root' : nil}'>\n"
s << "<ul class='projects'>\n"
else
ancestors.pop
s << "</li>"
while (ancestors.any? && !project.is_descendant_of?(ancestors.last))
ancestors.pop
s << "</ul></li>\n"
end
end
classes = (ancestors.empty? ? 'root' : 'child')
s << "<li class='project-table'><div class='#{classes}'>"
if project.try(:project_type) == Project::ProjectType_project
s << h(block_given? ? yield(project) : project.name)
else
end
if project.try(:project_type) == Project::ProjectType_project
unless User.current.member_of?(@project)
s << "<span style = 'float: right;'>"
s << watcher_link(@project, User.current)#, ['whiteButton'])
s << "</span>"
end
s << (render :partial => 'projects/project', :locals => {:project => project}).to_s
else
s << (render :partial => 'projects/course', :locals => {:project => project}).to_s
end
s << "</div>\n"
ancestors << project
end
s << ("</li></ul>\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 << "<ul class=courses>\n"
else
ancestors.pop
s << "</li>"
while (ancestors.any? )#&& !course.is_descendant_of?(ancestors.last))
ancestors.pop
s << "</ul></li>\n"
end
end
classes = (ancestors.empty? ? 'root' : 'child')
s << "<li class='project-table'><div class='#{classes}'>"
s << (render :partial => 'courses/course', :locals => {:course => course}).to_s
s << "</div>\n"
ancestors << course
end
s << ("</li></ul>\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 << "<ul class='projects #{ ancestors.empty? ? 'root' : nil}'>\n"
s << "<ul class='projects'>\n"
else
ancestors.pop
s << "</li>"
while (ancestors.any? && !project.is_descendant_of?(ancestors.last))
ancestors.pop
s << "</ul></li>\n"
end
end
classes = (ancestors.empty? ? 'root' : 'child')
s << h(block_given? ? yield(project) : project.name)
ancestors << project
end
s << ("</li></ul>\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 << "<ul class=\"pages-hierarchy\">\n"
pages[node].each do |page|
content << "<li>"
content << link_to(h(page.pretty_title), {:controller => 'wiki', :action => 'show', :project_id => page.project, :id => page.title, :version => nil},
:title => (options[:timestamp] && page.updated_on ? l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)) : nil))
content << "\n" + render_page_hierarchy(pages, page.id, options) if pages[page.id]
content << "</li>\n"
end
content << "</ul>\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 => "flash #{k}", :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 =
("<option value=''>#{ l(:label_jump_to_a_project) }</option>" +
'<option value="" disabled="disabled">---</option>').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 ? '&nbsp;' * 2 * level + '&#187; ' : '').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
# 项目版本库可见权限判断
# 条件1、modules中设置不可见或项目没有版本库2、如果项目是私有或者项目版本库隐藏则必须是项目成员才可见
def visible_repository?(project)
@result = false
unless project.enabled_modules.where("name = 'repository'").empty? || project.repositories.count == 0
if (project.hidden_repo || !project.is_public?)
if User.current.member_of?(project)
@result = true
end
else
@result = true
end
end
return @result
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
# 判断当前用户是否为项目管理员
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 << "<label>#{ check_box_tag name, principal.id, false, :id => nil } #{h principal}</label>\n"
end
s.html_safe
end
#项目成员列表复选框生成
def project_member_check_box_tags_ex name, principals
s = ''
principals.each do |principal|
s << "<li>#{ check_box_tag name, principal.id, false, :id => nil } #{h link_to principal.userInfo, user_url_in_org( principal.id)}</li>\n"
end
s.html_safe
end
#缺陷追踪者列表复选框生成
def issue_watcher_check_box_tags_ex name, principals
s = ''
principals.each do |principal|
s << "<li>#{ check_box_tag name, principal.id, false, :id => nil } #{h link_to principal.userInfo, user_path( principal.id)}</li>\n"
end
s.html_safe
end
#扩展的checkbox生成
def principals_check_box_tags_ex(name, principals)
s = ''
principals.each do |principal|
s << "<label>#{ check_box_tag name, principal.id, false, :id => nil } #{h link_to principal.userInfo, user_path( principal.id)}</label>\n"
end
s.html_safe
end
# li标签checkbos扩展
def principals_check_box_tags_li(name, principals)
s = ''
principals.each do |principal|
s << "<li>#{ check_box_tag name, principal.id, false, :id => nil } #{h link_to principal.userInfo, user_path( principal.id) }</li>\n"
end
s.html_safe
end
#扩展的checkbox生成
def principals_radio_box_tags_ex(name, principals)
s = ''
principals.each do |principal|
s << "<label>#{ radio_button_tag name, principal.id, false, :id => nil } #{h principal.userInfo }</label>\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) << %(<option value="#{element.id}"#{selected_attribute}>#{h element.name}</option>)
end
unless groups.empty?
s << %(<optgroup label="#{h(l(:label_group_plural))}">#{groups}</optgroup>)
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+)}, '<span class="hours hours-int">\1</span><span class="hours hours-dec">.\2</span>').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('<p class="other-formats fl">'.html_safe + l(:label_export_to))
yield Redmine::Views::OtherFormatsBuilder.new(self)
concat('</p>'.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
elsif @course
title << @course.name
elsif @organization
title << @organization.name
elsif @user
title << @user.try(:realname)
elsif @syllabus
title << @syllabus.title
else
title << (User.current.id == 2 ? "未登录" : User.current.try(:realname))
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 << "</#{tag}>"
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
# 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), url, :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)( [^>]+)?>(.+?)<\/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]
"<a name=\"#{anchor}\"></a>\n<h#{level} #{attrs}>#{content}<a href=\"##{anchor}\" class=\"wiki-anchor\">&para;</a></h#{level}>"
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 = /<p>\{\{([<>]?)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 = "<ul class=\"#{div_class}\"><li>"
root = headings.map(&:first).min
current = root
started = false
headings.each do |level, anchor, item|
if level > current
out << '<ul><li>' * (level - current)
elsif level < current
out << "</li></ul>\n" * (current - level) + "</li><li>"
elsif started
out << '</li><li>'
end
out << "<a href=\"##{anchor}\">#{item}</a>"
current = level
started = true
end
out << '</li></ul>' * (current - root)
out << '</li></ul>'
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+/, "<br /><br />"). # 2+ newline -> 2 br
gsub(/([^\n]\n)(?=[^\n])/, '\1<br />'). # 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+/, "<br /><br />"). # 2+ newline -> 2 br
gsub(/([^\n]\n)(?=[^\n])/, '\1<br />'). # 1 newline -> br
gsub("&amp;nbsp", " "). #gsub(/<\/?.*?>/,"").
gsub(/&lt;\/?.*?&gt;/, "").
gsub("&quot;", "'").
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 << "<div id='errorExplanation'><ul>\n"
errors.each do |error|
###by xianbo
if(error!=l(:label_repository_path_not_null))
html << "<li>#{h error}</li>\n"
end
###xianbo
end
###by xianbo
unless params[:repository].nil?
if params[:repository][:upassword]==""
html << "<li>"+ l(:label_password_not_null) +"</li>\n"
end
end
###xianbo
html << "</ul></div>\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 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 => " c_purple"))
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(l(:button_check_all), "checkAll('#{form_name}', true)") + "&nbsp;&nbsp;".html_safe + " | "+ "&nbsp;&nbsp;".html_safe +
link_to_function(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('table',
content_tag('tr',
(pcts[0] > 0 ? content_tag('td', '', :style => "width: #{pcts[0]}%;", :class => 'closed', :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('td', '', :style => "width: #{pcts[1]}%;", :class => 'todo', :title => "未完成:#{pcts[1]}%") : ''.html_safe), :style => "width: #{width}"
), :class => 'progress').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 <joe@foo.bar>')
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')
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
"<link rel='shortcut icon' href='#{image_path('/favicon.ico')}' />".html_safe
end
def robot_exclusion_tag
'<meta name="robots" content="noindex,follow,noarchive" />'.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
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
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 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.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
elsif attachment.container.is_a?(OrgDocumentComment)
org = attachment.container.organization
candown = 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=="BlogComment" #博客资源允许下载
candown = true
elsif attachment.container.class.to_s=="Memo" #论坛资源允许下载
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
end
candown
end
def project_type_link(text, value)
if value == 1
link_to "<span class='pr_kafa'></span>#{text}".html_safe,"javascript:void(0)" ,:onClick => "show_window();", :class => "pr_join_a",:id => "setting_project_type"
elsif value == 2
link_to "<span class='pr_keyan'></span>#{text}".html_safe,"javascript:void(0)" ,:onClick => "show_window();", :class => "pr_join_a",:id => "setting_project_type"
else
link_to "<span class='pr_friend'></span>#{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
if student_work.student_works_scores.any?
course = student_work.homework_common.course
course.members.map(&:user_id).uniq.each do|user_id|
if User.find(user_id).allowed_to?(:as_teacher, course)
student_work.course_messages << CourseMessage.new(:user_id => user_id, :course_id => course.id, :viewed => false, :status => 1)
end
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 = "<li class = 'topnav_a fl'>" << home_link << "</li>"
# 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 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://eecs.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 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.select{|attachment| attachment.is_public? ||
(attachment.container_type == "Course" && User.current.member_of_course?(course))||
attachment.author_id == User.current.id
}
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
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, is_in_course, user_activity_id = -1, course_activity = -1)
if homework.homework_detail_manual.comment_status == 0 ||Time.parse(homework.end_time.to_s).strftime("%Y-%m-%d") >= Time.now.strftime("%Y-%m-%d")
link = link_to "启动匿评","javascript:void(0)", :class => "postOptionLink", :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?is_in_course=" + is_in_course.to_s + "&user_activity_id=" + user_activity_id.to_s + "&course_activity=" + course_activity.to_s, id: "#{homework.id}_start_anonymous_comment", remote: true, disable_with: '加载中...',:class => 'postOptionLink'
when 2
link = link_to '关闭匿评', Setting.protocol + "://" + Setting.host_name + "/homework_common/" + homework.id.to_s + "/alert_anonymous_comment?is_in_course=" + is_in_course.to_s + "&user_activity_id=" + user_activity_id.to_s + "&course_activity=" + course_activity.to_s, id: "#{homework.id}_stop_anonymous_comment", remote: true,:class => 'postOptionLink'
when 3
# link = link_to "匿评结束","javascript:void(0)", :class => "postOptionLink", :title => "匿评结束"
end
else
link = link_to "启动匿评","javascript:void(0)", :class => "postOptionLink", :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_homework_common homework,is_teacher
count = homework.student_works.has_committed.count
if User.current.member_of_course?(homework.course)
if is_teacher #老师显示作品数量
link_to "作品(#{count})", student_work_index_url_in_org(homework.id), :class => "c_blue"
else #学生显示提交作品、修改作品等按钮
work = cur_user_works_for_homework homework
project = cur_user_projects_for_homework homework
if work.nil? && Time.parse(homework.end_time.to_s).strftime("%Y-%m-%d") >= Time.now.strftime("%Y-%m-%d")
if homework.homework_type ==3 && project.nil? && homework.homework_detail_group.base_on_project == 1
link_to "提交作品(#{count})","javascript:void(0)", :class => 'c_grey',:style=>"cursor:not-allowed",:title => '请先关联项目再提交作品'
else
link_to "提交作品(#{count})", new_student_work_url_without_domain(homework.id),:class => 'c_blue'
end
elsif work.nil? && Time.parse(homework.end_time.to_s).strftime("%Y-%m-%d") < Time.now.strftime("%Y-%m-%d")
if homework.homework_type ==3 && project.nil? && homework.homework_detail_group.base_on_project == 1
link_to "补交作品(#{count})","javascript:void(0)", :class => 'c_grey',:style=>"cursor:not-allowed",:title => '请先关联项目再补交作品'
else
link_to "补交作品(#{count})", new_student_work_url_without_domain(homework.id),:class => 'c_red'
end
else
if homework.homework_detail_manual && homework.homework_detail_manual.comment_status == 2 #匿评作业,且作业状态不是在开启匿评之前
link_to "作品匿评", student_work_index_url_in_org(homework.id), :class => 'c_blue', :title => "开启匿评后不可修改作品"
elsif homework.homework_detail_manual && homework.homework_detail_manual.comment_status == 3
link_to "查看作品(#{count})",student_work_index_url_in_org(homework.id), :class => 'c_blue', :title => "匿评已结束"
elsif homework.homework_type == 2 && Time.parse(homework.end_time.to_s).strftime("%Y-%m-%d") >= Time.now.strftime("%Y-%m-%d")#编程作业不能修改作品
link_to "修改作品(#{count})", new_student_work_url_without_domain(homework.id),:class => 'c_blue'
elsif Time.parse(homework.end_time.to_s).strftime("%Y-%m-%d") >= Time.now.strftime("%Y-%m-%d") && work.user_id == User.current.id
link_to "修改作品(#{count})", edit_student_work_url_without_domain(work.id),:class => 'c_blue'
else
link_to "查看作品(#{count})", student_work_index_url_in_org(homework.id), :class => 'c_blue', :title => "作业截止后不可修改作品"
end
end
end
else
link_to "作品(#{count})",student_work_index_url_in_org(homework.id),:class => "c_blue"
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
"<span class='fr mr10 pr_join_span '>未开启匿评</span>".html_safe
when 2
"<span class='fr mr10 pr_join_span '>正在匿评中</span>".html_safe
when 3
"<span class='fr mr10 pr_join_span '>匿评已结束</span>".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_work_projects.where("user_id = ?",User.current).first
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 '', download_named_attachment_path(file.id, file.filename, preview: true),html_options
end
end
#将文本内的/n转换为<br>
def text_format text
text.gsub("&","&amp;").gsub("<","&lt;").gsub(">","&gt;").gsub("\n","<br/>").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 += ",请&nbsp" + 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 += ",请&nbsp" + 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 <stdio.h> //引用必须头文件
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 <iostream> //引用必须头文件
#include <cstdlib>
using namespace std;
int main(int argc, char** argv){
int a = atoi(argv[1]); //将第一个输入转成整型
int b = atoi(argv[2]); //将第二个输入转换为整型
cout<<a+b; //输出a+b
return 0;
}".html_safe
end
#学生C语言的标准代码
def c_stantard_code_student
"// 同学好这是一个C语言的样例程序
// 程序功能:输入两个整数,输出两者之和
// 测试集合:老师可以给出多组测试集,例如:
// 输入1和2输出3
// 输入3和4输出7
// ... ...
// 系统将根据您给出的测试集对学生代码进行自动评分
// 特别提醒程序采用命令行传参方式输入通过argv传入
// 否则您的作业标准代码将不能通过测试
#include <stdio.h> //引用必须头文件
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 <iostream> //引用必须头文件
#include <cstdlib>
using namespace std;
int main(int argc, char** argv){
int a = atoi(argv[1]); //将第一个输入转成整型
int b = atoi(argv[2]); //将第二个输入转换为整型
cout<<a+b; //输出a+b
return 0;
}".html_safe
end
#判断用户是否已经提交了问卷
def has_commit_poll?(poll_id,user_id)
pu = PollUser.find_by_poll_id_and_user_id(poll_id,user_id)
if pu.nil?
false
else
true
end
end
def 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_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
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
#项目动态更新
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
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
#个人动态更新
def update_principal_activity type, id
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
#项目按更新时间排序
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, is_focus = '', show_work_id = '')
if is_focus != ''
Setting.protocol + "://" + Setting.host_name + "/student_work?homework=" + homework_id.to_s + "&is_focus=" + is_focus.to_s
elsif show_work_id != ''
Setting.protocol + "://" + Setting.host_name + "/student_work?homework=" + homework_id.to_s + "&show_work_id=" + show_work_id.to_s
else
Setting.protocol + "://" + Setting.host_name + "/student_work?homework=" + homework_id.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_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 result, jour
if (jour.kind_of? JournalsForMessage) || (jour.kind_of? Message) || (jour.kind_of? BlogComment) || (jour.kind_of? OrgDocumentComment)
jour.children.each do |jour_child|
result << jour_child
get_all_children 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 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(/&nbsp;*/, ' ')
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_hw_index(hw,is_teacher)
if is_teacher
homeworks = hw.course.homework_commons.order("created_at asc")
else
homeworks = hw.course.homework_commons.where("publish_time <= '#{Date.today}'").order("created_at asc")
end
hw_ids = homeworks.map{|hw| hw.id} if !homeworks.empty?
index = hw_ids.index(hw.id)
return index
end
def get_group_member_names work
result = ""
unless work.nil?
work.student_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 user = User.current
syllabuses = user.syllabuses
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