|
- # encoding: utf-8
- # REDO: 创建版本库权限控制
- class ShixunsController < ApplicationController
- layout 'base_shixun'
- before_filter :require_login
- before_filter :find_shixun, :except => [ :index, :new, :create]
- before_filter :shixun_view_allow, :only => [:show]
- before_filter :require_manager, :only => [ :settings, :add_script]
-
- include ApplicationHelper
-
- 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
-
- # copy_shixun:复制一个新的实训模块包括版本库
- # copy_myshixun自动创建系列game,game中只包含状态等信息,公共信息从Challeges中读取
- #
- def shixun_exec
- if has_exec_cur_shixun(@shixun) || User.current.id == @shixun.user_id
- render_403
- end
- repository = @shixun.repository
- ActiveRecord::Base.transaction do
- begin
- @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)
- if !gshixun.id.nil?
- myshixun = copy_myshixun(@shixun, gshixun)
- challenges = @shixun.challenges
- # 之所以增加user_id是为了方便统计查询性能
- challenges.each_with_index do |challenge, index|
- status = (index == 0 ? 0 : 3)
- Game.create!(:challenge_id => challenge.id, :myshixun_id => myshixun.id, :status => status, :user_id => myshixun.user_id)
- end
- else
- raise("网络异常,请稍后重试")
- end
- respond_to do |format|
- format.html{redirect_to myshixun_path(myshixun)}
- end
- rescue Exception => e
- flash[:error] = l(:notice_shixun_failed_exec)+ " : " + e.message
- @g.delete_project(gshixun.id) if !gshixun.id.nil?
- raise ActiveRecord::Rollback
- end
- end
- end
-
- def new
- @shixun = Shixun.new
-
- respond_to do |format|
- format.html{render :layout => 'new_base'}
- format.json
- end
- end
-
- def create
- @shixun = Shixun.new(params[:shixun])
- @shixun.user_id = User.current.id
- @shixun.language = params[:language]
- (params[:shixun][:is_public] == "1" ? @shixun.is_public = true : @shixun.is_public = false)
- respond_to do |format|
- if @shixun.save
- m = ShixunMember.new(:user_id => User.current.id, :role => 1)
- @shixun.shixun_members << m
- format.html { redirect_to @shixun, notice: l(:notice_successful_create) }
- format.js
- else
- format.html { render action: "new" }
- format.js
- end
- end
- end
-
- def show
- respond_to do |format|
- format.html{redirect_to shixun_challenges_path(@shixun)}
- end
- end
-
- def edit
-
- end
-
- def update
- @shixun.attributes = params[:shixun]
- @shixun.language = params[:language]
- params[:shixun][:is_public] == "on" ? @shixun.is_public = 1 : @shixun.is_public = 0
- @shixun.save
- respond_to do |format|
- format.html{redirect_to settings_shixun_url(@shixun)}
- end
- end
-
- def destroy
-
- end
-
- def settings
- @repository = Repository.where(:shixun_id => @shixun, :type => "Repository::Gitlab").first
- unless @repository.nil?
- gitlab_address = Redmine::Configuration['gitlab_address']
- creator = @shixun.owner.try(:login)
- @repos_url = gitlab_address+"/" + creator + "/" + @repository.identifier+"."+"git"
- 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
- @shixun = Shixun.find(params[:id])
- 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
-
- private
- # REDO: 新增类型copy的时候
- # 复制项目
- # gshixun --> gitlab project
- def copy_myshixun shixun, gshixun
- myshixun = Myshixun.new
- myshixun.attributes = shixun.attributes.dup.except("id","user_id","visits","gpid","status")
- myshixun.shixun_id = shixun.id
- myshixun.user_id = User.current.id
- myshixun.gpid = gshixun.id
- jenkins_shixuns = Redmine::Configuration['jenkins_shixuns']
- if myshixun.save!
- MyshixunMember.create!(:myshixun_id => myshixun.id, :user_id => User.current.id, :role => 1)
- uri = URI("#{jenkins_shixuns}/jenkins-exec/api/createJob")
- pipeLine = "#{Base64.encode64(shixun.script)}"
- params = {jobName: "myshixun_#{myshixun.id}", pipeLine: pipeLine}
- res = uri_exec uri, params
- rep = Repository.new(:myshixun_id => myshixun.id, :identifier => gshixun.name,:project_id => -1, :shixun_id => -2)
- rep.type = "Repository::Gitlab"
- rep.save!
- if (res && res['code'] != 0)
- raise("Job 创建失败")
- 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 shixun_view_allow
- if @shixun.is_public?
- true
- else
- User.current.member_of?(@shixun) ? true : false
- end
- end
-
- # 实训管理员或者超级管理员
- def require_manager
- render_403 unless User.current.manager_of_shixun?(@shixun)
- end
-
- end
|