# 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 + " 申请了新镜像:#{params[:notes]}"
# 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 + " 申请发布实训:#{@shixun.name}"
# 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?
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)
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
# 同步复制版本库,先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
@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
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
# 权限
@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