718 lines
28 KiB
Ruby
718 lines
28 KiB
Ruby
#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,
|
||
:game_status, :change_status, :answer, :minus_score, :refresh_game_list, :reset_original_code, :reset_new_code, :evaluating_choice, :sync_codes]
|
||
before_filter :find_repository, :only => [:show, :entry, :file_edit, :file_update, :reset_original_code, :reset_new_code, :html_show]
|
||
before_filter :allowd_manager
|
||
before_filter :allowd_view, :only => [:show]
|
||
before_filter :find__shixun_language, :only => [:show, :entry]
|
||
include ApplicationHelper
|
||
|
||
require 'open3'
|
||
# 同步更新最新代码
|
||
# 同步完成后,需要更新myshixun的commit_id为实训的commit最新值
|
||
# --------------------------
|
||
# 新思路,有冲突则则重置,没有冲突直接pull
|
||
# --------------------------
|
||
def sync_codes
|
||
g = Gitlab.client
|
||
myshixun_user_login = User.where(:id => @myshixun.user_id).first.try(:login)
|
||
myshixun_rep_identifier = Repository.where(:myshixun_id => @myshixun.id, :type => "Repository::Gitlab").first.try(:identifier)
|
||
gitlab_address = Redmine::Configuration['gitlab_address']
|
||
myshixun_domain = Redmine::Configuration['myshixun_domain']
|
||
gitlab_myshixun_url = git_myshixun_url(@myshixun, @myshixun.try(:user_id))
|
||
shixun = @myshixun.shixun
|
||
gitlab_shixun_url = git_shixun_url(shixun, (shixun.try(:fork_from).blank? ? "educoder" : "eduforge"))
|
||
if RUBY_PLATFORM =~ /w32/
|
||
path = "c:/test/"
|
||
else
|
||
path = "/home/pdl/myshixun_shell"
|
||
end
|
||
script = "cd #{path}
|
||
git clone #{gitlab_address.to_s+'/'+myshixun_user_login+'/'+ myshixun_rep_identifier}.git
|
||
cd #{myshixun_rep_identifier}/
|
||
git remote set-url origin https://#{shixun.fork_from.blank? ? "educoder" : "eduforge"}:xinhu1ji2qu3@#{myshixun_domain}/#{myshixun_user_login}/#{myshixun_rep_identifier}.git
|
||
git remote add remote_origin #{gitlab_shixun_url}
|
||
#git pull
|
||
git pull remote_origin master
|
||
if [ $? -eq 0 ];then
|
||
echo -e 'git pull succssed'
|
||
else
|
||
git reset --hard #{@myshixun.commit_id}
|
||
git pull remote_origin master
|
||
if [ $? -eq 0 ];then
|
||
echo -e 'git reset and pull succssed'
|
||
else
|
||
echo -e 'git reset and pull failed'
|
||
fi
|
||
fi
|
||
git push -f origin master
|
||
if [ $? -eq 0 ];then
|
||
echo -e 'git push succssed'
|
||
else
|
||
echo -e 'git push failed'
|
||
fi
|
||
cd ../
|
||
rm -rf #{myshixun_rep_identifier}/"
|
||
aFile =File.new(File.join("#{path}","#{@myshixun.identifier}.sh"), "w+")
|
||
if aFile
|
||
aFile.syswrite(script)
|
||
else
|
||
logger.error "Unable to open file!"
|
||
end
|
||
system("sh #{path}/#{@myshixun.identifier}.sh")
|
||
# stdin, stdout, stderr = Open3.popen3("sh #{path}/#{@myshixun.identifier}.sh")
|
||
shixun_new_commit = g.commits(@myshixun.shixun.try(:gpid)).first.try(:id)
|
||
@myshixun.update_column(:commit_id, shixun_new_commit)
|
||
sleep(2) # g
|
||
respond_to do |format|
|
||
format.js{ redirect_to myshixun_game_path( @game, :myshixun_id => @myshixun)}
|
||
end
|
||
# render :json => {:status => 200}
|
||
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 选择题任务
|
||
def show
|
||
# g = Gitlab.client
|
||
# g_name = g.project(@myshixun.gpid).try(:name)
|
||
# if g_name.include?("-")
|
||
# g.delete_project()
|
||
# end
|
||
# 展示全部实训
|
||
# git_myshixun_url_ip @myshixun, user_id
|
||
@is_subject = params[:is_subject]
|
||
if @game.status == 1
|
||
# 放置页面ajax数据还没获取就关闭
|
||
@game.update_attribute(:status, 0)
|
||
end
|
||
# logger.info("#################%%%%%%#{@game.outputs.first.out_put}")
|
||
# @games = @myshixun.games.includes(:challenge)
|
||
@game_challenge = @game.challenge
|
||
@challenges = Challenge.where(:shixun_id => @myshixun.shixun_id)
|
||
@shixun = @myshixun.shixun
|
||
# 判断tpm是否修改了
|
||
@tpm_modified = tpm_is_modified(@myshixun, @shixun.try(:gpid))
|
||
# end
|
||
@praise_count = PraiseTread.where(:praise_tread_object_id => @game_challenge.id, :praise_tread_object_type => "Challenge").count
|
||
@tread_count = PraiseTread.where(:praise_tread_object_id => @game_challenge.id, :praise_tread_object_type => "ChallengeTread").count
|
||
# @games_count = @games.count
|
||
@st = @game_challenge.st
|
||
@had_done = @game.had_done
|
||
@praise = PraiseTread.where("praise_tread_object_id=? and praise_tread_object_type=? and user_id=?", @game_challenge.id, @game_challenge.class.to_s, User.current.id).first
|
||
@tread = PraiseTread.where("praise_tread_object_id=? and praise_tread_object_type=? and user_id=?", @game_challenge.id, "ChallengeTread", User.current.id).first
|
||
@rev = @rev.nil? ? "master" : @rev
|
||
@type = params[:type]
|
||
challenge_path = @game_challenge.path
|
||
@discusses_count = @shixun.discusses.where(:parent_id => nil).count
|
||
# 用户选项
|
||
#@user_answer = @game.outputs.first.actual_output.split("") unless @st == 0 || @game.outputs.blank?
|
||
# 默认打开文件
|
||
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文件名的合法性
|
||
if @path.blank? && !challenge_path.blank? && challenge_path.include?(".") && @type != "root"
|
||
@path = challenge_path.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?
|
||
@entries = @repository.entries(@path, @rev)
|
||
end
|
||
# 页面前后端分离数据转换
|
||
test_sets = @game_challenge.test_sets
|
||
unless test_sets.blank?
|
||
@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 = ((@game.answer_open? || @shixun.status <= 1) ? 0 : @game.final_score.to_i)
|
||
@gold = @myshixun.shixun.status <= 1 ? 0 : (@game.answer_open? ? -@game_challenge.score.to_i : @game.final_score.to_i)
|
||
@had_done = @game.had_done
|
||
@language = @game_challenge.shixun.language
|
||
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)
|
||
|
||
respond_to do |format|
|
||
format.html
|
||
format.js
|
||
end
|
||
rescue Exception => e
|
||
logger.error("game error##############{e.message}")
|
||
flash[:error] = e.message
|
||
end
|
||
|
||
# 代码预览
|
||
def entry
|
||
# entry_and_raw(false)
|
||
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 file_update
|
||
@g = Gitlab.client
|
||
content = params[:content].try(:strip)
|
||
code_file = @g.edit_file(@myshixun.gpid, :content => params[:content], :file_path => @path, :branch_name => @rev, :commit_message => "shixun exec")
|
||
unless code_file.blank?
|
||
render :json => {:success => "success"}
|
||
end
|
||
|
||
=begin
|
||
respond_to do |format|
|
||
format.js
|
||
end
|
||
rescue Exception => e
|
||
puts e.message
|
||
=end
|
||
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['onRun'] 0 表示在等待中 1 表示可执行
|
||
def get_waiting_time
|
||
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
|
||
uri = "#{shixun_tomcat}/bridge/game/getWaitingTime"
|
||
params = {:tpiID => "#{@myshixun.id}"}
|
||
resubmit = @_params['resubmit']
|
||
res = uri_exec uri, params
|
||
if (res && res['code'] != 0)
|
||
@message = "实训云平台繁忙(繁忙等级:94)"
|
||
raise("实训云平台繁忙(繁忙等级:94)")
|
||
end
|
||
render :json => {:result => "success", :onRun => res['onRun'], :waitNum => res['waitNum'], :waitingTime => res['waitingTime'], :resubmit => resubmit }
|
||
#render :json => {:result => "success", :onRun => 0, :waitNum => 12, :waitingTime => 1234 }
|
||
rescue Exception => e
|
||
render :json => {:result => "failed"}
|
||
end
|
||
|
||
# status 0: 未提交测评或者提交测评失败后报错;1:中间状态还没返回值;2:返回值并成功
|
||
# resubmit 唯一随机码,为了区分每一次重新评测结果
|
||
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)
|
||
def game_build
|
||
game_challenge = @game.challenge
|
||
shixun = @myshixun.shixun
|
||
gitUrl = git_myshixun_url_ip(@myshixun, @myshixun.try(:user_id))
|
||
gitUrl = Base64.urlsafe_encode64(gitUrl)
|
||
taskId = @game.id
|
||
code = CODES.sample(8).join
|
||
# status为2说明是重新评测
|
||
if @game.status == 2
|
||
resubmit = "#{code}_#{@myshixun.id}"
|
||
else
|
||
# 重新评测不影响已通关的实训状态
|
||
@game.update_attributes!(:status => 1) if resubmit.nil?
|
||
end
|
||
|
||
gameInfo = shixun.gameInfo
|
||
shixun_tomcat = Redmine::Configuration['shixun_tomcat']
|
||
step = game_challenge.try(:position)
|
||
# 注意:这个地方的参数写的时候不能换行
|
||
params = {:tpiID => "#{@myshixun.id}", :buildID => "#{taskId}", :instanceGitURL => "#{gitUrl}", :instanceChallenge => "#{step}", :resubmit => resubmit, :operationEnvironment => "#{shixun.try(:language)}"}
|
||
# uri = URI("#{shixun_tomcat}/bridge/game/gameEvaluate")
|
||
uri = "#{shixun_tomcat}/bridge/game/gameEvaluate"
|
||
res = uri_exec uri, params
|
||
logger.info("#####################buildJobForInstance result is #{res}")
|
||
logger.info("#####################buildJobForInstance params is #{params}")
|
||
if (res && res['code'] != 0)
|
||
@message = "实训云平台繁忙(繁忙等级:86)"
|
||
raise("实训云平台繁忙(繁忙等级:86)")
|
||
end
|
||
render :json => {:result => "success", :resubmit => resubmit}
|
||
rescue Exception => e
|
||
if resubmit.nil?
|
||
@game.update_attributes!(:status => 0)
|
||
end
|
||
logger.error("###################" + e.message)
|
||
#REDO Jenkins服务异常弹框抛出
|
||
render :json => {:result => "failed"}
|
||
end
|
||
|
||
# @myshixun -status 1:完成实训
|
||
# 全部通关奖励1000分
|
||
# retry_status 评测的唯一标识,重新评测对以前已产生的结果不造成影响
|
||
# params[:resubmit] 不为空表示已通过该关后重新评测, 重新评测必须是通过该关后才能执行
|
||
# @had_done 1 通关所有关
|
||
def game_status
|
||
game_challenge = @game.challenge
|
||
had_done = @game.had_done
|
||
resubmit_identifier = @game.resubmit_identifier
|
||
shixun = @myshixun.shixun
|
||
score = 0
|
||
tag_count = 0
|
||
logger.info("##### resubmit_identifier is #{resubmit_identifier}")
|
||
if params[:resubmit].blank? # 非重新评测
|
||
if had_done == 1 # 通过最后一关,即所有关卡
|
||
@myshixun.update_attribute(:status, 1)
|
||
end
|
||
# 通过当前一关
|
||
if @game.status == 2
|
||
@game.update_attribute(:end_time, Time.now)
|
||
game_passed_code(@game.id, game_challenge.try(:path), @myshixun.try(:gpid), 1)
|
||
if !@game.answer_open && shixun.status > 1
|
||
reward_grade(@game.user, @game.id, 'Game', game_challenge.score)
|
||
reward_experience(@game.user, @game.id, 'Game', game_challenge.score)
|
||
score = 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
|
||
game_passed_code(@game.id, game_challenge.try(:path), @myshixun.try(:gpid), 1)
|
||
else
|
||
had_done = 0
|
||
end
|
||
else
|
||
# game_status 在前端有行为判断,2表示通关;0表示失败;1表示评测中的中间状态
|
||
game_status = 1
|
||
had_done = 0
|
||
end
|
||
end
|
||
test_sets = game_challenge.test_sets
|
||
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 = ((@game.answer_open? || shixun.status <= 1) ? 0 : @game.final_score.to_i)
|
||
@gold = @myshixun.shixun.status <= 1 ? 0 : (@game.answer_open? ? -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
|
||
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,
|
||
tag_count: tag_count,
|
||
position: game_challenge.position
|
||
}
|
||
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
|
||
#choose.current_choose_outputs.delete if choose.current_choose_outputs.present?
|
||
#ChooseOutputs.create(:challenge_choose_id => choose.id, :user_id => User.current.id, :answer => params[:answer][index], :correct => correct)
|
||
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.update_attributes(:status => 2, :end_time => Time.now)
|
||
reward_grade(@game.user, @game.id, 'Game', score)
|
||
reward_experience(@game.user, @game.id, 'Game', score)
|
||
@game.update_attribute(:final_score, score)
|
||
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
|
||
|
||
# 自动推送下一个任务
|
||
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)}
|
||
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)}
|
||
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 || @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
|
||
user = User.current
|
||
challenge_score = @game_challenge.score.to_i
|
||
reward_grade(user, @game.id, 'Answer', -challenge_score)
|
||
@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
|
||
@game.update_column(:answer_open, true)
|
||
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)
|
||
|
||
respond_to do |format|
|
||
format.js
|
||
end
|
||
end
|
||
|
||
def reset_original_code
|
||
begin
|
||
@shixun = @myshixun.shixun
|
||
@g = Gitlab.client
|
||
game_code = GameCode.where(:game_id => @game.id).first
|
||
content = game_code.try(:original_code)
|
||
if content.nil?
|
||
raise("初始代码为空,代码重置失败")
|
||
end
|
||
@path = params[:path]
|
||
@rev = @rev.nil? ? "master" : @rev
|
||
message = "file reset"
|
||
update_gitlab_file(content, @path, @rev, message)
|
||
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
|
||
|
||
def reset_new_code
|
||
begin
|
||
@shixun = @myshixun.shixun
|
||
@g = Gitlab.client
|
||
game_code = GameCode.where(:game_id => @game.id).first
|
||
content = game_code.try(:new_code)
|
||
if content.nil?
|
||
raise("示例代码为空,代码重置失败")
|
||
end
|
||
@path = params[:path]
|
||
@rev = @rev.nil? ? "master" : @rev
|
||
message = "file reset"
|
||
update_gitlab_file(content, @path, @rev, message)
|
||
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, :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|
|
||
output = Output.where(:game_id => @game.id, :test_set_position => test_set.position).first
|
||
actual_output = output.try(:actual_output)
|
||
result = output.try(:result)
|
||
compile_success = (actual_output.blank? || !actual_output.downcase.match(/error/).blank?) ? 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}
|
||
logger.info("1111#################################{public_result.to_json}")
|
||
test_result << public_result.to_json
|
||
end
|
||
end
|
||
test_result = test_result.blank? ? test_result : test_result.join(",")
|
||
logger.info("222#################################{test_result}")
|
||
return test_result
|
||
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
|