|
|
# encoding: utf-8
|
|
|
# REDO: 创建版本库权限控制
|
|
|
class ShixunsController < ApplicationController
|
|
|
layout 'base_shixun'
|
|
|
before_filter :require_login, :except => [:ghook, :download_file, :show, :index]
|
|
|
before_filter :check_authentication, :except => [:ghook, :download_file, :show, :index, :operation]
|
|
|
before_filter :find_shixun, :except => [ :index, :new, :create, :index, :search, :shixun_courses, :new_disscuss, :shixun_migrate, :qrcode, :download_file, :departments, :get_mirror_script, :send_message_to_administrator]
|
|
|
|
|
|
skip_before_filter :verify_authenticity_token, :only => [:ghook, :download_file]
|
|
|
before_filter :view_allow, :only => [:collaborators, :propaedeutics, :shixun_discuss, :ranking_list]
|
|
|
before_filter :require_manager, :only => [ :settings, :add_script, :publish, :collaborators_delete, :shixun_members_added, :add_collaborators, :update, :destroy]
|
|
|
before_filter :validation_email, :only => [:new]
|
|
|
#before_filter :require_manager, :only => [:destroy]
|
|
|
# 移动云ToC模式权限控制
|
|
|
# before_filter :ecloud_auth, :except => [:show, :index]
|
|
|
|
|
|
include ApplicationHelper
|
|
|
include ShixunsHelper
|
|
|
CODES = %W(2 3 4 5 6 7 8 9 A B C D E F G H J K L N M O P Q R S T U V W X Y Z)
|
|
|
DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z)
|
|
|
|
|
|
|
|
|
# 实训二维码生成器(android编译成功后,game的picture_path会返回中间层的workspace, workspace+关卡学院文件路径就是文件所在的路径)
|
|
|
def qrcode
|
|
|
@type == "qrcode"
|
|
|
game = Game.find(params[:game_id])
|
|
|
workspace = game.picture_path
|
|
|
game_challenge = game.challenge
|
|
|
qr = RQRCode::QRCode.new("#{Setting.host_name}/shixuns/download_file?file_name=#{workspace}/#{game_challenge.picture_path}/manual-ok.apk", :size => 10, :level => :h)
|
|
|
@qrcode_str = Base64.encode64( qr.to_img.resize(400,400).to_s )
|
|
|
respond_to do |format|
|
|
|
format.js
|
|
|
end
|
|
|
end
|
|
|
|
|
|
# 二维码扫描下载
|
|
|
def download_file
|
|
|
file_path = params[:file_name]
|
|
|
send_file "#{Rails.root}/#{file_path}", :filename => "#{file_path}",
|
|
|
:type => 'shixun',
|
|
|
:disposition => 'attachment' #inline can open in browser
|
|
|
end
|
|
|
|
|
|
# 获取版本库文件目录
|
|
|
def search_file_list
|
|
|
path = params[:path]
|
|
|
@path = to_path_param(path)
|
|
|
g = Gitlab.client
|
|
|
@dir = g.trees(@shixun.gpid, :path => @path).map{|tree|[tree.type, (@path.blank? ? tree.name : "#{@path}"+"/"+tree.name )]}
|
|
|
logger.info("dir is ##{@dir}")
|
|
|
respond_to do |format|
|
|
|
format.js
|
|
|
end
|
|
|
# render :json => {:dir => @dir}
|
|
|
end
|
|
|
|
|
|
def achieve_ways
|
|
|
@repository = @shixun.repository
|
|
|
@entries = @repository.entries(@path, @rev)
|
|
|
# @entries = Gitlab.client.trees(@shixun.gpid).map{|tree| tree.name}
|
|
|
end
|
|
|
|
|
|
def statistics_students
|
|
|
pub_shixun = ApplyAction.where(:container_type => "ApplyShixun", :status => 1, :container_id => @shixun.id).last
|
|
|
if pub_shixun.present?
|
|
|
updated_at = pub_shixun.updated_at
|
|
|
admin_ids = User.where(:admin => 1).blank? ? "(-1)" : "(" + User.where(:admin => 1).map(&:id).join(",") + ")"
|
|
|
@statistics = @shixun.myshixuns.where("user_id not in #{admin_ids}").select{|myshixun| myshixun.updated_at > updated_at}
|
|
|
@statistic_ids = @statistics.map(&:id)
|
|
|
@statistics = Myshixun.where(:id => @statistic_ids).order("created_at desc")
|
|
|
#@statistics = @shixun.myshixuns.where("created_at > #{updated_at}").order("created_at desc")
|
|
|
@complete_myshixun = Myshixun.where(:id => @statistics, :status => 1)
|
|
|
@complete_myshixun_count = @complete_myshixun.size
|
|
|
@complete_myshixun.each do |myshixun|
|
|
|
myshixun[:s_score] = myshixun.total_score
|
|
|
myshixun[:s_spend_time] = myshixun.total_spend_time
|
|
|
myshixun[:s_accuracy] = myshixun.total_accuracy
|
|
|
myshixun[:s_done_time] = myshixun.done_time
|
|
|
end
|
|
|
@complete_myshixun = @complete_myshixun.sort do |a, b|
|
|
|
[b[:s_score], a[:s_spend_time], b[:s_accuracy], a[:s_done_time]] <=> [a[:s_score], b[:s_spend_time], a[:s_accuracy], b[:s_done_time]]
|
|
|
end
|
|
|
@complete_myshixun = @complete_myshixun[0, 10]
|
|
|
@statistics_count = @statistics.size
|
|
|
@statistics = @statistics.limit(10)
|
|
|
end
|
|
|
end
|
|
|
|
|
|
# 学员统计中的关卡统计
|
|
|
def challenge_statistics
|
|
|
@challenge = @shixun.challenges.where(:id => params[:c]).first
|
|
|
if @challenge
|
|
|
pub_shixun = ApplyAction.where(:container_type => "ApplyShixun", :status => 1, :container_id => @shixun.id).last
|
|
|
if pub_shixun.present?
|
|
|
updated_at = pub_shixun.updated_at
|
|
|
admin_ids = User.where(:admin => 1).blank? ? "(-1)" : "(" + User.where(:admin => 1).map(&:id).join(",") + ")"
|
|
|
myshixuns = @shixun.myshixuns.where("user_id not in #{admin_ids}").select{|myshixun| myshixun.updated_at > updated_at}
|
|
|
@statistics = @challenge.games.where(:myshixun_id => myshixuns.map(&:id), :status => 2).select("games.*, (unix_timestamp(games.end_time)-unix_timestamp(games.open_time)) as spend_time").reorder("final_score desc, spend_time asc, accuracy desc, end_time asc")
|
|
|
@statistics_count = @statistics.size
|
|
|
@statistics = paginateHelper @statistics, 20
|
|
|
@page = params['page'] || 1
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
|
|
|
# 学员统计中的通关排行榜
|
|
|
def ranking_list
|
|
|
pub_shixun = ApplyAction.where(:container_type => "ApplyShixun", :status => 1, :container_id => @shixun.id).last
|
|
|
if pub_shixun.present?
|
|
|
updated_at = pub_shixun.updated_at
|
|
|
admin_ids = User.where(:admin => 1).blank? ? "(-1)" : "(" + User.where(:admin => 1).map(&:id).join(",") + ")"
|
|
|
@complete_myshixun = @shixun.myshixuns.includes(:user, :games => [:challenge]).where("user_id not in #{admin_ids} and status = 1").select{|myshixun| myshixun.updated_at > updated_at}
|
|
|
#@complete_myshixun = Myshixun.where(:id => statistics.map(&:id), :status => 1)
|
|
|
@complete_myshixun_count = @complete_myshixun.size
|
|
|
@complete_myshixun.each do |myshixun|
|
|
|
myshixun[:s_score] = myshixun_exp myshixun
|
|
|
myshixun[:s_spend_time] = myshixun_spend_time myshixun
|
|
|
# myshixun[:s_accuracy] = myshixun_accuracy myshixun
|
|
|
# myshixun[:s_done_time] = myshixun_done_time myshixun
|
|
|
end
|
|
|
# @complete_myshixun = @complete_myshixun.sort do |a, b|
|
|
|
# [b[:s_score], a[:s_spend_time], b[:s_accuracy], a[:s_done_time]] <=> [a[:s_score], b[:s_spend_time], a[:s_accuracy], b[:s_done_time]]
|
|
|
# end
|
|
|
@complete_myshixun = @complete_myshixun.sort do |a, b|
|
|
|
[b[:s_score], a[:s_spend_time]] <=> [a[:s_score], b[:s_spend_time]]
|
|
|
end
|
|
|
@complete_myshixun = @complete_myshixun[0..9]
|
|
|
end
|
|
|
end
|
|
|
|
|
|
# 学员统计中的学员列表
|
|
|
def trainee_list
|
|
|
pub_shixun = ApplyAction.where(:container_type => "ApplyShixun", :status => 1, :container_id => @shixun.id).last
|
|
|
if pub_shixun.present?
|
|
|
updated_at = pub_shixun.updated_at
|
|
|
admin_ids = User.where(:admin => 1).blank? ? "(-1)" : "(" + User.where(:admin => 1).map(&:id).join(",") + ")"
|
|
|
@statistics = @shixun.myshixuns.where("user_id not in #{admin_ids}").select{|myshixun| myshixun.updated_at > updated_at}
|
|
|
@statistics = @statistics.map(&:id)
|
|
|
@statistics = Myshixun.where(:id => @statistics).order("created_at desc")
|
|
|
@statistics_count = @statistics.size
|
|
|
@page = params['page'] || 1
|
|
|
@statistics = paginateHelper @statistics, 20
|
|
|
end
|
|
|
end
|
|
|
|
|
|
# push代码的时候会触发gitlab hook
|
|
|
def ghook
|
|
|
# shixun_modify_status_without_publish(@shixun, 1)
|
|
|
render :json => {status: "success"}
|
|
|
end
|
|
|
|
|
|
# 注意:shixun_id 格式 /shixun_migrate?shixun_id=100
|
|
|
# 注意:language 格式 /shixun_migrate?language="Java,Python"
|
|
|
def shixun_migrate
|
|
|
unless User.current.admin?
|
|
|
render_403
|
|
|
return
|
|
|
end
|
|
|
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
|
|
|
if params[:language]
|
|
|
language = params[:language].split("/")
|
|
|
logger.info(language)
|
|
|
shixuns = Shixun.where(:language => language)
|
|
|
elsif params[:shixun_id]
|
|
|
shixuns = Shixun.where(:id => params[:shixun_id])
|
|
|
else
|
|
|
shixuns = Shixun.all
|
|
|
end
|
|
|
if shixuns.present?
|
|
|
shixuns.each do |shixun|
|
|
|
begin
|
|
|
logger.info("shixun id is #{shixun.id}")
|
|
|
tpiList =[]
|
|
|
gameInfo = shixun.gameInfo
|
|
|
myshixuns = shixun.myshixuns
|
|
|
if myshixuns.present?
|
|
|
myshixuns.each do |myshixun|
|
|
|
logger.info("tpiID is #{myshixun.id}")
|
|
|
tpiID = myshixun.id
|
|
|
instanceGitURL = gitlab_url myshixun
|
|
|
logger.info("instanceGitURL is #{instanceGitURL}")
|
|
|
tpiList << {:tpiID => tpiID, :instanceGitURL => instanceGitURL}
|
|
|
logger.info("###############{tpiList.to_json unless tpiList.blank?}")
|
|
|
|
|
|
logger.info("************#{tpiList}")
|
|
|
end
|
|
|
end
|
|
|
tpiList = Base64.urlsafe_encode64(tpiList.to_json) unless tpiList.blank?
|
|
|
params = {:gameInfo => "#{gameInfo}", :tpiList => "#{tpiList}" }
|
|
|
logger.info("params is #{params}")
|
|
|
uri = "#{shixun_tomcat}/bridge/dataTransfer/transfer"
|
|
|
logger.info("uri is #{uri}")
|
|
|
res = uri_exec uri, params
|
|
|
logger.info("=====res is #{res['code']}")
|
|
|
render :json => {:result => "success"}
|
|
|
rescue Exception => e
|
|
|
logger.info("error ====> #{e.message}")
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
|
|
|
|
|
|
# 向管理员发私信
|
|
|
def send_message_to_administrator
|
|
|
# notes = User.current.show_name.to_s + " 申请了新镜像:<a href='javascript:void(0);'>#{params[:notes]}</a>"
|
|
|
# JournalsForMessage.create(
|
|
|
# :jour_id => 1,
|
|
|
# :jour_type => "Principal",
|
|
|
# :user_id => User.current.id,
|
|
|
# :reply_id => 0,
|
|
|
# :is_readed => 0,
|
|
|
# :private => 1,
|
|
|
# :notes => notes
|
|
|
# )
|
|
|
Tiding.create(:user_id => 1, :trigger_user_id => User.current.id, :container_type => "SendMessage", :extra => params[:notes], :viewed => 0, :tiding_type => "Apply")
|
|
|
render :json => {success: "true"}
|
|
|
end
|
|
|
|
|
|
def shixun_test
|
|
|
jenkins_shixuns = Redmine::Configuration['jenkins_shixuns']
|
|
|
uri = URI("#{jenkins_shixuns}/jenkins-exec/webssh/getConnectInfo")
|
|
|
user_id = User.current.id
|
|
|
params = {userID:user_id}
|
|
|
res = uri_exec uri, params
|
|
|
render :json => {data:"succesed"}
|
|
|
end
|
|
|
|
|
|
def delete_shixun_test
|
|
|
jenkins_shixuns = Redmine::Configuration['jenkins_shixuns']
|
|
|
uri = URI("#{jenkins_shixuns}/jenkins-exec/webssh/deleteSSH")
|
|
|
user_id = User.current.id
|
|
|
params = {userID:user_id}
|
|
|
res = uri_exec uri, params
|
|
|
render :json => {data:"succesed"}
|
|
|
end
|
|
|
|
|
|
def game_webssh
|
|
|
|
|
|
end
|
|
|
|
|
|
def entry_edit
|
|
|
g = Gitlab.client
|
|
|
@path = params[:path]
|
|
|
@rev = params[:rev]
|
|
|
file_content = g.files(@shixun.gpid, @path, @rev).content
|
|
|
@content = tran_base64_decode64(file_content)
|
|
|
|
|
|
respond_to do |format|
|
|
|
format.js
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def entry_update
|
|
|
g = Gitlab.client
|
|
|
@path = params[:path]
|
|
|
@rev = params[:rev]
|
|
|
@content = params[:content]
|
|
|
code_file = g.edit_file(@shixun.gpid, User.current.login, :content => params[:content], :file_path => @path, :branch_name => @rev, :commit_message => "file update")
|
|
|
# if @shixun.try(:status).to_i < 2
|
|
|
# shixun_modify_status_without_publish(@shixun, 1)
|
|
|
# end
|
|
|
@shixun.myshixuns.update_all(:system_tip => 0)
|
|
|
if code_file.message
|
|
|
@error_message = code_file.message
|
|
|
end
|
|
|
respond_to do |format|
|
|
|
format.js
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def shixun_monitor
|
|
|
# monitor_filter
|
|
|
# if @had_exec
|
|
|
# @tpm = Myshixun.where(:user_id => User.current, :shixun_id => @shixun).first
|
|
|
# end
|
|
|
#
|
|
|
# respond_to do |format|
|
|
|
# format.js
|
|
|
# end
|
|
|
end
|
|
|
|
|
|
def statistics
|
|
|
@challenges = @shixun.challenges
|
|
|
@top_students = @shixun.myshixuns.where(:status => 1)
|
|
|
myshixuns = @shixun.myshixuns.includes(:games)
|
|
|
@latest_myshixuns = myshixuns.order("created_at desc").limit(4)
|
|
|
end
|
|
|
|
|
|
def autocompletion
|
|
|
|
|
|
end
|
|
|
|
|
|
def edit_md
|
|
|
#render :layout => false
|
|
|
end
|
|
|
|
|
|
# 首页实训导航点击时,type参数
|
|
|
def index
|
|
|
@type = params[:type]
|
|
|
@status = [["全部状态", 0], ["已发布", 2], ["未发布", 1], ["已关闭", 3]]
|
|
|
@diff = ["全部难度", "初级学员", "中级学员", "高级学员", "顶级学员"]
|
|
|
@repertoires = Repertoire.includes(sub_repertoires: [:tag_repertoires]).order("updated_at asc")
|
|
|
if @type.present?
|
|
|
id = params[:id].to_i
|
|
|
case @type
|
|
|
when 'rep'
|
|
|
rep = Repertoire.find id
|
|
|
sub_id = rep.sub_repertoires.map(&:id)
|
|
|
tag = TagRepertoire.where(:sub_repertoire_id => sub_id)
|
|
|
@rep_active = rep.id # 页面样式、和首页跳转搜索需要
|
|
|
@search_name = ""
|
|
|
when 'sub'
|
|
|
sub = SubRepertoire.find id
|
|
|
tag = TagRepertoire.where(:sub_repertoire_id => sub)
|
|
|
@rep_active = sub.repertoire.id
|
|
|
@sub_acive = sub.id # 页面样式、和首页跳转搜索需要
|
|
|
@search_name = "#{sub.name}"
|
|
|
when 'tag'
|
|
|
tag = TagRepertoire.find id
|
|
|
sub = tag.sub_repertoire
|
|
|
@rep_active = sub.repertoire.id
|
|
|
@sub_active = sub.id
|
|
|
@tag_active = tag.id # 页面样式、和首页跳转搜索需要
|
|
|
@search_name = "#{sub.name} / #{tag.name}"
|
|
|
end
|
|
|
shixun_id = ShixunTagRepertoire.where(:tag_repertoire_id => tag).map(&:shixun_id)
|
|
|
@shixuns = Shixun.select([:id, :name, :user_id, :challenges_count, :visits, :status, :myshixuns_count,
|
|
|
:trainee, :use_scope, :identifier, :image_text, :averge_star])
|
|
|
.where(:id => shixun_id, :hidden => 0).where("status != -1")
|
|
|
.includes(:challenges, :schools, :shixun_members, :users).order("status = 2 desc, publish_time asc")
|
|
|
else
|
|
|
@shixuns = Shixun.select([:id, :name, :user_id, :challenges_count, :visits, :status, :myshixuns_count,
|
|
|
:trainee, :use_scope, :identifier, :image_text, :averge_star])
|
|
|
.where("status != ? and hidden = ?", -1, 0).includes(:challenges, :schools, :shixun_members, :users)
|
|
|
.order("status = 2 desc, publish_time asc")
|
|
|
end
|
|
|
# # 依据tag和语言推荐实训,如果tag不够,则依据语言推荐;语言不够,则取系统的三个
|
|
|
# @recommend_shixuns = Shixun.find_by_sql("select challenge_id from challenge_tags where name like
|
|
|
# CONCAT('%',(select name from challenge_tags where challenge_id in (select id from challenges where shixun_id=61)),'%')")
|
|
|
|
|
|
@obj_count = @shixuns.count
|
|
|
@limit = 16
|
|
|
@is_remote = true
|
|
|
@obj_pages = Paginator.new @obj_count, @limit, params['page'] || 1
|
|
|
@offset ||= @obj_pages.offset
|
|
|
@shixuns = paginateHelper @shixuns, @limit
|
|
|
respond_to do |format|
|
|
|
format.js
|
|
|
format.html{render :layout => "base_edu"}
|
|
|
end
|
|
|
end
|
|
|
|
|
|
# params
|
|
|
# repertoire:大类别; #sub_repertoire:子类别; #tag_repertoire 实训标签;
|
|
|
# status:实训状态; diff:实训难度; search: 搜索条件; order:排序; sort: 升序, 降序
|
|
|
def search
|
|
|
repertoire = params[:repertoire]
|
|
|
sub_repertoire = params[:sub_repertoire]
|
|
|
tag_repertoire = params[:tag_repertoire]
|
|
|
status = params[:status].to_i
|
|
|
diff = params[:diff].to_i
|
|
|
search = params[:search].try(:strip)
|
|
|
order = params[:order]
|
|
|
bsort = params[:sort]
|
|
|
hidden_learn = params[:hidden_learn]
|
|
|
logger.info("######params: #{params}")
|
|
|
diff = (diff == 0 ? [1,2,3,4] : diff) # diff = 0表示搜索所有
|
|
|
filter_status = order == "created_at" || order == "myshixuns_count" ? [2, 3] : [0, 1, 2, 3]
|
|
|
status = if status == 0
|
|
|
filter_status & [0, 1, 2 ,3] # 所有状态
|
|
|
elsif status == 1
|
|
|
filter_status & [0, 1] # 未发布
|
|
|
else
|
|
|
filter_status & [status]
|
|
|
end
|
|
|
shixun_id = if tag_repertoire.present?
|
|
|
tag = TagRepertoire.find(tag_repertoire)
|
|
|
ShixunTagRepertoire.where(:tag_repertoire_id => tag).map(&:shixun_id)
|
|
|
elsif sub_repertoire.present?
|
|
|
sub = SubRepertoire.find(sub_repertoire)
|
|
|
ShixunTagRepertoire.where(:tag_repertoire_id => sub.tag_repertoires).map(&:shixun_id)
|
|
|
elsif repertoire.present?
|
|
|
rep = Repertoire.find(repertoire)
|
|
|
tag_id = TagRepertoire.where(:sub_repertoire_id => rep.sub_repertoires).map(&:id)
|
|
|
ShixunTagRepertoire.where(:tag_repertoire_id => tag_id).map(&:shixun_id)
|
|
|
else
|
|
|
Shixun.select([:id]).map(&:id)
|
|
|
end
|
|
|
|
|
|
# "我的"实训
|
|
|
if order == "mine"
|
|
|
my_shixun_ids = User.current.shixun_members.map(&:shixun_id) + User.current.myshixuns.map(&:shixun_id)
|
|
|
shixun_id = shixun_id & my_shixun_ids
|
|
|
end
|
|
|
|
|
|
@shixuns = Shixun.select([:id, :name, :user_id, :challenges_count, :visits, :status, :myshixuns_count, :trainee, :use_scope, :identifier, :image_text, :averge_star]).where(:id => shixun_id, :hidden => 0, :trainee => diff, :status => status).includes(:challenges, :schools, :shixun_members, :users)
|
|
|
|
|
|
if search.present?
|
|
|
search_users_id = User.select([:id]).where("concat(lastname, firstname) like '%#{search}%'")
|
|
|
search_users_id = search_users_id.blank? ? "(-1)" : "(" + search_users_id.map{|sc| sc.id}.join(',') + ")"
|
|
|
search_shixun_ids = Challenge.where("subject like '%#{search}%'").pluck(:shixun_id).uniq
|
|
|
search_shixun_ids = search_shixun_ids.blank? ? "(-1)" : "(" + search_shixun_ids.join(",") + ")"
|
|
|
fuzzy_searchs = search.split(" ").join("%")
|
|
|
@shixuns = @shixuns.where("name like ? or user_id in #{search_users_id} or id in #{search_shixun_ids}", "%#{fuzzy_searchs}%")
|
|
|
end
|
|
|
|
|
|
if hidden_learn.present?
|
|
|
shixun_id = User.current.shixuns.map(&:id)
|
|
|
my_shixun_id = Myshixun.where(:user_id => User.current.id).map(&:shixun_id)
|
|
|
not_shixun_id = shixun_id + my_shixun_id
|
|
|
not_shixun_id = not_shixun_id.size > 0 ? "(" + not_shixun_id.join(",") + ")" : "(-1)"
|
|
|
@shixuns = @shixuns.where("id not in #{not_shixun_id}") if shixun_id.present?
|
|
|
end
|
|
|
|
|
|
if order == "mine"
|
|
|
@shixuns = @shixuns.order("created_at #{bsort}")
|
|
|
else
|
|
|
@shixuns = @shixuns.order("shixuns.status = 2 desc, #{order} #{bsort}")
|
|
|
end
|
|
|
@obj_count = @shixuns.count
|
|
|
@limit = 16
|
|
|
@is_remote = true
|
|
|
@obj_pages = Paginator.new @obj_count, @limit, params['page'] || 1
|
|
|
@offset ||= @obj_pages.offset
|
|
|
@shixuns = paginateHelper @shixuns, @limit
|
|
|
|
|
|
respond_to do |format|
|
|
|
format.js
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def propaedeutics
|
|
|
respond_to do |format|
|
|
|
format.html
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def update_propaedeutics
|
|
|
if request.get?
|
|
|
respond_to do |format|
|
|
|
format.html
|
|
|
end
|
|
|
else
|
|
|
@shixun = Shixun.where(:identifier => params[:id]).first
|
|
|
@shixun.update_attribute("propaedeutics", params[:shixun][:propaedeutics])
|
|
|
redirect_to propaedeutics_shixun_path(@shixun)
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def collaborators
|
|
|
@collaborators = @shixun.shixun_members.reorder("role = 1 desc, created_at asc")
|
|
|
@collaborators_count = @collaborators.size
|
|
|
@limit = 10
|
|
|
respond_to do |format|
|
|
|
format.js
|
|
|
format.html
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def collaborators_delete
|
|
|
user_id = params[:c_id]
|
|
|
gid = User.find(user_id).try(:gid)
|
|
|
shixun_member = ShixunMember.where(:user_id => user_id, :shixun_id => @shixun.id, :role => 2).first
|
|
|
shixun_member.delete
|
|
|
g = Gitlab.client
|
|
|
unless gid.nil?
|
|
|
g.remove_team_member(@shixun.gpid, gid)
|
|
|
end
|
|
|
@collaborators = @shixun.shixun_members.reorder("role = 1 desc, created_at asc")
|
|
|
@collaborators_count = @collaborators.count
|
|
|
@limit = 10
|
|
|
respond_to do |format|
|
|
|
format.js
|
|
|
end
|
|
|
end
|
|
|
|
|
|
# 已存在的成员不添加
|
|
|
def add_collaborators
|
|
|
if !params[:search].nil?
|
|
|
member_ids = "(" + @shixun.shixun_members.map(&:user_id).join(',') + ")"
|
|
|
condition = "%#{params[:search].strip}%".gsub(" ","")
|
|
|
@users = User.where("id not in #{member_ids} and status = 1 and LOWER(concat(lastname, firstname, login, mail, nickname)) LIKE '#{condition}'").includes(:user_extensions)
|
|
|
end
|
|
|
respond_to do |format|
|
|
|
format.js
|
|
|
end
|
|
|
end
|
|
|
|
|
|
# 事务处理,保证Trustie与Gitlab数据同步
|
|
|
def shixun_members_added
|
|
|
ActiveRecord::Base.transaction do
|
|
|
begin
|
|
|
unless params[:membership][:user_ids].blank?
|
|
|
memberships = params[:membership][:user_ids]
|
|
|
memberships.each do |member|
|
|
|
user = User.find(member)
|
|
|
s = Trustie::Gitlab::Sync.new
|
|
|
if user.gid.present?
|
|
|
gid = user.gid
|
|
|
else
|
|
|
guser = s.sync_user(user)
|
|
|
gid = guser.id
|
|
|
end
|
|
|
ShixunMember.create!(:user_id => member, :shixun_id => @shixun.id, :role => 2)
|
|
|
u = s.g.add_team_member(@shixun.gpid, gid, 40) # 3代表角色master
|
|
|
if u.blank?
|
|
|
raise("同步Gitlab数据失败")
|
|
|
end
|
|
|
end
|
|
|
respond_to do |format|
|
|
|
format.js{redirect_to collaborators_shixun_path(@shixun)}
|
|
|
end
|
|
|
end
|
|
|
rescue Exception => e
|
|
|
logger.error(e)
|
|
|
raise ActiveRecord::Rollback
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def change_manager
|
|
|
if request.get?
|
|
|
@collaborators = @shixun.shixun_members.where("user_id != #{@shixun.user_id}")
|
|
|
else
|
|
|
if params[:choosemanager]
|
|
|
man_member = ShixunMember.where(:shixun_id => @shixun.id, :user_id => @shixun.user_id).first
|
|
|
cha_member = ShixunMember.find params[:choosemanager]
|
|
|
if man_member && cha_member
|
|
|
man_member.update_attributes(:role => 2)
|
|
|
cha_member.update_attributes(:role => 1)
|
|
|
@shixun.update_attributes(:user_id => cha_member.user_id)
|
|
|
end
|
|
|
redirect_to collaborators_shixun_path(@shixun)
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
|
|
|
# gameID 及实训ID
|
|
|
# status: 0 , 1 申请过, 2,实训关卡路径未填, 3 实训标签未填, 4 实训未创建关卡
|
|
|
def publish
|
|
|
@status = 0
|
|
|
@position = ""
|
|
|
begin
|
|
|
if @shixun.challenges.count == 0
|
|
|
@status = 4
|
|
|
else
|
|
|
@shixun.challenges.each do |challenge|
|
|
|
if challenge.challenge_tags.count == 0
|
|
|
@status = 3
|
|
|
@position = (@position == "" ? @position : (@position + ",")) + challenge.position.to_s + "关"
|
|
|
end
|
|
|
end
|
|
|
unfinish_challenge = @shixun.challenges.where(:st => 0, :path => nil)
|
|
|
if unfinish_challenge.count > 0 && !@shixun.is_choice_type
|
|
|
@status = 2
|
|
|
@pos = []
|
|
|
unfinish_challenge.each do |challenge|
|
|
|
@pos << challenge.position
|
|
|
end
|
|
|
@pos = @pos.join(",")
|
|
|
end
|
|
|
end
|
|
|
if @status == 0
|
|
|
@shixun.update_attributes!(:status => 1)
|
|
|
apply = ApplyAction.where(:container_type => "ApplyShixun", :container_id => @shixun.id).order("created_at desc").first
|
|
|
if apply && apply.status == 0
|
|
|
@status = 0
|
|
|
else
|
|
|
ApplyAction.create(:container_type => "ApplyShixun", :container_id => @shixun.id, :user_id => User.current.id, :status => 0)
|
|
|
begin
|
|
|
status = Trustie::Sms.send(mobile: '15388083362', send_type:'publish_shixun' , name: '管理员')
|
|
|
rescue => e
|
|
|
Rails.logger.error "发送验证码出错: #{e}"
|
|
|
end
|
|
|
@status = 1
|
|
|
end
|
|
|
end
|
|
|
rescue Exception => e
|
|
|
logger.error("pushlish game #{e}")
|
|
|
respond_to do |format|
|
|
|
format.js
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def apply_publish
|
|
|
apply = ApplyAction.where(:container_type => "ApplyShixun", :container_id => @shixun.id).last
|
|
|
if apply && apply.status == 0
|
|
|
@status = 0
|
|
|
else
|
|
|
ApplyAction.create(:container_type => "ApplyShixun", :container_id => @shixun.id, :user_id => User.current.id, :status => 0)
|
|
|
# notes = User.current.show_name.to_s + " 申请发布实训:<a href='#{shixun_path(@shixun)}'>#{@shixun.name}</a>"
|
|
|
# JournalsForMessage.create(:jour_id => 1, :jour_type => 'Principal', :user_id => User.current.id, :notes => notes, :private => 1, :reply_id => 0)
|
|
|
@shixun.update_column('status', 1)
|
|
|
@status = 1
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def cancel_publish
|
|
|
apply = ApplyAction.where(:container_type => "ApplyShixun", :container_id => @shixun.id).order("created_at desc").first
|
|
|
if apply && apply.status == 0
|
|
|
apply.update_attributes(:status => 3)
|
|
|
apply.tidings.destroy_all
|
|
|
@shixun.update_column('status', 0)
|
|
|
end
|
|
|
redirect_to shixun_path(@shixun)
|
|
|
end
|
|
|
|
|
|
def close
|
|
|
render_403 unless User.current.admin?
|
|
|
@shixun.update_attributes(:status => 3, :closer_id => User.current.id, :end_time => Time.now)
|
|
|
redirect_to shixun_path(@shixun)
|
|
|
end
|
|
|
|
|
|
# copy_shixun:复制一个新的实训模块包括版本库
|
|
|
# copy_myshixun自动创建系列game,game中只包含状态等信息,公共信息从Challeges中读取
|
|
|
# 开启过实训的则直接跳入my实训页面
|
|
|
def shixun_exec
|
|
|
# unless allow_shixun_exec(@shixun) && (User.current.manager_of_shixun?(@shixun) || @shixun.status > 0)
|
|
|
# render_403
|
|
|
# return
|
|
|
# end
|
|
|
# 添加事务锁,防止并发情况下tpi被多次创建
|
|
|
myshixun = Myshixun.where(:user_id => User.current.id, :shixun_id => @shixun.id).first
|
|
|
unless myshixun.blank?
|
|
|
logger.info("current task id is #{myshixun.current_task}")
|
|
|
|
|
|
redirect_to "/tasks/#{myshixun.current_task.identifier}"
|
|
|
# redirect_to myshixun_game_path(myshixun.current_task, :myshixun_id => myshixun, :is_subject => params[:is_subject])
|
|
|
return
|
|
|
end
|
|
|
ActiveRecord::Base.transaction do
|
|
|
begin
|
|
|
# fork版本库,如果用户没有同步,则先同步用户
|
|
|
g = Gitlab.client
|
|
|
if User.current.gid.nil?
|
|
|
s = Trustie::Gitlab::Sync.new
|
|
|
s.sync_user(User.current)
|
|
|
end
|
|
|
gshixun = g.fork(@shixun.gpid, User.current.gid)
|
|
|
|
|
|
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
|
|
|
code = down_generate_identifier("myshixun")
|
|
|
|
|
|
|
|
|
# 一般通过默认分支是否存在来判断一个项目是否fork成功
|
|
|
if gshixun.try(:id).present?
|
|
|
commit_id = g.commits(@shixun.gpid).first.try(:id)
|
|
|
# educoder 加入到myshixun中
|
|
|
myshixun_admin_gid = User.where(:login => "educoder").first.try(:gid)
|
|
|
g.add_team_member(gshixun.id, myshixun_admin_gid, 40) # 40代表角色master
|
|
|
|
|
|
myshixun = Myshixun.create!(:shixun_id => @shixun.id, :user_id => User.current.id, :identifier => code, :modify_time => @shixun.modify_time,
|
|
|
:reset_time => @shixun.reset_time, :onclick_time => Time.now, :gpid => gshixun.id,
|
|
|
:git_url => gshixun.try(:path_with_namespace), :commit_id => commit_id)
|
|
|
|
|
|
# tpm 不需要目录的
|
|
|
# rep = Repository.create!(:myshixun_id => myshixun.id, :identifier => gshixun.name,:project_id => -1, :shixun_id => -2)
|
|
|
# rep.update_column(:type, "Repository::Gitlab")
|
|
|
rep_url = Base64.urlsafe_encode64(gitlab_url @shixun) # 注意:educoder为默认给实训创建版本库的用户,如果换成别的用户,名字要相应的修改
|
|
|
|
|
|
logger.info("start openGameInstance")
|
|
|
uri = "#{shixun_tomcat}/bridge/game/openGameInstance"
|
|
|
logger.info("end openGameInstance")
|
|
|
params = {tpiID: "#{myshixun.id}", tpmGitURL:rep_url, tpiRepoName: gshixun.try(:name)}
|
|
|
logger.info("openGameInstance params is #{params}")
|
|
|
res = uri_exec uri, params
|
|
|
if (res && res['code'].to_i != 0)
|
|
|
raise("实训云平台繁忙(繁忙等级:83)")
|
|
|
end
|
|
|
|
|
|
# 其它创建关卡等操作
|
|
|
challenges = @shixun.challenges
|
|
|
# 之所以增加user_id是为了方便统计查询性能
|
|
|
challenges.each_with_index do |challenge, index|
|
|
|
status = (index == 0 ? 0 : 3)
|
|
|
code = down_generate_identifier("game")
|
|
|
Game.create!(:challenge_id => challenge.id, :myshixun_id => myshixun.id, :status => status, :user_id => myshixun.user_id,
|
|
|
:open_time => Time.now, :identifier => code, :modify_time => challenge.modify_time)
|
|
|
# 记录刚开始时默认代开文件原始代码
|
|
|
# 刚开始fork的一段时间是获取不了content内容的
|
|
|
# if challenge.st == 0 && challenge.path.present?
|
|
|
# paths = challenge.path.split(";")
|
|
|
# paths.each do |path|
|
|
|
# game_code_init(game.id, path)
|
|
|
# end
|
|
|
# end
|
|
|
end
|
|
|
if params[:type] == "1" # 重置过来的请求
|
|
|
shixun_mod = ShixunModify.where(:shixun_id => myshixun.try(:shixun_id), :myshixun_id => myshixun.try(:id)).first
|
|
|
if shixun_mod.nil?
|
|
|
ShixunModify.create(:shixun_id => myshixun.shixun_id, :myshixun_id => myshixun.id, :status => 0)
|
|
|
else
|
|
|
shixun_mod.update_attributes(:status => 0)
|
|
|
end
|
|
|
end
|
|
|
else
|
|
|
raise("实训云平台繁忙(繁忙等级:81)")
|
|
|
end
|
|
|
# unlock
|
|
|
logger.info("myshixun id is #{myshixun.try(:identifier)} and current_task id is#{myshixun.try(:current_task).try(:id)}")
|
|
|
# 开启实训时更新关联作品的状态
|
|
|
update_myshixun_work_status myshixun
|
|
|
redirect_to myshixun_game_path(myshixun.current_task, :myshixun_id => myshixun, :is_subject => params[:is_subject])
|
|
|
rescue Exception => e
|
|
|
if e.message == "shixun error"
|
|
|
flash[:error] = "正在后台执行,请稍后重试"
|
|
|
elsif e.message.include?("Mysql2::Error")
|
|
|
flash[:error] = "正在后台执行,请稍后重试"
|
|
|
else
|
|
|
flash[:error] = e.message
|
|
|
end
|
|
|
logger.error("###failed to exec shixun: current task id is #{e}")
|
|
|
g.delete_project(gshixun.id) if gshixun.try(:id).present?
|
|
|
redirect_to shixun_challenges_path(@shixun)
|
|
|
raise ActiveRecord::Rollback
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def shixun_courses
|
|
|
data = {result:0,options:[]}
|
|
|
if params[:major_id] != 0
|
|
|
major = Major.find params[:major_id]
|
|
|
if major
|
|
|
data[:result] = 1
|
|
|
major_courses = major.major_courses
|
|
|
CourseList.where(:id => major_courses.map(&:course_list_id)).each do |course|
|
|
|
option = []
|
|
|
option << course.name.to_s
|
|
|
option << course.id
|
|
|
data[:options] << option
|
|
|
end
|
|
|
else
|
|
|
data[:result] = 0
|
|
|
end
|
|
|
else
|
|
|
data[:result] = 0
|
|
|
end
|
|
|
render :json =>data
|
|
|
end
|
|
|
|
|
|
def new
|
|
|
@shixun = Shixun.new
|
|
|
@support = Major.where(:support_shixuns=> 1)
|
|
|
@introduction_sample = PlatformSample.where(:samples_type => 'introduction').first.try(:contents)
|
|
|
@knowledge_sample = PlatformSample.where(:samples_type => 'knowledge').first.try(:contents)
|
|
|
@main_type = MirrorRepository.published_main_mirror
|
|
|
@small_type = MirrorRepository.published_small_mirror
|
|
|
|
|
|
|
|
|
respond_to do |format|
|
|
|
format.html{render :layout => 'base_edu'}
|
|
|
format.json
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def departments
|
|
|
respond_to do |format|
|
|
|
format.js
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def create
|
|
|
identifier = generate_identifier
|
|
|
@shixun = Shixun.new(params[:shixun])
|
|
|
@shixun.user_id = User.current.id
|
|
|
@shixun.trainee = params[:trainee]
|
|
|
@shixun.webssh = params[:webssh].to_i
|
|
|
@shixun.multi_webssh = @shixun.webssh == 2 && params[:multi_webssh] == "1" ? 1 : 0
|
|
|
@shixun.vnc = params[:vnc].to_i
|
|
|
@shixun.can_copy = params[:can_copy].to_i
|
|
|
@shixun.identifier = identifier
|
|
|
@shixun.reset_time = Time.now
|
|
|
@shixun.modify_time = Time.now
|
|
|
@shixun.use_scope = params[:public_degree].to_i
|
|
|
@shixun.visits = 1
|
|
|
main_type = params[:main_type]
|
|
|
sub_type = params[:small_type]
|
|
|
|
|
|
mirror = MirrorScript.where(:mirror_repository_id => main_type)
|
|
|
if sub_type.blank?
|
|
|
shixun_script = mirror.first.try(:script)
|
|
|
else
|
|
|
main_mirror = MirrorRepository.find(main_type).type_name
|
|
|
sub_mirror = MirrorRepository.find(sub_type).type_name
|
|
|
if main_mirror == "Java" && sub_mirror == "Mysql"
|
|
|
shixun_script = mirror.last.try(:script)
|
|
|
else
|
|
|
shixun_script = mirror.first.try(:script)
|
|
|
shixun_script = modify_shixun_script @shixun, shixun_script
|
|
|
end
|
|
|
end
|
|
|
@shixun.evaluate_script = shixun_script
|
|
|
|
|
|
ActiveRecord::Base.transaction do
|
|
|
begin
|
|
|
@shixun.save!
|
|
|
if params[:scope_partment].present?
|
|
|
arr = []
|
|
|
ids = School.where(:name => params[:scope_partment]).map(&:id).uniq
|
|
|
ids.each do |id|
|
|
|
arr << { :school_id => id, :shixun_id => @shixun.id }
|
|
|
end
|
|
|
ShixunSchool.create!(arr)
|
|
|
end
|
|
|
m = ShixunMember.new(:user_id => User.current.id, :role => 1)
|
|
|
@shixun.shixun_members << m
|
|
|
# 镜像-实训关联表
|
|
|
ShixunMirrorRepository.create!(:shixun_id => @shixun.id, :mirror_repository_id => main_type.to_i) if main_type.present?
|
|
|
# 创建Pod配置信息
|
|
|
ShixunServiceConfig.create!(:shixun_id => @shixun.id, :mirror_repository_id => main_type.to_i)
|
|
|
if sub_type.present?
|
|
|
sub_mirrors = sub_type.split(",").map(&:to_i)
|
|
|
sub_mirrors.each do |mirror|
|
|
|
ShixunMirrorRepository.create!(:shixun_id => @shixun.id, :mirror_repository_id => mirror)
|
|
|
ShixunServiceConfig.create!(:shixun_id => @shixun.id, :mirror_repository_id => mirror)
|
|
|
end
|
|
|
end
|
|
|
#自动构建版本库
|
|
|
repository = Repository.new
|
|
|
repository.shixun = @shixun
|
|
|
repository.type = 'Repository::Gitlab'
|
|
|
repository.identifier = @shixun.identifier.downcase
|
|
|
repository.project_id = -1
|
|
|
repository.save!
|
|
|
s = Trustie::Gitlab::Sync.new
|
|
|
gproject = s.create_shixun(@shixun, repository)
|
|
|
raise "版本库创建失败" if @shixun.gpid.blank? # 若和gitlab没同步成功,则抛出异常
|
|
|
g = Gitlab.client
|
|
|
@shixun.update_column(:git_url, g.project(@shixun.gpid).path_with_namespace)
|
|
|
# g = Gitlab.client
|
|
|
# hook_url = Setting.protocol + "://" + Setting.host_name + "/shixuns/#{@shixun.identifier}" + "/ghook"
|
|
|
# g.add_project_hook(@shixun.gpid, hook_url)
|
|
|
redirect_to shixun_path @shixun, notice: l(:notice_successful_create)
|
|
|
rescue Exception => e
|
|
|
respond_to do |format|
|
|
|
flash[:notice] = "#{e.message}"
|
|
|
redirect_to new_shixun_path
|
|
|
raise ActiveRecord::Rollback
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def copy
|
|
|
# 实训设置了能复制并且(平台认证的老师或者实训管理员二选一)
|
|
|
unless (@shixun.can_copy && ((User.current.user_extensions.try(:identity) == 0 && User.current.professional_certification) || User.current.manager_of_shixun?(@shixun)))
|
|
|
render_403
|
|
|
return
|
|
|
end
|
|
|
ActiveRecord::Base.transaction do
|
|
|
begin
|
|
|
raise "请先绑定邮箱" if User.current.mail.blank?
|
|
|
new_shixun = Shixun.new
|
|
|
new_shixun.attributes = @shixun.attributes.dup.except("id","user_id","visits","gpid","status", "identifier", "homepage_show","git_url", "propaedeutics")
|
|
|
new_shixun.user_id = User.current.id
|
|
|
new_shixun.identifier = generate_identifier
|
|
|
new_shixun.status = 0
|
|
|
new_shixun.visits = 1
|
|
|
new_shixun.fork_from = @shixun.id
|
|
|
new_shixun.save!
|
|
|
shixun_major_courses = ShixunMajorCourse.where(:shixun_id => @shixun.id)
|
|
|
if shixun_major_courses.present?
|
|
|
shixun_major_courses.each do |smc|
|
|
|
ShixunMajorCourse.create!(:shixun_id => new_shixun.id, :major_id => smc.major_id, :course_list_id => smc.course_list_id)
|
|
|
end
|
|
|
end
|
|
|
# 同步镜像
|
|
|
if @shixun.mirror_repositories.present?
|
|
|
@shixun.mirror_repositories.each do |mirror|
|
|
|
ShixunMirrorRepository.create!(:shixun_id => new_shixun.id, :mirror_repository_id => mirror.id)
|
|
|
end
|
|
|
end
|
|
|
# 同步技术标签
|
|
|
@shixun.shixun_tag_repertoires.each do |str|
|
|
|
ShixunTagRepertoire.create!(:tag_repertoire_id => str.tag_repertoire_id, :shixun_id => new_shixun.id)
|
|
|
end
|
|
|
|
|
|
# 同步配置
|
|
|
@shixun.shixun_service_configs.each do |config|
|
|
|
ShixunServiceConfig.create!(:shixun_id => new_shixun.id,
|
|
|
:cpu_limit => config.cpu_limit,
|
|
|
:lower_cpu_limit => config.lower_cpu_limit,
|
|
|
:memory_limit => config.memory_limit,
|
|
|
:request_limit => config.request_limit,
|
|
|
:mirror_repository_id => config.mirror_repository_id)
|
|
|
end
|
|
|
|
|
|
# 同步复制版本库,先fork再修改版本库名
|
|
|
# eduforge用户作为版本库的创建者
|
|
|
repository = Repository.new
|
|
|
repository.shixun = new_shixun
|
|
|
repository.type = 'Repository::Gitlab'
|
|
|
repository.identifier = new_shixun.identifier.downcase
|
|
|
repository.project_id = -1
|
|
|
repository.save!
|
|
|
g = Gitlab.client
|
|
|
user_gid = User.find_by_mail("eduforge@163.com").try(:gid)
|
|
|
gshixun = g.fork(@shixun.gpid, user_gid)
|
|
|
raise "版本库创建失败" if gshixun.try(:id).blank?
|
|
|
|
|
|
# gshixun = g.edit_project(gshixun.id, new_shixun.identifier, new_shixun.identifier)
|
|
|
# raise "实训复制失败" if (gshixun.try(:name) != new_shixun.identifier || gshixun.try(:path) != new_shixun.identifier)
|
|
|
new_shixun.update_attributes!(:gpid => gshixun.id, :git_url => gshixun.try(:path_with_namespace))
|
|
|
# 同步复制者至gitlab, 必须要求用户绑定了邮箱
|
|
|
ShixunMember.create!(:user_id => User.current.id, :shixun_id => new_shixun.try(:id), :role => 1)
|
|
|
|
|
|
gid = User.current.try(:gid)
|
|
|
if gid.nil?
|
|
|
s = Trustie::Gitlab::Sync.new
|
|
|
gid = s.sync_user(User.current).try(:id)
|
|
|
end
|
|
|
g.add_team_member(gshixun.id, gid, 40) # 3代表角色master
|
|
|
|
|
|
# # 同步复制合作者,合作者加入到gitlab
|
|
|
# unless User.current.manager_of_shixun?(@shixun)
|
|
|
# ShixunMember.create!(:user_id => User.current.id, :shixun_id => new_shixun.try(:id), :role => 1)
|
|
|
# end
|
|
|
# @shixun.shixun_members.each do |shixun_member|
|
|
|
# if ShixunMember.where(:shixun_id => new_shixun.try(:id), :user_id => shixun_member.user_id).blank?
|
|
|
# ShixunMember.create!(:user_id => shixun_member.try(:user_id), :shixun_id => new_shixun.try(:id),
|
|
|
# :role => (shixun_member.try(:user_id) == User.current.id ? 1 : 2))
|
|
|
# end
|
|
|
# s = Trustie::Gitlab::Sync.new
|
|
|
# gid = User.find(shixun_member.user_id).try(:gid)
|
|
|
# u = s.g.add_team_member(gshixun.id, gid, 40) # 3代表角色master
|
|
|
# if u.blank?
|
|
|
# raise("同步Gitlab数据失败")
|
|
|
# end
|
|
|
# end
|
|
|
# 同步复制关卡
|
|
|
if @shixun.challenges.present?
|
|
|
@shixun.challenges.each do |challenge|
|
|
|
new_challenge = Challenge.new
|
|
|
new_challenge.attributes = challenge.attributes.dup.except("id","shixun_id","user_id")
|
|
|
new_challenge.user_id = User.current.id
|
|
|
new_challenge.shixun_id = new_shixun.id
|
|
|
new_challenge.save!
|
|
|
if challenge.st == 0 # 评测题
|
|
|
# 同步测试集
|
|
|
if challenge.test_sets.present?
|
|
|
challenge.test_sets.each do |test_set|
|
|
|
new_test_set = TestSet.new
|
|
|
new_test_set.attributes = test_set.attributes.dup.except("id","challenge_id")
|
|
|
new_test_set.challenge_id = new_challenge.id
|
|
|
new_test_set.save!
|
|
|
end
|
|
|
end
|
|
|
# 同步关卡标签
|
|
|
challenge_tags = ChallengeTag.where("challenge_id =? and challenge_choose_id is null", challenge.id)
|
|
|
if challenge_tags.present?
|
|
|
challenge_tags.each do |challenge_tag|
|
|
|
ChallengeTag.create!(:challenge_id => new_challenge.id, :name => challenge_tag.try(:name))
|
|
|
end
|
|
|
end
|
|
|
elsif challenge.st == 1 # 选择题
|
|
|
if challenge.challenge_chooses.present?
|
|
|
challenge.challenge_chooses.each do |challenge_choose|
|
|
|
new_challenge_choose = ChallengeChoose.new
|
|
|
new_challenge_choose.attributes = challenge_choose.attributes.dup.except("id","challenge_id")
|
|
|
new_challenge_choose.challenge_id = new_challenge.id
|
|
|
new_challenge_choose.save!
|
|
|
# 每一题的选项
|
|
|
if challenge_choose.challenge_questions.present?
|
|
|
challenge_choose.challenge_questions.each do |challenge_question|
|
|
|
new_challenge_question = ChallengeQuestion.new
|
|
|
new_challenge_question.attributes = challenge_question.attributes.dup.except("id","challenge_choose_id")
|
|
|
new_challenge_question.challenge_choose_id = new_challenge_choose.id
|
|
|
new_challenge_question.save!
|
|
|
end
|
|
|
end
|
|
|
# 每一题的知识标签
|
|
|
st_challenge_tags = ChallengeTag.where(:challenge_id => challenge.id, :challenge_choose_id => challenge_choose.id)
|
|
|
if st_challenge_tags.present?
|
|
|
st_challenge_tags.each do |st_challenge_tag|
|
|
|
ChallengeTag.create!(:challenge_id => new_challenge.id, :name => st_challenge_tag.try(:name), :challenge_choose_id => new_challenge_choose.id)
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
# 中间层创建测试集
|
|
|
#shixun_modify_status_publish(new_shixun, 1)
|
|
|
flash[:notice] = "实训复制成功"
|
|
|
redirect_to shixun_challenges_path(new_shixun)
|
|
|
rescue Exception => e
|
|
|
logger.info("copy shixun failed ##{e.message}")
|
|
|
flash[:notice] = "#{e.message}"
|
|
|
g.delete_project(gshixun.id) if gshixun.try(:id).present? # 异常后,如果已经创建了版本库需要删除该版本库
|
|
|
redirect_to shixun_challenges_path(@shixun)
|
|
|
raise ActiveRecord::Rollback
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def fork_list
|
|
|
@shixuns = Shixun.where(:fork_from => @shixun.id)
|
|
|
@shixuns_count = @shixuns.count
|
|
|
@limit = 16
|
|
|
@is_remote = true
|
|
|
@shixun_pages = Paginator.new @shixuns_count, @limit, params['page'] || 1
|
|
|
@offset ||= @shixun_pages.offset
|
|
|
@shixuns = paginateHelper @shixuns, @limit
|
|
|
end
|
|
|
|
|
|
def show
|
|
|
# 如果是从TPI中退出,则更新TPI时间
|
|
|
# 更新时间是为了TPM端显示的更新,退出实训及访问实训的时候会更新
|
|
|
if params[:exit] && !User.current.admin?
|
|
|
@shixun.myshixuns.where(:user_id => User.current).first.update_column(:updated_at, Time.now)
|
|
|
end
|
|
|
respond_to do |format|
|
|
|
format.html{redirect_to shixun_challenges_path(@shixun)}
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def generate_identifier
|
|
|
code = DCODES.sample(8).join
|
|
|
return generate_identifier if Shixun.where(identifier: code).present?
|
|
|
code
|
|
|
end
|
|
|
|
|
|
def down_generate_identifier type
|
|
|
if type == "game"
|
|
|
code = DCODES.sample(12).join
|
|
|
return down_generate_identifier(type) if Game.where(identifier: code).present?
|
|
|
elsif type == "myshixun"
|
|
|
code = DCODES.sample(10).join
|
|
|
return down_generate_identifier(type) if Myshixun.where(identifier: code).present?
|
|
|
end
|
|
|
code
|
|
|
end
|
|
|
|
|
|
def edit
|
|
|
end
|
|
|
|
|
|
def update
|
|
|
logger.info("#######-----#{params[:config]}")
|
|
|
@shixun.attributes = params[:shixun]
|
|
|
#@shixun.language = params[:language]
|
|
|
@shixun.trainee = params[:trainee]
|
|
|
@shixun.webssh = params[:webssh].to_i
|
|
|
@shixun.multi_webssh = @shixun.webssh == 2 && params[:multi_webssh] == "1" ? 1 : 0
|
|
|
@shixun.vnc = params[:vnc].to_i
|
|
|
@shixun.can_copy = params[:can_copy].to_i
|
|
|
@shixun.test_set_permission = params[:test_set_permission].to_i
|
|
|
@shixun.code_hidden = params[:code_hidden].to_i
|
|
|
@shixun.task_pass = params[:task_pass].to_i
|
|
|
@shixun.mirror_script_id = params[:mirror_script].to_i
|
|
|
@shixun.hide_code = params[:hide_code].to_i
|
|
|
@shixun.forbid_copy = params[:forbid_copy].to_i
|
|
|
if params[:public_degree]
|
|
|
use_scope = params[:public_degree].to_i
|
|
|
else
|
|
|
use_scope = @shixun.use_scope
|
|
|
end
|
|
|
mirror_ids = (@shixun.shixun_mirror_repositories.blank? ? [] : @shixun.shixun_mirror_repositories.map(&:id))
|
|
|
update_miiror_id = []
|
|
|
@shixun.shixun_mirror_repositories.destroy_all
|
|
|
|
|
|
if params[:main_type].present?
|
|
|
update_miiror_id << params[:main_type].to_i
|
|
|
ShixunMirrorRepository.create(:shixun_id => @shixun.id, :mirror_repository_id => params[:main_type])
|
|
|
end
|
|
|
if params[:small_type].present?
|
|
|
sub_mirrors = params[:small_type].split(",").map(&:to_i)
|
|
|
sub_mirrors.each do |mirror|
|
|
|
update_miiror_id << mirror
|
|
|
ShixunMirrorRepository.create(:shixun_id => @shixun.id, :mirror_repository_id => mirror)
|
|
|
end
|
|
|
end
|
|
|
# 超级管理员才能保存 中间层服务器pod信息的配置
|
|
|
@shixun.shixun_service_configs.destroy_all
|
|
|
params[:mirror_id].each_with_index do |mirror_id, index|
|
|
|
ShixunServiceConfig.create!(:shixun_id => @shixun.id,
|
|
|
:cpu_limit => params[:cpu_limit][index],
|
|
|
:lower_cpu_limit => params[:lower_cpu_limit][index],
|
|
|
:memory_limit => params[:memory_limit][index],
|
|
|
# :resource_limit => params[:resource_limit][index],
|
|
|
:request_limit => params[:request_limit][index],
|
|
|
:mirror_repository_id => mirror_id)
|
|
|
end
|
|
|
|
|
|
ActiveRecord::Base.transaction do
|
|
|
begin
|
|
|
@shixun.save!
|
|
|
@shixun.shixun_schools.delete_all
|
|
|
if params[:scope_partment].present? && use_scope == 1
|
|
|
arr = []
|
|
|
@shixun.schools
|
|
|
ids = School.where(:name => params[:scope_partment]).map(&:id).uniq
|
|
|
ids.each do |id|
|
|
|
arr << { :school_id => id, :shixun_id => @shixun.id }
|
|
|
end
|
|
|
ShixunSchool.create!(arr)
|
|
|
else
|
|
|
use_scope = 0
|
|
|
end
|
|
|
@shixun.update_attributes!(:use_scope => use_scope)
|
|
|
rescue
|
|
|
@error = "实训保存失败"
|
|
|
raise ActiveRecord::Rollback
|
|
|
end
|
|
|
end
|
|
|
respond_to do |format|
|
|
|
format.js
|
|
|
format.html{redirect_to settings_shixun_path(@shixun)}
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def shixun_discuss
|
|
|
if User.current.logged?
|
|
|
render file: 'public/react/build/index.html', :layout => false
|
|
|
else
|
|
|
redirect_to signin_path
|
|
|
end
|
|
|
|
|
|
# @discusses = @shixun.discusses.reorder("created_at desc")
|
|
|
# @discusses_num = @discusses.count
|
|
|
# @discusses = get_no_children_comments_all @discusses
|
|
|
# @discusses_count = @discusses.count
|
|
|
# @limit = 15
|
|
|
# @is_remote = true
|
|
|
# @discusses_pages = Paginator.new @discusses_count, @limit, params['page'] || 1
|
|
|
# @offset ||= @discusses_pages.offset
|
|
|
# @discusses = paginateHelper @discusses, @limit
|
|
|
# #@game_challenge = params[:challenge_id].blank? ? Challenge.find(@discusses.first.try(:challenge_id)) : Challenge.find(params[:challenge_id])
|
|
|
# challenge_id = params[:challenge_id].nil? ? @shixun.challenges.first.try(:id) : params[:challenge_id].to_i
|
|
|
# @game_challenge = Challenge.find(challenge_id)
|
|
|
# @praise = PraiseTread.where("praise_tread_object_id=? and praise_tread_object_type=? and praise_or_tread=? and user_id=?", @game_challenge.id, @game_challenge.class.to_s, 1, User.current.id).first
|
|
|
# @tread = PraiseTread.where("praise_tread_object_id=? and praise_tread_object_type=? and praise_or_tread=? and user_id=?", @game_challenge.id, @game_challenge.class.to_s, 0, User.current.id).first
|
|
|
# @praise_count = PraiseTread.where(:praise_tread_object_id => @game_challenge.id, :praise_tread_object_type => "Challenge", :praise_or_tread => 1).count
|
|
|
# @tread_count = PraiseTread.where(:praise_tread_object_id => @game_challenge.id, :praise_tread_object_type => "Challenge", :praise_or_tread => 0).count
|
|
|
#
|
|
|
# respond_to do |format|
|
|
|
# format.js
|
|
|
# format.html
|
|
|
# end
|
|
|
end
|
|
|
|
|
|
def destroy
|
|
|
render_403 if @shixun.status > 1 && !User.current.admin?
|
|
|
ActiveRecord::Base.transaction do
|
|
|
g = Gitlab.client
|
|
|
g.delete_project(@shixun.gpid) if @shixun.try(:gpid).present?
|
|
|
apply_record = ApplyAction.where(:container_id => @shixun.id, :container_type => "ApplyShixun")
|
|
|
apply_record.delete_all if apply_record
|
|
|
#HomeworkCommonsShixuns.where(:shixun_id => @shixun).delete_all # 关联删报错,后续解决
|
|
|
@shixun.update_attribute(:status, -1)
|
|
|
respond_to do |format|
|
|
|
if params[:come_from] == "admin"
|
|
|
format.html{ redirect_to shixuns_managements_path }
|
|
|
else
|
|
|
format.html{ redirect_to user_path(User.current) }
|
|
|
end
|
|
|
format.js
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def settings
|
|
|
@edit = params[:edit]
|
|
|
@repository = Repository.where(:shixun_id => @shixun, :type => "Repository::Gitlab").first
|
|
|
@main_type = MirrorRepository.published_main_mirror
|
|
|
@small_type = MirrorRepository.published_small_mirror
|
|
|
@shixun_main_mirror = @shixun.mirror_repositories.published_main_mirror.first
|
|
|
# 权限
|
|
|
logger.info("###########{User.current.admin?}")
|
|
|
logger.info("#########business:##{User.current.business?}")
|
|
|
@power = (@shixun.status < 2 ? true : ( User.current.admin? ? true : false))
|
|
|
# unless @repository.nil?
|
|
|
# gitlab_address = Redmine::Configuration['gitlab_address']
|
|
|
# login = User.find_by_mail("educoder@163.com").try(:login)
|
|
|
# @repos_url = gitlab_url @shixun
|
|
|
# end
|
|
|
respond_to do |format|
|
|
|
format.html
|
|
|
format.js
|
|
|
end
|
|
|
end
|
|
|
|
|
|
# 添加实训脚本
|
|
|
def add_script
|
|
|
if @shixun.update_attribute(:script, params[:shixun_script])
|
|
|
@notice = "脚本添加成功"
|
|
|
else
|
|
|
@notice = "脚本添加失败"
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def get_mirror_script
|
|
|
mirror = MirrorRepository.find(params[:mirror_id])
|
|
|
script = mirror.mirror_scripts if mirror
|
|
|
render :json => script
|
|
|
end
|
|
|
|
|
|
def get_script_contents
|
|
|
if params[:script_id].to_i == -1
|
|
|
render :json => {contents: "", description: ""}
|
|
|
else
|
|
|
mirrir_script = MirrorScript.find(params[:script_id])
|
|
|
script = mirrir_script.try(:script)
|
|
|
description = mirrir_script.try(:description)
|
|
|
script = modify_shixun_script @shixun, script
|
|
|
render :json => {contents: script, description: description}
|
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
def get_common_script
|
|
|
shixun_script = PlatformSample.where(:samples_type => "script").first.try(:contents)
|
|
|
compile = params[:compile]
|
|
|
execute = params[:executive]
|
|
|
if shixun_script
|
|
|
shixun_script = compile.blank? ? shixun_script.gsub("COMPILEFUNCTION", "").gsub("CHALLENGEFIELPATH", "") : shixun_script.gsub("COMPILEFUNCTION", "#{compile_command}").gsub("COMPILECOMMAND", "#{compile}")
|
|
|
shixun_script = execute.blank? ? shixun_script.gsub("EXECUTEFUNCTION", "") : shixun_script.gsub("EXECUTECOMMAND", "#{execute}")
|
|
|
shixun_script = modify_shixun_script @shixun, shixun_script
|
|
|
end
|
|
|
render :json => {contents: shixun_script}
|
|
|
end
|
|
|
|
|
|
# 创建实训job
|
|
|
def shixun_job_create
|
|
|
if @shixun.challenges.count == 0
|
|
|
@notice = "实训开启失败:请先发布实训任务"
|
|
|
return
|
|
|
elsif Repository.where(:shixun_id => @shixun.id, :type => "Repository::Gitlab").count == 0
|
|
|
@notice = "实训开启失败:请先创建版本库"
|
|
|
return
|
|
|
end
|
|
|
@shixun.update_attribute(:status, 1)
|
|
|
end
|
|
|
|
|
|
# 更新实训job
|
|
|
def shixun_job_update
|
|
|
# jobName = "#{@shixun.id}"
|
|
|
# pipeLine = "#{Base64.encode64(@shixun.script)}"
|
|
|
# uri = URI("http://123.59.135.74:9999/jenkins-exec/api/updateJob")
|
|
|
# params = {jobName: jobName, pipeLine: pipeLine}
|
|
|
# res = uri_exec uri, params
|
|
|
training_shixun_notice res
|
|
|
if res['code'] == 0
|
|
|
@shixun.update_attribute(:status, 1)
|
|
|
end
|
|
|
end
|
|
|
|
|
|
# Find shixun of id params[:id]
|
|
|
def find_shixun
|
|
|
@shixun = Shixun.find_by_identifier(params[:id])
|
|
|
render_404 if @shixun.nil? || @shixun.status == -1
|
|
|
rescue ActiveRecord::RecordNotFound
|
|
|
render_404
|
|
|
end
|
|
|
|
|
|
def monitor_filter
|
|
|
if User.current.id == @shixun.user_id
|
|
|
@notice = l(:label_shixun_mine)
|
|
|
else
|
|
|
if has_exec_cur_shixun(@shixun)
|
|
|
@notice = l(:label_shixun_had_forked)
|
|
|
@had_exec = true
|
|
|
else
|
|
|
@notice = l(:label_shixun_exec)
|
|
|
@had_exec = false
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
|
|
|
# 实训行为操作
|
|
|
def operation
|
|
|
@is_subject = params[:is_subject]
|
|
|
@myshixun = Myshixun.where(:id => params[:myshixun_id]).first
|
|
|
@is_modify = ShixunModify.where(:myshixun_id => params[:myshixun_id], :shixun_id => @shixun.try(:id), :status => 1).first
|
|
|
@mail = User.current.mail.blank?
|
|
|
# @challenge_count = @shixun.challenges.count
|
|
|
# @git_commit = Gitlab.client.trees(@shixun.gpid).count.to_i
|
|
|
|
|
|
@choice_shixun = @shixun.is_choice_type
|
|
|
unfinish_challenge = @shixun.challenges.where(:path => nil, :st => 0) # 学员任务文件是否为空
|
|
|
if unfinish_challenge.count > 0 && !@shixun.is_choice_type
|
|
|
@pos = []
|
|
|
unfinish_challenge.each do |challenge|
|
|
|
@pos << challenge.position
|
|
|
end
|
|
|
@pos = @pos.join(",")
|
|
|
end
|
|
|
end
|
|
|
|
|
|
# 实训的发送至课堂:搜索课堂
|
|
|
def search_user_courses
|
|
|
@user = User.current
|
|
|
if !params[:search].nil?
|
|
|
search = "%#{params[:search].to_s.strip.downcase}%"
|
|
|
@courses = @user.courses.not_deleted_not_end.where("#{Course.table_name}.name like :p",:p=>search).select{|course| @user.has_teacher_role(course)}
|
|
|
else
|
|
|
@courses = @user.courses.not_deleted_not_end.select{|course| @user.has_teacher_role(course)}
|
|
|
end
|
|
|
@pages = Paginator.new @courses.count, 8, params['page'] || 1
|
|
|
@offset ||= @pages.offset
|
|
|
@courses = paginateHelper @courses, 8
|
|
|
respond_to do |format|
|
|
|
format.js
|
|
|
end
|
|
|
end
|
|
|
|
|
|
# 将实训发送到课程
|
|
|
def send_to_course
|
|
|
course = Course.where(:id => params[:course]).first
|
|
|
if course.present?
|
|
|
homework = HomeworkCommon.new
|
|
|
homework.name = @shixun.name
|
|
|
homework.description = @shixun.description
|
|
|
homework.anonymous_comment = 1
|
|
|
homework.homework_type = 4
|
|
|
homework.late_penalty = 0
|
|
|
homework.teacher_priority = 1
|
|
|
homework.user_id = User.current.id
|
|
|
homework.course_id = params[:course]
|
|
|
|
|
|
homework_detail_manual = HomeworkDetailManual.new
|
|
|
homework_detail_manual.te_proportion = 1.0
|
|
|
homework_detail_manual.ta_proportion = 0
|
|
|
homework_detail_manual.comment_status = 0
|
|
|
|
|
|
homework_detail_manual.evaluation_num = 0
|
|
|
homework_detail_manual.absence_penalty = 0
|
|
|
homework.homework_detail_manual = homework_detail_manual
|
|
|
if homework.save!
|
|
|
homework_detail_manual.save if homework_detail_manual
|
|
|
HomeworkCommonsShixuns.create(:homework_common_id => homework.id, :shixun_id => @shixun.id)
|
|
|
create_shixun_homework_cha_setting homework, @shixun
|
|
|
create_works_list homework
|
|
|
redirect_to homework_common_index_path(:course => course.id, :homework_type => 4)
|
|
|
end
|
|
|
else
|
|
|
render_404
|
|
|
end
|
|
|
end
|
|
|
private
|
|
|
def view_allow
|
|
|
shixun_view_allow @shixun
|
|
|
end
|
|
|
|
|
|
# REDO: 新增类型copy的时候
|
|
|
# 复制项目
|
|
|
# gshixun --> gitlab project
|
|
|
# CODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z)
|
|
|
def copy_myshixun shixun, gshixun
|
|
|
myshixun = Myshixun.new
|
|
|
# myshixun.attributes = shixun.attributes.dup.except("id","user_id","visits","gpid","status", "identifier","propaedeutics")
|
|
|
myshixun.shixun_id = shixun.id
|
|
|
myshixun.user_id = User.current.id
|
|
|
myshixun.gpid = gshixun.id
|
|
|
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
|
|
|
if myshixun.save!
|
|
|
# 为了避免fork多次的问题
|
|
|
if gshixun.try(:name).include?("-")
|
|
|
logger.info("***** gshixun name is #{gshixun.try(:name)}")
|
|
|
@g.delete_project(gshixun.id)
|
|
|
gshixun = @g.project(myshixun.gpid)
|
|
|
myshixun.update_column(:gpid, gshixun.id)
|
|
|
end
|
|
|
code = down_generate_identifier("myshixun")
|
|
|
myshixun.update_attribute(:identifier, code)
|
|
|
rep = Repository.new(:myshixun_id => myshixun.id, :identifier => gshixun.name,:project_id => -1, :shixun_id => -2)
|
|
|
rep.type = "Repository::Gitlab"
|
|
|
rep.save!
|
|
|
login = User.find_by_mail("educoder@163.com").try(:login)
|
|
|
rep_url = Base64.urlsafe_encode64(gitlab_url shixun)
|
|
|
uri = "#{shixun_tomcat}/bridge/game/openGameInstance"
|
|
|
params = {tpiID: "#{myshixun.id}", tpmID: "#{shixun.id}", instanceGitURL:rep_url, operationEnvironment:"#{shixun.try(:language)}"}
|
|
|
logger.info("openGameInstance params is #{params}")
|
|
|
res = uri_exec uri, params
|
|
|
if (res && res['code'].to_i != 0)
|
|
|
raise("实训云平台繁忙(繁忙等级:83)")
|
|
|
end
|
|
|
return myshixun
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def training_shixun_notice res
|
|
|
if res['code'] == 0
|
|
|
@notice = "实训开启成功"
|
|
|
else
|
|
|
@notice = res['msg'].nil? ? "实训开启失败" : res['msg']
|
|
|
end
|
|
|
end
|
|
|
|
|
|
# 实训管理员或者超级管理员
|
|
|
def require_manager
|
|
|
render_403 unless User.current.manager_of_shixun?(@shixun)
|
|
|
end
|
|
|
|
|
|
def validation_email
|
|
|
render_403 if User.current.mail.blank?
|
|
|
end
|
|
|
|
|
|
def validate_shixun
|
|
|
|
|
|
end
|
|
|
end
|