|
|
|
|
#coding=utf-8
|
|
|
|
|
class GamesController < ApplicationController
|
|
|
|
|
layout "base_myshixun"
|
|
|
|
|
skip_before_filter :verify_authenticity_token, :only => [:file_update]
|
|
|
|
|
before_filter :find_myshixun, :only => [:index]
|
|
|
|
|
before_filter :find_game, :only => [:show, :game_build, :entry,:next_step, :prev_step,:outputs_show, :file_edit, :file_update, :get_waiting_time, :web_display, :check_test_sets,
|
|
|
|
|
:game_status, :change_status, :answer, :minus_score, :refresh_game_list, :reset_original_code, :reset_new_code, :evaluating_choice,
|
|
|
|
|
:sync_codes, :myshixun_repair, :system_update, :enter_game, :get_repository_contents, :sync_modify_time, :challenges]
|
|
|
|
|
before_filter :find_repository, :only => [:entry, :file_edit, :file_update, :reset_original_code, :reset_new_code, :html_show, :get_repository_contents]
|
|
|
|
|
before_filter :allowd_manager, :except => [:show]
|
|
|
|
|
# before_filter :allowd_view, :only => [:show]
|
|
|
|
|
before_filter :find__shixun_language, :only => [:entry]
|
|
|
|
|
include ApplicationHelper
|
|
|
|
|
include GamesHelper
|
|
|
|
|
CODES = %W(1 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)
|
|
|
|
|
require 'open3'
|
|
|
|
|
|
|
|
|
|
# 同步更新最新代码
|
|
|
|
|
# 同步完成后,需要更新myshixun的commit_id为实训的commit最新值
|
|
|
|
|
# --------------------------
|
|
|
|
|
# 新思路,有冲突则则重置,没有冲突直接pull
|
|
|
|
|
# identifier为password---
|
|
|
|
|
# --------------------------
|
|
|
|
|
def sync_codes
|
|
|
|
|
g = Gitlab.client
|
|
|
|
|
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
|
|
|
|
|
begin
|
|
|
|
|
shixun_new_commit = g.commits(@myshixun.shixun.try(:gpid)).first.try(:id)
|
|
|
|
|
if @myshixun.commit_id != shixun_new_commit
|
|
|
|
|
if @myshixun.reset_time != @myshixun.shixun.try(:reset_time)
|
|
|
|
|
flag = 2
|
|
|
|
|
else
|
|
|
|
|
flag = 0
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
flag = 1
|
|
|
|
|
end
|
|
|
|
|
git_myshixun_url = gitlab_url @myshixun
|
|
|
|
|
login = @myshixun.shixun.try(:git_login)
|
|
|
|
|
# 如果educoder不是当前项目的成员,则需要把educoder设置成管理员,为了便于权限验证
|
|
|
|
|
# REDO:如果用educoder的话,可能其他成员也可以推代码
|
|
|
|
|
educoder_gid = Redmine::Configuration['educoder_gid']
|
|
|
|
|
Gitlab.client.add_team_member(@myshixun.gpid, educoder_gid, 40)
|
|
|
|
|
|
|
|
|
|
git_shixun_url = gitlab_url @myshixun.shixun
|
|
|
|
|
git_myshixun_url = Base64.urlsafe_encode64(git_myshixun_url)
|
|
|
|
|
git_shixun_url = Base64.urlsafe_encode64(git_shixun_url)
|
|
|
|
|
params = {tpiID: "#{@myshixun.try(:id)}", :tpiGitURL => "#{git_myshixun_url}", :tpmGitURL => "#{git_shixun_url}", :identifier => "xinhu1ji2qu3"}
|
|
|
|
|
uri = "#{shixun_tomcat}/bridge/game/resetTpmRepository"
|
|
|
|
|
res = uri_exec uri, params
|
|
|
|
|
if (res && res['code'] != 0)
|
|
|
|
|
render :json => {:status => -1, :message => "实训云平台繁忙(繁忙等级:95)"}
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
shixun_new_commit = g.commits(@myshixun.shixun.try(:gpid)).first.try(:id)
|
|
|
|
|
Rails.logger.info("#######Game -- myshixun")
|
|
|
|
|
@myshixun.update_attributes!(:commit_id => shixun_new_commit, :reset_time => @myshixun.shixun.try(:reset_time))
|
|
|
|
|
if @game.challenge.st == 0 && @game.challenge.path.present?
|
|
|
|
|
paths = @game.challenge.path.split(";")
|
|
|
|
|
paths.each do |path|
|
|
|
|
|
game_code_init @game.id, path.try(:strip)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
render :json => {:status => 1, :message => "success", :path => @game.challenge.path}
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
@message = e.try(:message)
|
|
|
|
|
logger.error(e)
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.js
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def enter_game
|
|
|
|
|
if @game.status == 3
|
|
|
|
|
@game.update_attributes(:status => 0, :open_time => Time.now)
|
|
|
|
|
redirect_to myshixun_game_path( @game, :myshixun_id => @myshixun)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 出现代码不存在、脚本异常等自动修复
|
|
|
|
|
# 88错误的修复等
|
|
|
|
|
def myshixun_repair
|
|
|
|
|
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
|
|
|
|
|
begin
|
|
|
|
|
git_myshixun_url = gitlab_url @myshixun
|
|
|
|
|
git_myshixun_url = Base64.urlsafe_encode64(git_myshixun_url)
|
|
|
|
|
params = {tpiID: "#{@myshixun.try(:id)}", :tpiGitURL => "#{git_myshixun_url}", :tpmID => "#{@myshixun.shixun.try(:id)}"}
|
|
|
|
|
uri = "#{shixun_tomcat}/bridge/game/solveProblems"
|
|
|
|
|
res = uri_exec uri, params
|
|
|
|
|
if (res && res['code'] != 0)
|
|
|
|
|
@message = "实训云平台繁忙(繁忙等级:96)"
|
|
|
|
|
raise("实训云平台繁忙(繁忙等级:96)")
|
|
|
|
|
end
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.js{ redirect_to myshixun_game_path(@game, :myshixun_id => @myshixun)}
|
|
|
|
|
end
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
@message = e.try(:message)
|
|
|
|
|
logger.error(e)
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.js
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def index
|
|
|
|
|
@games = @myshixun.games.includes(:challenge)
|
|
|
|
|
@games_count = @games.count
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.html
|
|
|
|
|
format.js
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# mushixun的版本库必须创建时就创建
|
|
|
|
|
# 首次进入版本库自动打开文件
|
|
|
|
|
# path:"" && path: @game.path
|
|
|
|
|
# @praise 判断是否点赞
|
|
|
|
|
# @tread 判断是否踩
|
|
|
|
|
# git_repository_url @myshixun, "Myshixun"
|
|
|
|
|
# @st 0 实践任务 1 选择题任务
|
|
|
|
|
# begin表示用户从实训tpm列表点击进入
|
|
|
|
|
def show
|
|
|
|
|
# 该参数是为了判断是否需要加载loading
|
|
|
|
|
@is_subject = params[:is_subject]
|
|
|
|
|
redirect_to "/tasks/#{@game.identifier}"
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# 验证版本库
|
|
|
|
|
gitUrl = gitlab_url @myshixun
|
|
|
|
|
gitUrl = Base64.urlsafe_encode64(gitUrl)
|
|
|
|
|
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
|
|
|
|
|
params = {:tpiID => "#{@myshixun.id}", :tpiGitURL => "#{gitUrl}"}
|
|
|
|
|
# 监测版本库HEAD是否存在,不存在则取最新的HEAD
|
|
|
|
|
uri = "#{shixun_tomcat}/bridge/game/check"
|
|
|
|
|
res = uri_exec uri, params
|
|
|
|
|
if (res && res['code'] != 0)
|
|
|
|
|
logger.error("Verify the repository exception")
|
|
|
|
|
end
|
|
|
|
|
# end
|
|
|
|
|
@is_subject = params[:is_subject]
|
|
|
|
|
# 防止页面ajax数据还没获取就关闭
|
|
|
|
|
@game.update_attribute(:status, 0) if @game.status == 1
|
|
|
|
|
@game_challenge = @game.challenge
|
|
|
|
|
@position = @game_challenge.position
|
|
|
|
|
@challenges = Challenge.where(:shixun_id => @myshixun.shixun_id).includes(:games).where("games.user_id = #{@myshixun.user_id}")
|
|
|
|
|
@shixun = @myshixun.shixun
|
|
|
|
|
# 判断tpm是否修改了
|
|
|
|
|
@tpm_modified = repository_is_modified(@myshixun, @shixun.try(:gpid))
|
|
|
|
|
unless (@shixun.modify_time.blank? || @myshixun.modify_time.blank? || @shixun.reset_time.blank? || @myshixun.reset_time.blank?)
|
|
|
|
|
@tpm_script_modified = (@shixun.reset_time > @myshixun.reset_time ? true : false)
|
|
|
|
|
end
|
|
|
|
|
if (@game_challenge.modify_time.present? || @game.modify_time.present?)
|
|
|
|
|
@tpm_cases_modified = (@game_challenge.modify_time != @game.modify_time ? true : false)
|
|
|
|
|
end
|
|
|
|
|
# end
|
|
|
|
|
@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
|
|
|
|
|
# st:判断是选择类型还是实训类型
|
|
|
|
|
@st = @game_challenge.st
|
|
|
|
|
@had_done = @game.had_done
|
|
|
|
|
@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
|
|
|
|
|
@rev = @rev.nil? ? "master" : @rev
|
|
|
|
|
@type = @_params['type']
|
|
|
|
|
challenge_path = @game_challenge.path
|
|
|
|
|
@discusses_count = @shixun.discusses.count
|
|
|
|
|
@arr_path = challenge_path.present? ? challenge_path.split(";") : []
|
|
|
|
|
# 默认打开文件
|
|
|
|
|
logger.info("repository id is #{@repository.try(:id)}, repository's shixun_id =#{@repository.try(:myshixun_id)} shixun_id =#{@repository.try(:shixun_id)}, project_id => #{@repository.try(:project_id)}")
|
|
|
|
|
# 验证challenge文件名的合法性
|
|
|
|
|
# 获取文件content内容,如果内容不存在则说明是目录,否则则认为是文件
|
|
|
|
|
if (@g.files(@myshixun.gpid, @path, @rev).try(:message).present? && !@path.present? && @_params['type'] != "root" )
|
|
|
|
|
@path = @arr_path.reject(&:blank?)[0].try(:strip) # 多文件(以';'形式隔开),默认打开第一个文件
|
|
|
|
|
file_content = @g.files(@myshixun.gpid, @path, @rev).content
|
|
|
|
|
if file_content.blank?
|
|
|
|
|
# gitlab缺陷:forked完成,短暂时间内取不了内容的,所以做一个小轮询,间隔0.1秒
|
|
|
|
|
# 超过2秒则失败,需通过页面刷新
|
|
|
|
|
for i in 0..20 do
|
|
|
|
|
sleep(0.1)
|
|
|
|
|
file_content = @g.files(@myshixun.gpid, @path, @rev).content
|
|
|
|
|
unless file_content.blank?
|
|
|
|
|
logger.info("start: file_content is####{file_content.first(6)}")
|
|
|
|
|
break
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
@content = tran_base64_decode64(file_content)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if @content.nil? || @_params['type'] == "root"
|
|
|
|
|
@entries = @repository.entries(@path, @rev)
|
|
|
|
|
end
|
|
|
|
|
# 页面前后端分离数据转换
|
|
|
|
|
# test_sets = @game_challenge.test_sets
|
|
|
|
|
max_query_index = @game.outputs.first.try(:query_index)
|
|
|
|
|
if max_query_index.present?
|
|
|
|
|
test_sets = TestSet.find_by_sql("SELECT o.actual_output, o.result, o.test_set_position, o.query_index,t.is_public,t.input, t.output, g.id as game_id, c.id as challenge_id FROM outputs o,games g ,challenges c,test_sets t where
|
|
|
|
|
g.id=#{@game.id} and o.query_index=#{max_query_index} and g.id = o.game_id and c.id= g.challenge_id and t.challenge_id = c.id and t.position =o.test_set_position order by o.query_index
|
|
|
|
|
")
|
|
|
|
|
else
|
|
|
|
|
test_sets = TestSet.find_by_sql("SELECT t.is_public,t.input, t.output,t.position FROM games g ,challenges c,test_sets t where
|
|
|
|
|
g.id=#{@game.id} and c.id= g.challenge_id and t.challenge_id = c.id
|
|
|
|
|
")
|
|
|
|
|
end
|
|
|
|
|
unless test_sets.blank?
|
|
|
|
|
@test_sets = test_set_static_data(test_sets)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
@test_sets_count = test_sets.count
|
|
|
|
|
@test_sets_hidden_count = test_sets.blank? ? 0 :test_sets.select{|test_set| test_set.is_public == false}.count
|
|
|
|
|
@test_sets_public_count = @test_sets_count - @test_sets_hidden_count
|
|
|
|
|
had_test = Output.where(:game_id => @game.id, :query_index => (@game.query_index - 1))
|
|
|
|
|
@had_test_count = had_test.count
|
|
|
|
|
@had_passed_testsests_error_count = had_test.blank? ? 0 : had_test.select{|had_test| had_test.result == false}.count
|
|
|
|
|
@had_passed_testsests_error_count = @had_test_count - @had_passed_testsests_error_count
|
|
|
|
|
@had_passed_testsests_hidden_count = had_test.blank? ? 0 : had_test.select{|had_test| had_test.result == true && had_test.is_public == false}.count
|
|
|
|
|
@had_passed_testsests_public_count = had_test.blank? ? 0 : had_test.select{|had_test| had_test.result == true && had_test.is_public == true}.count
|
|
|
|
|
@mirror_name = @myshixun.mirror_name
|
|
|
|
|
@final_score = ((@shixun.status <= 1) ? 0 : @game.final_score.to_i)
|
|
|
|
|
if @myshixun.shixun.status <= 1 || (@game.final_score != 0 && @game.answer_open?)
|
|
|
|
|
@gold = 0
|
|
|
|
|
else
|
|
|
|
|
if @game.answer_open? && @game.final_score ==0
|
|
|
|
|
@gold = -@game_challenge.score.to_i
|
|
|
|
|
else
|
|
|
|
|
@gold = @game.final_score.to_i
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
#@gold = @myshixun.shixun.status <= 1 ? 0 : ((@game.answer_open? && @game.final_score == 0 && @game.status == 2) ? -@game_challenge.score.to_i : @game.final_score.to_i)
|
|
|
|
|
@had_done = @game.had_done
|
|
|
|
|
@language = @game_challenge.shixun.language
|
|
|
|
|
@mirror_name = @myshixun.mirror_name
|
|
|
|
|
error_position = had_test.blank? ? nil : had_test.select{|had_test| had_test.result == false}.last
|
|
|
|
|
logger.info("latest output id is #{error_position.id unless error_position.blank?}")
|
|
|
|
|
@latest_output = error_position.try(:out_put).gsub(/\n/, '<br/>').gsub(/\t/, ' ').to_json unless error_position.try(:out_put).blank?
|
|
|
|
|
logger.info(@latest_output)
|
|
|
|
|
@power = (User.current.manager_of_shixun?(@shixun) || (User.current.try(:professional_certification) && User.current.user_extensions.try(:identity) == 0) || @game.test_sets_view ) ? true : false
|
|
|
|
|
@record = EvaluateRecord.where(:game_id => @game.id).first.try(:consume_time)
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.html
|
|
|
|
|
format.js
|
|
|
|
|
end
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
logger.error("game error##############{e.message}")
|
|
|
|
|
flash[:error] = e.message
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def get_repository_contents
|
|
|
|
|
@rev = @rev.nil? ? "master" : @rev
|
|
|
|
|
@path = params[:path].try(:strip) # 多文件(以';'形式隔开),默认打开第一个文件
|
|
|
|
|
file_content = @g.files(@myshixun.gpid, @path, @rev).content
|
|
|
|
|
@content = tran_base64_decode64(file_content)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 代码预览
|
|
|
|
|
def entry
|
|
|
|
|
# entry_and_raw(false)
|
|
|
|
|
@arr_path = @game.challenge.path.split(";")
|
|
|
|
|
file_content = @g.files(@myshixun.gpid, @path, @rev).content
|
|
|
|
|
@content =tran_base64_decode64(file_content)
|
|
|
|
|
# @content = @repository.cat(@path, @rev)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def file_edit
|
|
|
|
|
# entry_and_raw(false)
|
|
|
|
|
# @content = @repository.cat(@path, @rev).strip
|
|
|
|
|
# # respond_to do |format|
|
|
|
|
|
# # format.js
|
|
|
|
|
# end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def sync_modify_time
|
|
|
|
|
@game.update_column(:modify_time, @game.challenge.try(:modify_time))
|
|
|
|
|
# return {:status => 1, :message => "success"}
|
|
|
|
|
render :json => {:status => 1, :message => "success"}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def file_update
|
|
|
|
|
# render :json => {:success => "success", :resubmit => '11111'}
|
|
|
|
|
logger.info("file_update start#1**#{@game.id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
ActiveRecord::Base.transaction do
|
|
|
|
|
if params[:evaluate].present?
|
|
|
|
|
# 创建评测记录
|
|
|
|
|
record = EvaluateRecord.create!(:user_id => User.current.id, :shixun_id => @myshixun.shixun.id, :game_id => @game.id)
|
|
|
|
|
logger.info("file_update start#2**#{@game.id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
# @myshixun.student_works.update_all(:update_time => Time.now) if !@myshixun.student_works.blank?
|
|
|
|
|
|
|
|
|
|
student_work_time = format("%.3f", (Time.now.to_f - record.created_at.to_f)).to_f
|
|
|
|
|
record.update_attributes!(:student_work => student_work_time)
|
|
|
|
|
end
|
|
|
|
|
logger.info("file_update start#3**#{@game.id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
@g = Gitlab.client
|
|
|
|
|
last_content = @g.files(@myshixun.gpid, @path, "master").try(:content)
|
|
|
|
|
logger.info("file_update start#4**#{@game.id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
last_content = tran_base64_decode64(last_content)
|
|
|
|
|
content = if (@myshixun.mirror_name.include?('Python2.7') || @myshixun.mirror_name.include?('Python3.6') || @myshixun.mirror_name.include?('MachineLearning')) && params[:content].present?
|
|
|
|
|
params[:content].gsub(/\t/, ' ')
|
|
|
|
|
else
|
|
|
|
|
params[:content]
|
|
|
|
|
end
|
|
|
|
|
logger.info("file_update start#5**#{@game.id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
if content != last_content
|
|
|
|
|
code_file = @g.edit_file(@myshixun.gpid, User.current.login, :content => content, :file_path => @path, :branch_name => @rev, :commit_message => "shixun exec")
|
|
|
|
|
end
|
|
|
|
|
if record.present?
|
|
|
|
|
consume_time = format("%.3f", (Time.now.to_f - record.created_at.to_f)).to_f
|
|
|
|
|
record.update_attributes!(:file_update => consume_time)
|
|
|
|
|
end
|
|
|
|
|
logger.info("file_update start#6**#{@game.id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
# status为2说明是重新评测
|
|
|
|
|
if @game.status == 2
|
|
|
|
|
code = CODES.sample(8).join
|
|
|
|
|
resubmit = "#{code}_#{@myshixun.id}"
|
|
|
|
|
end
|
|
|
|
|
if content != last_content && code_file.blank?
|
|
|
|
|
raise("update file failed")
|
|
|
|
|
else
|
|
|
|
|
render :json => {:success => "success", :resubmit => resubmit}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
render :json => {:success => "fail", :contents => "实训云平台繁忙(繁忙等级:81),请稍后刷新并重试", :position => @game.challenge.position, :had_done => @game.had_done}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# json调用,显示左边的隐藏具体详情@game 字段 msg
|
|
|
|
|
# 刷新右边的输出结果 @game out_put
|
|
|
|
|
def outputs_show
|
|
|
|
|
@output = Output.find(params[:game_output_id])
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.js
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 获取评测的等待的时间
|
|
|
|
|
# res['waitNum'] 评测等待人数
|
|
|
|
|
# res['waitingTime'] 评测等待时间
|
|
|
|
|
# res['ableToCreate'] 0 表示在等待中 1 表示可执行 -1 表示超过最大等待人数
|
|
|
|
|
def get_waiting_time
|
|
|
|
|
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
|
|
|
|
|
uri = "#{shixun_tomcat}/bridge/game/getWaitingTime"
|
|
|
|
|
params = {:tpiID => "#{@myshixun.id}", :first => @_params[:first].to_i}
|
|
|
|
|
res = uri_exec uri, params
|
|
|
|
|
logger.info("############ res: #{res}")
|
|
|
|
|
if (res && res['code'] != 0)
|
|
|
|
|
@message = "实训云平台繁忙(繁忙等级:94)"
|
|
|
|
|
raise("实训云平台繁忙(繁忙等级:94)")
|
|
|
|
|
end
|
|
|
|
|
logger.info("########### get_waiting_time: #{params}")
|
|
|
|
|
logger.info("########### ableToCreate : #{res['ableToCreate']}")
|
|
|
|
|
|
|
|
|
|
render :json => {:result => "success", :ableToCreate => res['ableToCreate'], :waitNum => res['waitNum'], :waitingTime => res['waitingTime'], :position => @game.challenge.position}
|
|
|
|
|
#render :json => {:result => "success", :ableToCreate => 1, :waitNum => 10, :waitingTime => 1324 }
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
render :json => {:result => "fail", :contents => '实训云平台繁忙(繁忙等级:94),请稍后刷新并重试', :position => @game.challenge.position}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# status 0: 未提交测评或者提交测评失败后报错;1:中间状态还没返回值;2:返回值并成功
|
|
|
|
|
# resubmit 唯一随机码,为了区分每一次重新评测结果
|
|
|
|
|
def game_build
|
|
|
|
|
#render :json => {:result => "success", :ableToCreate => 1, :waitNum => 13, :port => 41222 }
|
|
|
|
|
# 更新时间是为了TPM端显示的更新,退出实训及访问实训的时候会更新
|
|
|
|
|
logger.info("game_build start#1**#{@game.id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
@myshixun.update_column(:updated_at, Time.now)
|
|
|
|
|
game_challenge = @game.challenge
|
|
|
|
|
shixun = @myshixun.shixun
|
|
|
|
|
gitUrl = gitlab_url @myshixun
|
|
|
|
|
gitUrl = Base64.urlsafe_encode64(gitUrl)
|
|
|
|
|
taskId = @game.id
|
|
|
|
|
#code = CODES.sample(8).join
|
|
|
|
|
# status为2说明是重新评测
|
|
|
|
|
if @game.status == 2
|
|
|
|
|
resubmit = @_params[:resubmit]
|
|
|
|
|
else
|
|
|
|
|
# 重新评测不影响已通关的实训状态
|
|
|
|
|
if @_params[:first].to_i == 1
|
|
|
|
|
@game.update_attributes!(:status => 1)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
|
|
|
|
|
step = game_challenge.try(:position)
|
|
|
|
|
logger.info("game_build start#2**#{@game.id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
testSet = []
|
|
|
|
|
game_challenge.test_sets.each do |test_set|
|
|
|
|
|
input = test_set.input.nil? ? "" : test_set.input.gsub("\r\n", "\n")
|
|
|
|
|
output = test_set.output.nil? ? "" : test_set.output.gsub("\r\n", "\n")
|
|
|
|
|
test_cases = {:input => input, :output => output}
|
|
|
|
|
testSet << test_cases
|
|
|
|
|
end
|
|
|
|
|
logger.info("game_build start#3**#{@game.id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
testCases = Base64.urlsafe_encode64(testSet.to_json) unless testSet.blank?
|
|
|
|
|
mirror_repository = shixun.mirror_repositories.where(:main_type => 1).first
|
|
|
|
|
resource_limit = "echo 'ulimit -f #{mirror_repository.resource_limit}' >> /root/.bashrc ; source /root/.bashrc\n"
|
|
|
|
|
tpmScript = shixun.evaluate_script.nil? ? "" : Base64.urlsafe_encode64((resource_limit + shixun.evaluate_script).gsub("\r\n", "\n"))
|
|
|
|
|
# 注意:这个地方的参数写的时候不能换行
|
|
|
|
|
params = {:tpiID => "#{@myshixun.id}", :tpiGitURL => "#{gitUrl}", :buildID => "#{taskId}",:instanceChallenge => "#{step}",
|
|
|
|
|
:testCases => "#{testCases}", :resubmit => "#{resubmit}", :times => @_params[:first].to_i, :podType => shixun.webssh,
|
|
|
|
|
:containers => "#{Base64.urlsafe_encode64(container_limit(shixun.mirror_repositories))}", :tpmScript => "#{tpmScript}",
|
|
|
|
|
:timeLimit => "#{shixun.main_mirror.try(:time_limit)}"}
|
|
|
|
|
# 评测有文件输出的需要特殊传字段 path:表示文件存储的位置
|
|
|
|
|
params['file'] = Base64.urlsafe_encode64({:path => "#{game_challenge.picture_path}"}.to_json) if game_challenge.picture_path.present?
|
|
|
|
|
# needPortMapping: web类型需要pod端口映射
|
|
|
|
|
params[:needPortMapping] = 8080 if @myshixun.mirror_name.include?("Web")
|
|
|
|
|
# uri = URI("#{shixun_tomcat}/bridge/game/gameEvaluate")
|
|
|
|
|
logger.info("game_build start#4**#{@game.id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
uri = "#{shixun_tomcat}/bridge/game/gameEvaluate"
|
|
|
|
|
res = uri_exec uri, params
|
|
|
|
|
if (res && res['code'] != 0)
|
|
|
|
|
@message = "实训云平台繁忙(繁忙等级:86)"
|
|
|
|
|
raise("实训云平台繁忙(繁忙等级:86)")
|
|
|
|
|
end
|
|
|
|
|
logger.info("game_build start#5****** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
render :json => {:result => "success", :resubmit => resubmit, :ableToCreate => res['ableToCreate'], :waitNum => res['waitNum'], :waitingTime => res['waitingTime'], :position => @game.challenge.position, :port => res['port'], :had_done => @game.had_done }
|
|
|
|
|
logger.info("game_build start#6****** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
if resubmit.nil?
|
|
|
|
|
@game.update_attributes!(:status => 0)
|
|
|
|
|
end
|
|
|
|
|
logger.error("###################" + e.message)
|
|
|
|
|
render :json => {:result => 'fail', :contents =>"实训云平台繁忙(繁忙等级:86),请稍后刷新并重试", :position => game_challenge.position, :had_done => @game.had_done}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# @myshixun -status 1:完成实训
|
|
|
|
|
# 全部通关奖励1000分
|
|
|
|
|
# retry_status 评测的唯一标识,重新评测对以前已产生的结果不造成影响
|
|
|
|
|
# params[:resubmit] 不为空表示已通过该关后重新评测, 重新评测必须是通过该关后才能执行
|
|
|
|
|
# @had_done 1 通关所有关
|
|
|
|
|
# port: PHP/Web会有端口号,其他语言返回-1
|
|
|
|
|
# params[:time_out] 超时
|
|
|
|
|
def game_status
|
|
|
|
|
logger.info("game_status start#1**#{@game.id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
if (params[:time_out] == "false") && ((params[:resubmit].blank? && @game.status != 2 && @game.status != 0) || (params[:resubmit].present? && (params[:resubmit] != @game.resubmit_identifier)))
|
|
|
|
|
render :json => {:status => 1}
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
game_challenge = @game.challenge
|
|
|
|
|
had_done = @game.had_done
|
|
|
|
|
resubmit_identifier = @game.resubmit_identifier
|
|
|
|
|
shixun = @myshixun.shixun
|
|
|
|
|
port = params[:port]
|
|
|
|
|
score = 0
|
|
|
|
|
user_gold = 0 #用户奖励金币
|
|
|
|
|
tag_count = 0
|
|
|
|
|
logger.info("##### resubmit_identifier is #{resubmit_identifier}")
|
|
|
|
|
logger.info("game_status start#2**#{@game.id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
if params[:resubmit].blank? # 非重新评测
|
|
|
|
|
# 通过当前一关
|
|
|
|
|
if @game.status == 2
|
|
|
|
|
if !@game.answer_open && shixun.status > 1
|
|
|
|
|
score = game_challenge.score
|
|
|
|
|
user_gold = game_challenge.score
|
|
|
|
|
tag_count = game_challenge.challenge_tags.count
|
|
|
|
|
elsif shixun.status > 1 && @game.answer_open
|
|
|
|
|
score = -game_challenge.score.to_i
|
|
|
|
|
tag_count = 0
|
|
|
|
|
else
|
|
|
|
|
score = "+0"
|
|
|
|
|
tag_count = 0
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
game_status = @game.status
|
|
|
|
|
else # 重新评测
|
|
|
|
|
if params[:resubmit] == resubmit_identifier # 本次重新评测结果已经返回并存入数据库
|
|
|
|
|
game_status = (@game.retry_status == 2 ? 2 : 0) # retry_status 2:成功 1: 失败
|
|
|
|
|
if game_status == 2 && had_done == 1 # 重新评测如果评测成功
|
|
|
|
|
had_done =1
|
|
|
|
|
else
|
|
|
|
|
had_done = 0
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
# game_status 在前端有行为判断,2表示通关;0表示失败;1表示评测中的中间状态
|
|
|
|
|
game_status = 1
|
|
|
|
|
had_done = 0
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
logger.info("game_status start#3**#{@game.id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
max_query_index = @game.outputs.first.try(:query_index)
|
|
|
|
|
if max_query_index.present?
|
|
|
|
|
test_sets = TestSet.find_by_sql("SELECT o.actual_output, o.result, o.test_set_position, o.query_index,t.is_public,t.input, t.output, g.id as game_id, c.id as challenge_id FROM outputs o,games g ,challenges c,test_sets t where
|
|
|
|
|
g.id=#{@game.id} and o.query_index=#{max_query_index} and g.id = o.game_id and c.id= g.challenge_id and t.challenge_id = c.id and t.position =o.test_set_position order by o.query_index
|
|
|
|
|
")
|
|
|
|
|
else
|
|
|
|
|
test_sets = TestSet.find_by_sql("SELECT t.is_public,t.input, t.output,t.position FROM games g ,challenges c,test_sets t where
|
|
|
|
|
g.id=#{@game.id} and c.id= g.challenge_id and t.challenge_id = c.id
|
|
|
|
|
")
|
|
|
|
|
end
|
|
|
|
|
logger.info("game_status start#4**#{@game.id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
unless test_sets.blank?
|
|
|
|
|
total_test_sets = test_set_static_data(test_sets)
|
|
|
|
|
end
|
|
|
|
|
logger.info("#################################{@public_test_sets}")
|
|
|
|
|
@test_sets_count = test_sets.count
|
|
|
|
|
@test_sets_hidden_count = test_sets.blank? ? 0 :test_sets.select{|test_set| test_set.is_public == false}.count
|
|
|
|
|
@test_sets_public_count = @test_sets_count - @test_sets_hidden_count
|
|
|
|
|
had_test = Output.where(:game_id => @game.id, :query_index => (@game.query_index - 1))
|
|
|
|
|
@had_test_count = had_test.count
|
|
|
|
|
@had_passed_testsests_error_count = had_test.blank? ? 0 : had_test.select{|had_test| had_test.result == false}.count
|
|
|
|
|
@had_passed_testsests_error_count = @had_test_count - @had_passed_testsests_error_count
|
|
|
|
|
@had_passed_testsests_hidden_count = had_test.blank? ? 0 : had_test.select{|had_test| had_test.result == true && had_test.is_public == false}.count
|
|
|
|
|
@had_passed_testsests_public_count = had_test.blank? ? 0 : had_test.select{|had_test| had_test.result == true && had_test.is_public == true}.count
|
|
|
|
|
@final_score = (( shixun.try(:status).to_i <= 1) ? 0 : @game.try(:final_score).to_i)
|
|
|
|
|
picture = (@game.picture_path.nil? ? 0 : @game.id)
|
|
|
|
|
if @myshixun.shixun.try(:status) <= 1 || (@game.try(:final_score).to_i != 0 && @game.answer_open?)
|
|
|
|
|
@gold = 0
|
|
|
|
|
else
|
|
|
|
|
if @game.answer_open? && @game.try(:final_score).to_i ==0
|
|
|
|
|
@gold = -game_challenge.try(:score).to_i
|
|
|
|
|
else
|
|
|
|
|
@gold = @game.try(:final_score).to_i
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
#@gold = @myshixun.shixun.status <= 1 ? 0 : (@game.answer_open? && @game.final_score.to_i == 0 && @game.status == 2 ? -game_challenge.score.to_i : @game.final_score.to_i)
|
|
|
|
|
error_position = had_test.blank? ? nil : had_test.select{|had_test| had_test.result == false}.last
|
|
|
|
|
@latest_output = error_position.try(:out_put).gsub(/\n/, '<br/>').gsub(/\t/, ' ') unless error_position.try(:out_put).blank?
|
|
|
|
|
logger.info("@compile_success###################{@compile_success}")
|
|
|
|
|
@language = game_challenge.shixun.language
|
|
|
|
|
@mirror_name = @myshixun.mirror_name
|
|
|
|
|
power = (User.current.manager_of_shixun?(shixun) || (User.current.try(:professional_certification) && User.current.user_extensions.try(:identity) == 0)) ? true : false
|
|
|
|
|
logger.info("game_status start#5**#{@game.id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
# 更新用户时间
|
|
|
|
|
if game_status == 0 || game_status == 2
|
|
|
|
|
record = EvaluateRecord.where(:game_id => @game.id).first
|
|
|
|
|
if record
|
|
|
|
|
front_js = format("%.3f", (Time.now.to_f - record.try(:updated_at).to_f)).to_f
|
|
|
|
|
consume_time = format("%.3f", (Time.now - record.created_at)).to_f
|
|
|
|
|
record.update_attributes(:consume_time => consume_time, :front_js => front_js)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
# 记录前端总耗时
|
|
|
|
|
record = EvaluateRecord.where(:game_id => @game.id).first.try(:consume_time)
|
|
|
|
|
logger.info("game_status start#6**#{@game.id}**** #{Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")}")
|
|
|
|
|
render :json => {test_sets: total_test_sets,
|
|
|
|
|
test_sets_count: @test_sets_count,
|
|
|
|
|
test_sets_hidden_count: @test_sets_hidden_count,
|
|
|
|
|
test_sets_public_count: @test_sets_public_count,
|
|
|
|
|
had_test_count: @had_test_count,
|
|
|
|
|
had_passed_testsests_error_count: @had_passed_testsests_error_count,
|
|
|
|
|
had_passed_testsests_hidden_count: @had_passed_testsests_hidden_count,
|
|
|
|
|
had_passed_testsests_public_count: @had_passed_testsests_public_count,
|
|
|
|
|
final_score: @final_score,
|
|
|
|
|
gold: @gold,
|
|
|
|
|
latest_output: @latest_output,
|
|
|
|
|
status: game_status,
|
|
|
|
|
had_done: had_done,
|
|
|
|
|
language: @language,
|
|
|
|
|
score: score,
|
|
|
|
|
user_gold: user_gold,
|
|
|
|
|
tag_count: tag_count,
|
|
|
|
|
position: game_challenge.position,
|
|
|
|
|
port: port,
|
|
|
|
|
power: power,
|
|
|
|
|
record:record,
|
|
|
|
|
mirror_name:@mirror_name,
|
|
|
|
|
picture:picture
|
|
|
|
|
}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 选择题评测(选择题不需要重新评测)
|
|
|
|
|
# score 获得金币数 tag_count 技能数 right用户是否全对 answer_right全部选择题的正确性
|
|
|
|
|
def evaluating_choice
|
|
|
|
|
@game_challenge = @game.challenge
|
|
|
|
|
@challenges = Challenge.where(:shixun_id => @myshixun.shixun_id)
|
|
|
|
|
@shixun = @myshixun.shixun
|
|
|
|
|
score = 0
|
|
|
|
|
tag_count = 0
|
|
|
|
|
@right = true
|
|
|
|
|
answer_right = []
|
|
|
|
|
@game_challenge.challenge_chooses.each_with_index do |choose, index|
|
|
|
|
|
correct = (params[:answer][index] == choose.standard_answer) ? true : false
|
|
|
|
|
Output.create(:game_id => @game.id, :test_set_position => choose.position, :actual_output => params[:answer][index], :result => correct, :query_index => @game.query_index)
|
|
|
|
|
if @shixun.status > 1 && !@game.answer_open
|
|
|
|
|
if correct
|
|
|
|
|
score += choose.score
|
|
|
|
|
tag_count += choose.challenge_tags.count
|
|
|
|
|
end
|
|
|
|
|
elsif @shixun.status > 1 && @game.answer_open
|
|
|
|
|
score -= choose.score
|
|
|
|
|
end
|
|
|
|
|
unless correct
|
|
|
|
|
@right = false
|
|
|
|
|
end
|
|
|
|
|
answer_right << correct
|
|
|
|
|
end
|
|
|
|
|
@had_done = @game.had_done
|
|
|
|
|
if @right && @game.status != 2
|
|
|
|
|
@game.update_attributes(:status => 2, :end_time => Time.now)
|
|
|
|
|
# 选择题最后一关,更新status
|
|
|
|
|
if @had_done
|
|
|
|
|
@myshixun.update_attribute(:status, 1)
|
|
|
|
|
end
|
|
|
|
|
if @shixun.status > 1 && !@game.answer_open
|
|
|
|
|
reward_grade(@game.user, @game.id, 'Game', @game_challenge.choose_score)
|
|
|
|
|
reward_experience(@game.user, @game.id, 'Game', @game_challenge.choose_score)
|
|
|
|
|
@game.update_attribute(:final_score, @game_challenge.choose_score)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.js{redirect_to myshixun_game_path(@game, :myshixun_id => @myshixun, :choose => @right)}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def change_status
|
|
|
|
|
@game.update_attribute(:status, 0)
|
|
|
|
|
outputs = @game.outputs
|
|
|
|
|
if outputs.count == 0
|
|
|
|
|
outputs = ""
|
|
|
|
|
else
|
|
|
|
|
outputs = outputs.map{|result| [result.code, result.id]}
|
|
|
|
|
end
|
|
|
|
|
render :json => {status: @game.status, output: "服务器网络异常", results: outputs, had_done: 0}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 获取等待的任务数
|
|
|
|
|
# 如果没有等待任务页面上将不显示
|
|
|
|
|
# msg: -1 不存在等待的任务
|
|
|
|
|
# 如果该方法异常则直接返回0,跳过等待
|
|
|
|
|
def waiting_info
|
|
|
|
|
begin
|
|
|
|
|
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
|
|
|
|
|
params = {:buildID => "#{@game.id}"}
|
|
|
|
|
uri = URI("#{shixun_tomcat}/jenkins-exec/api/getWaitingTime")
|
|
|
|
|
res = uri_exec uri, params
|
|
|
|
|
if (res && res['code'] != 0)
|
|
|
|
|
raise("获取等待任务数异常")
|
|
|
|
|
end
|
|
|
|
|
task_count = res['msg'].to_i
|
|
|
|
|
task_count > 0 ? task_count : 0
|
|
|
|
|
render :json => {task_count: task_count}
|
|
|
|
|
rescue
|
|
|
|
|
render :json => {task_count: 0}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 自动推送下一个任务
|
|
|
|
|
# 从waiting_time发的请求则有type
|
|
|
|
|
def next_step
|
|
|
|
|
#unless show_next_stage?(@game, @myshixun.shixun.try(:status))
|
|
|
|
|
# render_403
|
|
|
|
|
#end
|
|
|
|
|
|
|
|
|
|
next_game = @game.next_game
|
|
|
|
|
next_game.update_attributes(:status => 0, :open_time => Time.now) if next_game.status == 3
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.js{ redirect_to myshixun_game_path(next_game, :myshixun_id => @myshixun)}
|
|
|
|
|
format.html{redirect_to myshixun_game_path(next_game, :myshixun_id => @myshixun)}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def prev_step
|
|
|
|
|
prev_game = @game.prev_game
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.js{ redirect_to myshixun_game_path(prev_game, :myshixun_id => @myshixun)}
|
|
|
|
|
format.html{ redirect_to myshixun_game_path(prev_game, :myshixun_id => @myshixun)}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 获取答案,第一次查看需扣掉该关卡的积分
|
|
|
|
|
# 如果已看过,下次可以免费查看
|
|
|
|
|
# viewed 1: 直接查看 2:弹框提示将要扣除积分,确定后显示内容 3:弹框提示分数不够
|
|
|
|
|
def answer
|
|
|
|
|
challenge = @game.challenge
|
|
|
|
|
@challenge_score = challenge.score.to_i
|
|
|
|
|
@answer = ""
|
|
|
|
|
# 已经开启过
|
|
|
|
|
@score = User.current.grade.to_i - @challenge_score
|
|
|
|
|
if(params[:choose] == "true")
|
|
|
|
|
challenge.challenge_chooses.each_with_index do |choose, index|
|
|
|
|
|
@answer += "第"+ ((index + 1).to_s) +"题:<br />"
|
|
|
|
|
@answer += (choose.answer.blank? ? choose.standard_answer : choose.answer)
|
|
|
|
|
@answer += "<br /><br /><br />"
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
@answer = challenge.answer
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
if challenge.shixun.status < 2 || User.current.manager_of_shixun?(challenge.shixun) || @game.answer_open || (challenge.st != 0 && @game.status == 2)
|
|
|
|
|
@viewed = 1
|
|
|
|
|
else
|
|
|
|
|
if @score >= 0
|
|
|
|
|
@viewed = 2
|
|
|
|
|
else
|
|
|
|
|
@viewed = 3
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.js
|
|
|
|
|
format.html
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# web渲染
|
|
|
|
|
def web_display
|
|
|
|
|
path = @game.challenge.path.strip
|
|
|
|
|
port = (50000 + @game.myshixun_id).to_s
|
|
|
|
|
# 测试
|
|
|
|
|
#path = "src/step1/Helloworld.php"
|
|
|
|
|
#port = (50000+4116).to_s
|
|
|
|
|
@url = "http://106.75.96.108:" + port + '/' + path
|
|
|
|
|
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.html{render :layout => false}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def minus_score
|
|
|
|
|
@game_challenge = @game.challenge
|
|
|
|
|
@position = @game_challenge.position
|
|
|
|
|
user = User.current
|
|
|
|
|
challenge_score = @game_challenge.score.to_i
|
|
|
|
|
@answer = ""
|
|
|
|
|
if @game.challenge.st == 0
|
|
|
|
|
@answer = @game_challenge.answer
|
|
|
|
|
else
|
|
|
|
|
@game_challenge.challenge_chooses.each_with_index do |choose, index|
|
|
|
|
|
@answer += "第"+ ((index + 1).to_s) +"题:<br />"
|
|
|
|
|
@answer += (choose.answer.blank? ? choose.standard_answer : choose.answer)
|
|
|
|
|
@answer += "<br /><br /><br />"
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
unless @game.answer_open
|
|
|
|
|
# 最终得分可能是负分
|
|
|
|
|
final_score = @game.final_score - challenge_score
|
|
|
|
|
@game.update_attributes!(:answer_open => true, :final_score => final_score)
|
|
|
|
|
# 积分消耗情况统计
|
|
|
|
|
reward_grade(user, @game.id, 'Answer', -challenge_score)
|
|
|
|
|
@grades = final_score
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def refresh_game_list
|
|
|
|
|
myshixun_id = params[:myshixun_id]
|
|
|
|
|
@myshixun = Myshixun.find_by_identifier(myshixun_id)
|
|
|
|
|
# @challenges = Challenge.where(:shixun_id => @myshixun.shixun_id)
|
|
|
|
|
@challenges = Challenge.where(:shixun_id => @myshixun.shixun_id).includes(:games).where("games.user_id = #{@myshixun.user_id}")
|
|
|
|
|
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.js
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def check_test_sets
|
|
|
|
|
user_grade = User.current.grade
|
|
|
|
|
@minus_grade = @game.challenge.score * 5
|
|
|
|
|
if user_grade >= @minus_grade
|
|
|
|
|
User.current.update_attribute(:grade, user_grade - @minus_grade)
|
|
|
|
|
@game.update_attribute(:test_sets_view, true)
|
|
|
|
|
# 扣分记录
|
|
|
|
|
Grade.create(:user_id => User.current.id, :container_id => @game.id, :score => -@minus_grade, :container_type => "testSet")
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.js{redirect_to myshixun_game_path(@game, :myshixun_id => @myshixun, :test_sets_view => true)}
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.js
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def reset_original_code
|
|
|
|
|
@g = Gitlab.client
|
|
|
|
|
begin
|
|
|
|
|
@shixun = @myshixun.shixun
|
|
|
|
|
@path = params[:path].try(:strip)
|
|
|
|
|
game_code = GameCode.where(:game_id => @game.id, :path => @path).first
|
|
|
|
|
GameCode.create(:game_id => @game.id, :path => @path) if game_code.blank?
|
|
|
|
|
content = game_code.try(:original_code)
|
|
|
|
|
@arr_path = @game.challenge.path.split(";")
|
|
|
|
|
@rev = @rev.nil? ? "master" : @rev
|
|
|
|
|
content = @g.files(@shixun.gpid, @path, @rev).try(:content)
|
|
|
|
|
content = tran_base64_decode64(content)
|
|
|
|
|
update_gitlab_file(content, @path, @rev, "file reset")
|
|
|
|
|
file_content = @g.files(@myshixun.gpid, @path, @rev).content
|
|
|
|
|
@content = tran_base64_decode64(file_content)
|
|
|
|
|
if @content.nil?
|
|
|
|
|
raise("初始代码为空,代码重置失败")
|
|
|
|
|
end
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
@error_messages = e.message
|
|
|
|
|
end
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.js
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def system_update
|
|
|
|
|
@myshixun.update_attribute(:system_tip, true)
|
|
|
|
|
render :json => {:status => 1, :message => "success"}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def reset_new_code
|
|
|
|
|
begin
|
|
|
|
|
@shixun = @myshixun.shixun
|
|
|
|
|
@g = Gitlab.client
|
|
|
|
|
@arr_path = params[:path]
|
|
|
|
|
@path = @arr_path[0].try(:strip)
|
|
|
|
|
@rev = @rev.nil? ? "master" : @rev
|
|
|
|
|
message = "file reset"
|
|
|
|
|
@arr_path.each do |path|
|
|
|
|
|
game_code = GameCode.where(:game_id => @game.id, :path => path).first
|
|
|
|
|
content = game_code.try(:new_code)
|
|
|
|
|
if content.nil?
|
|
|
|
|
raise("示例代码为空,代码重置失败")
|
|
|
|
|
end
|
|
|
|
|
update_gitlab_file(content, path, @rev, message)
|
|
|
|
|
end
|
|
|
|
|
file_content = @g.files(@myshixun.gpid, @path, @rev).content
|
|
|
|
|
@content = tran_base64_decode64(file_content)
|
|
|
|
|
if @content.nil?
|
|
|
|
|
raise("示例代码为空,代码重置失败")
|
|
|
|
|
# @entries = @repository.entries(@path, @rev)
|
|
|
|
|
end
|
|
|
|
|
respond_to do |format|
|
|
|
|
|
format.js
|
|
|
|
|
end
|
|
|
|
|
rescue Exception => e
|
|
|
|
|
@error_messages = e.message
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
private
|
|
|
|
|
def update_gitlab_file content, path, rev, message
|
|
|
|
|
code_file = @g.edit_file(@myshixun.gpid, User.current.login, :content => content, :file_path => path, :branch_name => rev, :commit_message => "#{message}")
|
|
|
|
|
if code_file.nil?
|
|
|
|
|
raise("网络异常,文件更新失败")
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def test_set_static_data test_sets
|
|
|
|
|
test_result = []
|
|
|
|
|
unless test_sets.blank?
|
|
|
|
|
test_sets.each do |test_set|
|
|
|
|
|
actual_output = test_set.attributes.count > 4 ? test_set.try(:actual_output) : nil
|
|
|
|
|
result = test_set.attributes.count > 4 ? test_set.try(:result) : nil
|
|
|
|
|
#actual_output = Base64.encode64(actual_output)
|
|
|
|
|
compile_success = (actual_output.blank? || actual_output.downcase.match(/error/).present?) ? 0 : 1
|
|
|
|
|
public_result = {:is_public => (test_set.is_public ? 1 : 0), :result => result, :input => test_set.input,
|
|
|
|
|
:actual_output => actual_output, :output => test_set.output, :compile_success => compile_success}
|
|
|
|
|
test_result << public_result.to_json
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
test_result = test_result.blank? ? test_result : test_result.join(",")
|
|
|
|
|
return test_result.gsub(/<\/script>/, '<//script>')
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def entry_and_raw(is_raw)
|
|
|
|
|
@entry = @repository.entry(@path, @rev)
|
|
|
|
|
(show_error_not_found; return) unless @entry
|
|
|
|
|
|
|
|
|
|
# If the entry is a dir, show the browser
|
|
|
|
|
(show; return) if @entry.is_dir?
|
|
|
|
|
|
|
|
|
|
@content = @repository.cat(@path, @rev)
|
|
|
|
|
(show_error_not_found; return) unless @content
|
|
|
|
|
if is_raw || (@content.size && @content.size > Setting.file_max_size_displayed.to_i.kilobyte) || !is_entry_text_data?(@content, @path)
|
|
|
|
|
# Force the download
|
|
|
|
|
send_opt = { :filename => filename_for_content_disposition(@path.split('/').last) }
|
|
|
|
|
send_type = Redmine::MimeType.of(@path)
|
|
|
|
|
send_opt[:type] = send_type.to_s if send_type
|
|
|
|
|
send_opt[:disposition] = (Redmine::MimeType.is_type?('image', @path) && !is_raw ? 'inline' : 'attachment')
|
|
|
|
|
send_data @content, send_opt
|
|
|
|
|
else
|
|
|
|
|
# Prevent empty lines when displaying a file with Windows style eol
|
|
|
|
|
# TODO: UTF-16
|
|
|
|
|
# Is this needs? AttachmentsController reads file simply.
|
|
|
|
|
@content.gsub!("\r\n", "\n")
|
|
|
|
|
@changeset = @repository.find_changeset_by_name(@rev)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def is_entry_text_data?(ent, path)
|
|
|
|
|
# UTF-16 contains "\x00".
|
|
|
|
|
# It is very strict that file contains less than 30% of ascii symbols
|
|
|
|
|
# in non Western Europe.
|
|
|
|
|
return true if Redmine::MimeType.is_type?('text', path)
|
|
|
|
|
# Ruby 1.8.6 has a bug of integer divisions.
|
|
|
|
|
# http://apidock.com/ruby/v1_8_6_287/String/is_binary_data%3F
|
|
|
|
|
return false if ent.is_binary_data?
|
|
|
|
|
true
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def find_repository
|
|
|
|
|
@repository = @myshixun.repository
|
|
|
|
|
render_404 if @myshixun.gpid.nil?
|
|
|
|
|
@path = params[:path].is_a?(Array) ? params[:path].join('/') : params[:path].to_s
|
|
|
|
|
@g = Gitlab.client
|
|
|
|
|
@g_project = @g.project(@myshixun.gpid)
|
|
|
|
|
@g_default_branch = @g_project.default_branch
|
|
|
|
|
# gitlab端获取默认分支
|
|
|
|
|
@rev = params[:rev].blank? ? @g_default_branch : params[:rev].to_s.strip
|
|
|
|
|
rescue ActiveRecord::RecordNotFound
|
|
|
|
|
render_404
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def allowd_manager
|
|
|
|
|
render_403 unless (User.current.manager_of_myshixun?(@myshixun) || User.current.admin? || User.current.id == @myshixun.shixun.try(:user_id))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# 判断成员是否允许查看
|
|
|
|
|
def allowd_view
|
|
|
|
|
if @myshixun.shixun.try(:status) == 2 && @game.status == 3 && User.current.id != @myshixun.shixun.try(:user_id)
|
|
|
|
|
render_403
|
|
|
|
|
end
|
|
|
|
|
# render_403 if (@game.status == 3 && User.current.id != @myshixun.shixun.try(:user_id))
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def find__shixun_language
|
|
|
|
|
language = @myshixun.shixun.try(:language)
|
|
|
|
|
@language = language_switch(language)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# Find myshixun of id params[:id]
|
|
|
|
|
def find_myshixun
|
|
|
|
|
myshixun_id = params[:myshixun_id] || (params[:game] && params[:game][:myshixun_id])
|
|
|
|
|
@myshixun = Myshixun.find_by_identifier(myshixun_id)
|
|
|
|
|
if @myshixun.nil?
|
|
|
|
|
render_404
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
rescue ActiveRecord::RecordNotFound
|
|
|
|
|
render_404
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def find_game
|
|
|
|
|
# myshixun_id = params[:myshixun_id]
|
|
|
|
|
@game = Game.find_by_identifier(params[:id])
|
|
|
|
|
if @game.nil?
|
|
|
|
|
render_404
|
|
|
|
|
return
|
|
|
|
|
end
|
|
|
|
|
@myshixun = @game.myshixun
|
|
|
|
|
rescue ActiveRecord::RecordNotFound
|
|
|
|
|
render_404
|
|
|
|
|
end
|
|
|
|
|
end
|