You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
educoder/app/controllers/hack_user_lastest_codes_con...

166 lines
5.3 KiB

class HackUserLastestCodesController < ApplicationController
5 years ago
before_action :require_login, except: [:listen_result]
5 years ago
before_action :find_user_hack, only: [:show, :code_debug, :code_submit, :update_code, :listen_result]
before_action :update_user_hack_status, only: [:code_debug, :code_submit]
5 years ago
before_action :require_auth_identity, only: [:update_code]
before_action :require_manager_identity, only: [:update_code]
5 years ago
def show
@my_hack.update_attribute(:status, 0) if @my_hack.status == 1
end
5 years ago
5 years ago
def update_code
@my_hack.update_attribute(:code, params[:code])
end
5 years ago
# 调试代码
def code_debug
exec_mode = "debug"
error_status = 501
error_msg = "debug_error"
oj_evaluate exec_mode, error_status, error_msg
render_ok
5 years ago
end
5 years ago
# 提交
def code_submit
5 years ago
exec_mode = "normal"
5 years ago
error_status = 502
error_msg = "submit_error"
oj_evaluate exec_mode, error_status, error_msg
render_ok
end
5 years ago
# 提交结果显示
def result
end
5 years ago
# 接收中间件返回结果接口
5 years ago
# 调试模式: status 0 表示评测无错误,其他 表示错误(如编译出错,执行出错,超时等)
5 years ago
def listen_result
logger.info("###########listen_result#{params}")
5 years ago
begin
5 years ago
ojEvaResult = JSON.parse(params[:ojEvaResult])
testCase = ojEvaResult['testCase']
5 years ago
# 只有编译出错时,才正则匹配错误行数
5 years ago
error_line=
if params[:status] == "-4"
5 years ago
regular_match_error_line ojEvaResult['outPut'], @my_hack.hack.language
5 years ago
end
# debug 与submit 公用的参数
5 years ago
ds_params = {input: testCase['input'], output: testCase['output'], hack_id: @hack.id,
user_id: @my_hack.user_id, error_line: error_line, status: ojEvaResult['status'],
error_msg: ojEvaResult[:outPut], execute_time: ojEvaResult['executeTime'],
execute_memory: ojEvaResult['executeMem']}
5 years ago
ActiveRecord::Base.transaction do
# debug模式与submit模式
if params[:execMode] == "debug"
save_debug_data ds_params
elsif params[:execMode] == "normal"
save_submit_data ds_params
end
# 评测完成后,还原评测中的状态
@my_hack.update_attribute(:submit_status, 0)
5 years ago
end
5 years ago
rescue Exception => e
5 years ago
logger.error("#########listen_result: #{e.message}")
5 years ago
end
5 years ago
end
5 years ago
private
def find_user_hack
@my_hack = HackUserLastestCode.find_by(identifier: params[:identifier])
@hack = @my_hack.hack
end
5 years ago
def oj_evaluate exec_mode, error_status, error_msg
request_url = "#{edu_setting('cloud_bridge')}/bridge/ojs/evaluate"
5 years ago
test_sets =
if exec_mode == "normal"
@hack.hack_sets.map{|set| {input: set.input, output: set.output, caseId: set.id}}
else
{input: params[:input]}
end
testCases = Base64.urlsafe_encode64(test_sets.to_json)
5 years ago
codeFileContent = Base64.urlsafe_encode64(@my_hack.code)
5 years ago
debug_params = {execMode: exec_mode,
tpiID: @my_hack.identifier,
testCases: testCases,
platform: @my_hack.language,
5 years ago
codeFileContent: codeFileContent,
5 years ago
timeLimit: @hack.time_limit,
5 years ago
sec_key: Time.now.to_i}
5 years ago
interface_json_post request_url, debug_params, error_status, error_msg
5 years ago
# 每次评测提交数增加
@hack.increment!(:submit_num)
5 years ago
end
# 正则错误行数
def regular_match_error_line content, language
case language
when 'Java'
5 years ago
content.scan(/.java.\d+/).map{|s| s.match(/\d+/)[0].to_i}.min
when 'C', 'C++'
content.scan(/\d:\d+: error/).map{|s| s.match(/\d+/)[0]}.min
5 years ago
when 'Python'
5 years ago
content.scan(/line \d+/).map{|s| s.match(/\d+/)[0].to_i}.min
end
end
# 存储debug数据
def save_debug_data debug_params
if @my_hack.hack_user_debug.present?
@my_hack.hack_user_debug.update_attributes!(debug_params)
else
@my_hack.hack_user_debug.create!(debug_params)
end
end
# 存储submit数据
def save_submit_data submit_params
# 通关
if submit_params[:status] == "0"
# 编程题已经发布,且之前未通关奖励积分
if @hack.status == 1 && !@my_hack.passed?
reward_attrs = { container_id: game.id, container_type: 'Hack', score: @hack.score }
RewardGradeService.call(@my_hack.user, reward_attrs)
RewardExperienceService.call(@my_hack.user, reward_attrs)
# 评测完成更新通过数
@hack.increment!(:pass_num)
@my_hack.update_attribute(:passed, true)
end
end
# 创建用户评测记录
@my_hack.hack_user_codes.create!(submit_params)
end
# 调试或提交改变状态
def update_user_hack_status
@my_hack.update_attribute(:submit_status, 1)
end
# 只有自己才能改动代码
def require_identity
if @my_hack.user_id != current_user.id
tip_exception(403, "..")
end
end
5 years ago
# 老师、自己、管理可以查看他人的编程题
5 years ago
def require_manager_identity
unless current_user.certification_teacher? || admin_or_business? || @my_hack.user_id == current_user.id
tip_exception(403, "..")
5 years ago
end
end
5 years ago
# 只有自己才能评测
def require_auth_identity
unless @my_hack.user_id == current_user.id
tip_exception(403, "..")
end
end
end