# 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 : '18711011226' , 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