educoder/app/controllers/shixuns_controller.rb

938 lines
36 KiB
Ruby
Raw Normal View History

2017-04-07 10:16:13 +08:00
# encoding: utf-8
# REDO: 创建版本库权限控制
class ShixunsController < ApplicationController
layout 'base_shixun'
2017-08-24 14:36:46 +08:00
before_filter :require_login, :except => [:ghook]
before_filter :check_authentication, :except => [:ghook]
before_filter :find_shixun, :except => [ :index, :new, :create, :index, :search, :shixun_courses, :new_disscuss, :shixun_migrate]
2017-08-24 14:36:46 +08:00
skip_before_filter :verify_authenticity_token, :only => [:ghook]
2017-04-07 10:16:13 +08:00
before_filter :shixun_view_allow, :only => [:show]
2017-05-19 17:30:30 +08:00
before_filter :require_manager, :only => [ :settings, :add_script, :publish, :collaborators_delete, :shixun_members_added, :add_collaborators]
2017-08-15 09:57:03 +08:00
before_filter :validation_email, :only => [:new]
2017-04-07 10:16:13 +08:00
include ApplicationHelper
2017-08-22 09:20:25 +08:00
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)
2017-04-07 10:16:13 +08:00
def statistics_students
2017-09-22 20:54:43 +08:00
@statistics = @shixun.myshixuns.order("created_at desc")
@statistics_count = @statistics.count
@limit = 10
@is_remote = true
@statistic_pages = Paginator.new @statistics_count, @limit, params['page'] || 1
@offset ||= @statistic_pages.offset
@statistics = paginateHelper @statistics, @limit
end
2017-09-21 15:20:39 +08:00
2017-08-21 14:41:33 +08:00
# push代码的时候会触发gitlab hook
2017-08-22 16:50:07 +08:00
def ghook
2017-09-18 15:25:34 +08:00
# shixun_modify_status_without_publish(@shixun, 1)
2017-08-21 14:41:33 +08:00
render :json => {status: "success"}
end
def shixun_migrate
unless User.current.admin?
render_403
return
end
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
if params[:shixun_id]
shixuns = Shixun.where(:id => params[:shixun_id])
else
shixuns = Shixun.all
end
shixuns.each do |shixun|
2017-08-11 15:15:07 +08:00
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 = git_myshixun_url_ip(myshixun, myshixun.try(:user_id))
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']}")
2017-08-11 15:15:07 +08:00
rescue Exception => e
logger.info("error ====> #{e.message}")
end
end
end
2017-07-03 17:06:55 +08:00
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
2017-07-06 09:46:54 +08:00
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
2017-07-05 14:16:02 +08:00
def game_webssh
end
2017-07-07 11:04:53 +08:00
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)
2017-07-07 11:04:53 +08:00
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, :content => params[:content], :file_path => @path, :branch_name => @rev, :commit_message => "shixun entry")
if @shixun.try(:status).to_i < 2
shixun_modify_status_without_publish(@shixun, 1)
end
2017-07-07 11:04:53 +08:00
respond_to do |format|
format.js
end
end
2017-07-05 14:16:02 +08:00
2017-04-07 10:16:13 +08:00
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
2017-04-07 10:16:13 +08:00
2017-05-02 17:18:34 +08:00
def statistics
@challenges = @shixun.challenges
@top_students = @shixun.myshixuns.where(:status => 1)
2017-05-02 17:18:34 +08:00
myshixuns = @shixun.myshixuns.includes(:games)
@latest_myshixuns = myshixuns.order("created_at desc").limit(4)
end
2017-06-06 14:17:07 +08:00
def autocompletion
end
2017-04-24 14:42:54 +08:00
def index
@order = "myshixun_count"
@sort = "asc"
2017-06-30 16:36:07 +08:00
search = params[:search]
2017-08-15 09:15:09 +08:00
@mail = User.current.mail.blank?
@shixun_all_count = Shixun.where(:hidden => 0).count
@shixuns = Shixun.where("name like ? and hidden = 0", "%#{search}%")
# @shixuns.each do |shixun|
# shixun[:myshixunCount] = shixun.myshixuns.count
# end
# @shixuns = @shixuns.sort{|x, y| y[:myshixunCount] <=> x[:myshixunCount]}
@shixuns = @shixuns.select("shixuns.*, (select count(myshixuns.id) from myshixuns where myshixuns.shixun_id = shixuns.id group by shixuns.id) AS myshixunCount").reorder("status = 2 desc, myshixunCount desc")
2017-06-30 16:36:07 +08:00
@shixun_my_score = Experience.find_by_sql("SELECT sum(score) as score FROM `experiences` where user_id=#{User.current.id}").first.try(:score).to_i
@current_user_had_passed = Myshixun.find_by_sql("select count(*) as had_passed from myshixuns where status =1 and user_id=#{User.current.id}
2017-06-30 16:36:07 +08:00
and shixun_id in (SELECT id FROM `shixuns` where status > 1)").first.try(:had_passed).to_i
2017-09-08 20:30:25 +08:00
#@majors = Major.where(:id => [635, 636, 637, 638, 639, 622, 619])
@courses = CourseList.where(:support_shixuns_search => 1)
2017-04-24 17:29:38 +08:00
@shixuns_count = @shixuns.count
2017-06-02 19:21:09 +08:00
@limit = 16
@is_remote = true
@shixun_pages = Paginator.new @shixuns_count, @limit, params['page'] || 1
@offset ||= @shixun_pages.offset
@shixuns = paginateHelper @shixuns, @limit
2017-04-24 14:42:54 +08:00
render :layout => "base_edu"
end
def propaedeutics
respond_to do |format|
format.html
end
end
2017-06-23 08:57:56 +08:00
def update_propaedeutics
@shixun = Shixun.where(:identifier => params[:id]).first
@shixun.update_attribute("propaedeutics", params[:shixun][:propaedeutics])
redirect_to propaedeutics_shixun_path(@shixun)
end
2017-05-19 16:56:09 +08:00
def collaborators
@collaborators = @shixun.collaborators
end
2017-05-19 17:14:15 +08:00
def collaborators_delete
user_id = params[:c_id]
gid = User.find(user_id).try(:gid)
2017-05-19 17:14:15 +08:00
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
2017-05-19 17:14:15 +08:00
@collaborators = @shixun.collaborators
respond_to do |format|
format.js
end
end
2017-05-19 16:56:09 +08:00
# 已存在的成员不添加
def add_collaborators
if !params[:search].nil?
# members = searchTeacherAndAssistant @course
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)) LIKE '#{condition}'").includes(:user_extensions)
2017-05-19 16:56:09 +08:00
end
respond_to do |format|
format.js
end
end
# 事务处理保证Trustie与Gitlab数据同步
2017-05-19 16:56:09 +08:00
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?
2017-09-22 09:52:13 +08:00
raise("同步Gitlab数据失败")
end
end
@collaborators = @shixun.collaborators
respond_to do |format|
format.js
end
end
rescue Exception => e
logger.error(e)
raise ActiveRecord::Rollback
2017-05-19 16:56:09 +08:00
end
end
end
2017-04-27 10:18:15 +08:00
def search
2017-04-25 14:18:52 +08:00
# 确定 sort 1升序 2 降序
2017-08-08 09:32:46 +08:00
@order = params[:order] || "myshixun_count"
2017-07-07 16:17:45 +08:00
bsort = params[:sort] || "desc"
2017-09-25 11:16:16 +08:00
@sort = bsort == "asc" ? "desc" : "asc"
if @order == "updated_at"
2017-09-25 11:16:16 +08:00
order_str = "#{Shixun.table_name}.updated_at #{@sort}"
else
2017-07-07 16:17:45 +08:00
order_str = "myshixun_count #{bsort}, #{Shixun.table_name}.updated_at #{bsort}"
end
2017-06-02 15:17:13 +08:00
@language = params[:language]
2017-06-01 15:20:12 +08:00
@status = params[:status].to_i
@shixun_status = params[:shixun_status] # 2是已发布 3是未发布
@search = params[:search]
2017-09-08 20:30:25 +08:00
#@major = params[:major]
2017-07-07 16:17:45 +08:00
@course = params[:course]
@trainee = params[:trainee]
#ids = Shixun.find_by_sql("select group_concat(id) as allId from shixuns where id in (SELECT distinct(shixun_id) FROM `challenges`)")
# @shixuns = Shixun.where("hidden = 0").reorder("updated_at desc")
@shixuns = Shixun.where("hidden = 0")
2017-07-14 12:37:20 +08:00
@shixuns = @shixuns.where(:language => @language) unless @language.blank?
2017-07-07 16:17:45 +08:00
@shixuns = @shixuns.where("name like ?", "%#{@search}%") unless @search.blank?
2017-09-08 20:30:25 +08:00
# if !@major.blank?
# @shixuns = @shixuns.where(:major_id => @major.to_i)
# @courses = CourseList.where(:id => MajorCourse.where(:major_id => @major).map(&:course_list_id))
# else
# @courses = CourseList.where(:id => MajorCourse.where(:major_id => [635, 636, 637, 638, 639, 622, 619]).map(&:course_list_id))
# end
@courses = CourseList.where(:support_shixuns_search => 1)
#if !@course.blank? && (@major.blank? || MajorCourse.where(:major_id => @major, :course_list_id => @course).count == 1)
if !@course.blank?
@shixuns = @shixuns.where(:id => ShixunMajorCourse.where(:course_list_id => @course).map(&:shixun_id))
2017-07-07 16:17:45 +08:00
end
2017-09-08 20:30:25 +08:00
# if !@major.blank? && MajorCourse.where(:major_id => @major, :course_list_id => @course).count == 0
# @course = nil
# end
2017-07-07 16:17:45 +08:00
@shixuns = @shixuns.where(:trainee => @trainee) unless @trainee.blank?
case @status
when 1, 0
@shixuns = @shixuns
when 2
@shixuns = @shixuns.where(:user_id => User.current)
when 3
shixun_ids = Myshixun.where(:user_id => User.current).blank? ? "(-1)" : "(" + Myshixun.where(:user_id => User.current).map(&:shixun_id).join(',') +")"
@shixuns = @shixuns.where("id not in #{shixun_ids}")
when 4
shixun_ids = Myshixun.where(:user_id => User.current, :status => 0).map(&:shixun_id)
@shixuns = @shixuns.where(:id => shixun_ids)
when 5
shixun_ids = Myshixun.where(:user_id => User.current, :status => 1).map(&:shixun_id)
@shixuns = @shixuns.where(:id => shixun_ids)
end
case @shixun_status
when "1"
@shixuns = @shixuns.where(:status => [0, 1])
when "2"
@shixuns = @shixuns.where(:status => 2)
when "3"
@shixuns = @shixuns.where(:status => 3)
when nil, "0"
@shixuns = @shixuns
end
2017-08-11 19:29:44 +08:00
if @order == "updated_at"
@shixuns =@shixuns.reorder(order_str)
else
# 最热排序
# @shixuns.each do |shixun|
# shixun[:myshixunCount] = shixun.myshixuns.count
# end
@shixuns = @shixuns.select("shixuns.*, (select count(myshixuns.id) from myshixuns where myshixuns.shixun_id = shixuns.id group by shixuns.id) AS myshixunCount").reorder("status = 2 desc, myshixunCount #{bsort}")
#@shixuns = @shixuns.reorder("status = 2 #{bsort}, myshixunCount #{bsort}")
# if bsort == "desc"
# @shixuns = @shixuns.sort{|x, y| y[:myshixunCount] <=> x[:myshixunCount]}
# else
# @shixuns = @shixuns.sort{|x, y| x[:myshixunCount] <=> y[:myshixunCount]}
# end
end
# @shixuns = Shixun.where(:authentication => 1).reorder(order)
@shixuns_count = @shixuns.count
2017-06-02 19:21:09 +08:00
@limit = 16
@is_remote = true
@shixun_pages = Paginator.new @shixuns_count, @limit, params['page'] || 1
@offset ||= @shixun_pages.offset
@shixuns = paginateHelper @shixuns, @limit
respond_to do |format|
format.js
end
2017-04-25 14:18:52 +08:00
end
# jenkins回调脚本
2017-04-16 17:20:47 +08:00
# gameID 及实训ID
def publish
begin
2017-08-07 15:56:04 +08:00
@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
2017-04-17 15:30:31 +08:00
else
2017-08-07 15:56:04 +08:00
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)
@status = 1
end
rescue Exception => e
2017-06-19 17:27:11 +08:00
@jenkin_error = true
logger.error("pushlish game #{e}")
respond_to do |format|
format.js
end
2017-04-07 10:16:13 +08:00
end
end
2017-06-21 17:26:49 +08:00
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
2017-06-30 21:00:13 +08:00
apply = ApplyAction.where(:container_type => "ApplyShixun", :container_id => @shixun.id).order("created_at desc").first
2017-06-21 17:26:49 +08:00
if apply && apply.status == 0
apply.update_attributes(:status => 3)
@shixun.update_column('status', 0)
end
redirect_to shixun_path(@shixun)
end
def close
@shixun.update_column('status', 3)
redirect_to shixun_path(@shixun)
end
2017-04-07 10:16:13 +08:00
# copy_shixun复制一个新的实训模块包括版本库
# copy_myshixun自动创建系列game,game中只包含状态等信息公共信息从Challeges中读取
# 开启过实训的则直接跳入my实训页面
2017-04-07 10:16:13 +08:00
def shixun_exec
unless allow_shixun_exec(@shixun) && (User.current.manager_of_shixun?(@shixun) || @shixun.status > 0)
2017-04-07 10:16:13 +08:00
render_403
return
2017-04-07 10:16:13 +08:00
end
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 myshixun_game_path(myshixun.current_task, :myshixun_id => myshixun, :is_subject => params[:is_subject])
return
end
2017-04-07 10:16:13 +08:00
ActiveRecord::Base.transaction do
begin
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
code = down_generate_identifier("myshixun")
myshixun = Myshixun.create!(:shixun_id => @shixun.id, :user_id => User.current.id, :identifier => code)
# fork版本库如果用户没有同步则先同步用户
g = Gitlab.client
2017-06-23 15:13:45 +08:00
if User.current.gid.nil?
s = Trustie::Gitlab::Sync.new
s.sync_user(User.current)
end
gshixun = g.fork(@shixun.gpid, User.current.gid)
if !gshixun.try(:id).blank?
myshixun.update_column(:gpid, gshixun.id) if myshixun.try(:gpid).blank? # 为了防止多次fork
rep = Repository.create!(:myshixun_id => myshixun.id, :identifier => gshixun.name,:project_id => -1, :shixun_id => -2)
rep.update_column(:type, "Repository::Gitlab")
2017-09-22 11:23:57 +08:00
rep_url = Base64.urlsafe_encode64(git_shixun_url_ip @shixun, (@shixun.try(:fork_from).blank? ? "educoder" : "eduforge")) # 注意educoder为默认给实训创建版本库的用户如果换成别的用户名字要相应的修改
2017-09-19 17:25:03 +08:00
logger.info("start openGameInstance")
uri = "#{shixun_tomcat}/bridge/game/openGameInstance"
2017-09-19 17:25:03 +08:00
logger.info("end 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
# 其它操作
2017-06-23 15:13:45 +08:00
challenges = @shixun.challenges
# 之所以增加user_id是为了方便统计查询性能
challenges.each_with_index do |challenge, index|
status = (index == 0 ? 0 : 3)
2017-08-10 10:00:11 +08:00
code = down_generate_identifier("game")
2017-06-23 15:13:45 +08:00
game =Game.create!(:challenge_id => challenge.id, :myshixun_id => myshixun.id, :status => status, :user_id => myshixun.user_id, :open_time => Time.now, :identifier => code)
# 记录刚开始时默认代开文件原始代码
# 刚开始fork的一段时间是获取不了content内容的
game_passed_code(game.try(:id), challenge.try(:path), myshixun.try(:gpid), 0)
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
2017-06-23 15:13:45 +08:00
else
raise("实训云平台繁忙繁忙等级81")
end
logger.info("myshixun id si #{myshixun.id} and current_task id is#{myshixun.current_task.id}")
redirect_to myshixun_game_path(myshixun.current_task, :myshixun_id => myshixun, :is_subject => params[:is_subject])
2017-04-07 10:16:13 +08:00
rescue Exception => e
flash[:error] = e.message
logger.info("failed to exec shixun: current task id is #{e}")
2017-09-08 15:49:48 +08:00
g.delete_project(gshixun.id) if !gshixun.id.nil?
redirect_to shixun_challenges_path(@shixun)
2017-04-07 10:16:13 +08:00
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
2017-04-07 10:16:13 +08:00
def new
@shixun = Shixun.new
2017-08-25 16:11:35 +08:00
@support = Major.where(:support_shixuns=> 1)
2017-04-07 10:16:13 +08:00
respond_to do |format|
2017-05-17 17:19:16 +08:00
format.html{render :layout => 'base_edu'}
2017-04-07 10:16:13 +08:00
format.json
end
end
def create
2017-04-25 17:15:37 +08:00
identifier = generate_identifier
2017-04-07 10:16:13 +08:00
@shixun = Shixun.new(params[:shixun])
@shixun.user_id = User.current.id
@shixun.language = params[:language]
#@shixun.major_id = params[:major_id]
@shixun.trainee = params[:trainee]
@shixun.webssh = params[:webssh].to_i
2017-09-21 17:25:51 +08:00
@shixun.can_copy = params[:can_copy].to_i
2017-04-25 17:15:37 +08:00
@shixun.identifier = identifier
# if params[:course_id]
# params[:course_id].each do |course_id|
# @shixun.shixun_major_courses << ShixunMajorCourse.new(:major_id => params[:major_id], :course_list_id => course_id)
# end
# end
if CourseList.where(:name => params[:course_list].strip).count > 0
@shixun.shixun_major_courses << ShixunMajorCourse.new(:major_id => -1, :course_list_id => CourseList.where(:name => params[:course_list].strip).first.id)
else
course_list = CourseList.create(:name => params[:course_list].strip, :user_id => User.current.id, :is_admin => 0)
@shixun.shixun_major_courses << ShixunMajorCourse.new(:major_id => -1, :course_list_id => course_list.id)
end
2017-04-07 10:16:13 +08:00
(params[:shixun][:is_public] == "1" ? @shixun.is_public = true : @shixun.is_public = false)
ActiveRecord::Base.transaction do
begin
@shixun.save!
2017-04-07 10:16:13 +08:00
m = ShixunMember.new(:user_id => User.current.id, :role => 1)
@shixun.shixun_members << m
2017-05-08 15:28:35 +08:00
# 自动构建版本库
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没同步成功则抛出异常
2017-09-21 15:20:39 +08:00
# 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
2017-04-07 10:16:13 +08:00
end
end
end
2017-09-21 15:20:39 +08:00
def copy
2017-09-22 09:52:13 +08:00
ActiveRecord::Base.transaction do
begin
new_shixun = Shixun.new
new_shixun.attributes = @shixun.attributes.dup.except("id","user_id","visits","gpid","status", "identifier", "homepage_show")
new_shixun.user_id = User.current.id
new_shixun.identifier = generate_identifier
new_shixun.status = 0
new_shixun.fork_from = @shixun.id
2017-09-21 16:50:13 +08:00
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
2017-09-22 09:52:13 +08:00
# 同步复制版本库先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_column(:gpid, gshixun.id)
# 同步复制合作者,合作者加入到gitlab
2017-09-22 22:51:44 +08:00
unless User.current.manager_of_shixun?(@shixun)
ShixunMember.create!(:user_id => User.current.id, :shixun_id => new_shixun.try(:id), :role => 1)
end
2017-09-22 09:52:13 +08:00
@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))
2017-09-21 16:50:13 +08:00
end
2017-09-22 09:52:13 +08:00
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
2017-09-21 15:20:39 +08:00
end
2017-09-22 09:52:13 +08:00
# 同步关卡标签
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
2017-09-21 15:20:39 +08:00
end
2017-09-22 09:52:13 +08:00
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
2017-09-21 15:20:39 +08:00
end
2017-09-22 09:52:13 +08:00
# 每一题的知识标签
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
2017-09-21 15:20:39 +08:00
end
end
end
end
end
end
2017-09-22 09:52:13 +08:00
# 中间层创建测试集
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
gameInfo = new_shixun.gameInfo
uri ="#{shixun_tomcat}/bridge/game/publishGame"
params = {gameInfo:gameInfo}
res = uri_exec uri, params
if res && res['code'].to_i != 0
raise("实训云平台繁忙繁忙等级90")
end
2017-09-22 11:00:08 +08:00
flash[:notice] = "实训复制成功"
redirect_to shixun_challenges_path(new_shixun)
2017-09-22 09:52:13 +08:00
rescue Exception => e
logger.info("copy shixun failed ##{e.message}")
flash[:notice] = "#{e.message}"
g.delete_project(gshixun.id) if gshixun.try(:id).present? # 异常后,如果已经创建了版本库需要删除该版本库
2017-09-22 10:09:34 +08:00
redirect_to shixun_challenges_path(@shixun)
2017-09-22 09:52:13 +08:00
raise ActiveRecord::Rollback
2017-09-21 15:20:39 +08:00
end
end
end
2017-04-07 10:16:13 +08:00
def show
respond_to do |format|
format.html{redirect_to shixun_challenges_path(@shixun)}
end
end
2017-04-25 17:15:37 +08:00
def generate_identifier
2017-08-22 09:20:25 +08:00
code = DCODES.sample(8).join
2017-04-25 17:15:37 +08:00
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
2017-04-07 10:16:13 +08:00
def edit
end
def update
2017-08-11 17:21:25 +08:00
language = @shixun.language
@shixun.attributes = params[:shixun]
@shixun.language = params[:language]
@shixun.trainee = params[:trainee]
2017-08-25 15:25:56 +08:00
@shixun.webssh = params[:webssh].to_i
2017-09-21 17:25:51 +08:00
@shixun.can_copy = params[:can_copy].to_i
# if params[:course_id]
# @shixun.shixun_major_courses.destroy_all
# params[:course_id].each do |course_id|
# @shixun.shixun_major_courses << ShixunMajorCourse.new(:major_id => params[:major_id], :course_list_id => course_id)
# end
# end
# @shixun.major_id = params[:major_id]
@shixun.shixun_major_courses.destroy_all
2017-09-11 10:36:12 +08:00
course_lists = params[:course_list].strip.split(",")
course_lists.each do |course|
if CourseList.where(:name => course).count > 0
@shixun.shixun_major_courses << ShixunMajorCourse.new(:major_id => -1, :course_list_id => CourseList.where(:name => course.strip).first.id)
else
course_list = CourseList.create(:name => course.strip, :user_id => User.current.id, :is_admin => 0)
@shixun.shixun_major_courses << ShixunMajorCourse.new(:major_id => -1, :course_list_id => course_list.id)
end
2017-08-11 17:21:25 +08:00
end
params[:shixun][:is_public] == "on" ? @shixun.is_public = 1 : @shixun.is_public = 0
ActiveRecord::Base.transaction do
begin
@shixun.save!
if language != params[:language]
add_shixun_modify_status(@shixun, 1)
end
2017-08-11 17:21:25 +08:00
rescue
@error = "实训保存失败"
raise ActiveRecord::Rollback
end
respond_to do |format|
format.js
2017-06-22 16:21:47 +08:00
end
2017-06-20 16:09:48 +08:00
end
2017-04-07 10:16:13 +08:00
end
def shixun_discuss
2017-09-30 19:23:38 +08:00
@discusses = @shixun.discusses.reorder("created_at desc")
@discusses_count = @discusses.count
2017-09-30 19:23:38 +08:00
#@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.challenge_id) : Challenge.find(params[:challenge_id])
@game_challenge = Challenge.find(params[:challenge_id].to_i)
end
2017-04-07 10:16:13 +08:00
def destroy
2017-07-10 16:41:15 +08:00
unless User.current.admin?
render_403
return
end
Subject.where(:id => @shixun.stage_shixuns.map(&:subject_id)).destroy_all
2017-07-10 16:41:15 +08:00
@shixun.destroy
respond_to do |format|
format.html{ redirect_to shixuns_managements_path }
format.js
end
2017-04-07 10:16:13 +08:00
end
def settings
@repository = Repository.where(:shixun_id => @shixun, :type => "Repository::Gitlab").first
unless @repository.nil?
gitlab_address = Redmine::Configuration['gitlab_address']
login = User.find_by_mail("educoder@163.com").try(:login)
@repos_url = git_shixun_url(@shixun, login)
2017-04-07 10:16:13 +08:00
end
end
# 添加实训脚本
def add_script
if @shixun.update_attribute(:script, params[:shixun_script])
@notice = "脚本添加成功"
else
@notice = "脚本添加失败"
end
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
2017-04-25 17:15:37 +08:00
@shixun = Shixun.find_by_identifier(params[:id])
render_404 if @shixun.nil?
2017-04-07 10:16:13 +08:00
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?
end
2017-09-05 17:01:28 +08:00
# 实训的发送至课堂:搜索课堂
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)}
2017-09-05 17:01:28 +08:00
else
@courses = @user.courses.not_deleted_not_end.select{|course| @user.has_teacher_role(course)}
2017-09-05 17:01:28 +08:00
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
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
2017-09-12 17:32:50 +08:00
if homework.save!
2017-09-05 17:01:28 +08:00
homework_detail_manual.save if homework_detail_manual
HomeworkCommonsShixuns.create(:homework_common_id => homework.id, :shixun_id => @shixun.id)
2017-09-12 17:05:21 +08:00
redirect_to setting_homework_common_path(homework, :is_new => 1)
2017-09-05 17:01:28 +08:00
end
end
2017-04-07 10:16:13 +08:00
private
2017-06-23 15:13:45 +08:00
# 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)
2017-06-23 15:13:45 +08:00
def copy_myshixun shixun, gshixun
myshixun = Myshixun.new
# myshixun.attributes = shixun.attributes.dup.except("id","user_id","visits","gpid","status", "identifier","propaedeutics")
2017-06-23 15:13:45 +08:00
myshixun.shixun_id = shixun.id
myshixun.user_id = User.current.id
myshixun.gpid = gshixun.id
2017-08-04 14:19:22 +08:00
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
2017-06-23 15:13:45 +08:00
if myshixun.save!
# 为了避免fork多次的问题
if gshixun.try(:name).include?("-")
logger.info("***** gshixun name is #{gshixun.try(:name)}")
@g.delete_project(gshixun.id)
2017-08-10 10:00:11 +08:00
gshixun = @g.project(myshixun.gpid)
myshixun.update_column(:gpid, gshixun.id)
end
code = down_generate_identifier("myshixun")
2017-06-23 15:13:45 +08:00
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)
2017-08-06 15:34:24 +08:00
rep_url = Base64.urlsafe_encode64(git_shixun_url_ip shixun, login)
uri = "#{shixun_tomcat}/bridge/game/openGameInstance"
params = {tpiID: "#{myshixun.id}", tpmID: "#{shixun.id}", instanceGitURL:rep_url, operationEnvironment:"#{shixun.try(:language)}"}
2017-06-23 15:13:45 +08:00
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
2017-04-07 10:16:13 +08:00
def training_shixun_notice res
if res['code'] == 0
@notice = "实训开启成功"
else
@notice = res['msg'].nil? ? "实训开启失败" : res['msg']
end
end
# 权限控制
def shixun_view_allow
2017-09-22 22:51:44 +08:00
render_403 if (@shixun.status == 0 && !(User.current.manager_of_shixun?(@shixun) || User.current.admin?))
2017-04-07 10:16:13 +08:00
end
# 实训管理员或者超级管理员
def require_manager
2017-04-17 15:39:01 +08:00
render_403 unless (User.current.manager_of_shixun?(@shixun) || User.current.admin?)
2017-04-07 10:16:13 +08:00
end
2017-08-15 09:57:03 +08:00
def validation_email
render_403 if User.current.mail.blank?
end
2017-04-07 10:16:13 +08:00
end