educoder/app/controllers/games_controller.rb

292 lines
12 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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, :outputs_show, :file_edit, :file_update, :game_status, :change_status]
before_filter :find_repository, :only => [:show, :entry, :file_edit, :file_update]
before_filter :allowd_manager
before_filter :allowd_view, :only => [:show]
before_filter :find__shixun_language, :only => [:show, :entry]
include ApplicationHelper
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 判断是否点赞
# @praise 判断是否踩
def show
@game_challenge = @game.challenge
(@myshixun.games.count == @game_challenge.position && @game.status ==2) ? @had_done = 1 : @had_done = 0
@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
logger.info("test ................#{@game_challenge.id}")
game_path = (@game_challenge.path.blank? ? @path : @game_challenge.path.strip)
logger.info("test game_path ................#{game_path}")
@rev = @rev.nil? ? "master" : @rev
@git_url = git_repository_url(@myshixun, "Myshixun")
@type = params[:type]
logger.info("##########************languae is #{@language}")
logger.info("out is666************#{@path} ")
logger.info("git_url************#{@git_url} ")
logger.info("game_path************#{game_path} ")
logger.info("repository************#{@repository} type is #{@type} ")
logger.info("content************#{@repository.cat(game_path, @rev)} ")
# 默认打开文件
if @path == "" && !game_path.nil? && !@repository.cat(game_path, @rev).blank? && @type != "root"
@path = game_path
@file_open = true
logger.info("@git_url************#{@git_url} ")
logger.info("666666666666************languae ")
logger.info("path is666************#{@path} ")
logger.info("repository is666************#{@repository} ")
file_content = @g.files(@myshixun.gpid, @path, @rev).content
@content = Base64.decode64(file_content) unless file_content.blank?
logger.info("contentdddd#{@content.first(5)} ")
else
logger.info("77777************languae ")
logger.info("77777repository************#{@repository} ")
logger.info("77777@git_url************#{@git_url} ")
@entries = @repository.entries(@path, @rev)
logger.info("7777************#{@entries} ")
end
logger.info("88888************#{@entries} ")
# 页面前后端分离数据转换
test_sets = @game_challenge.test_sets
unless test_sets.blank?
public_test_sets = test_sets.where(:is_public => true)
logger.info("#################################{test_set_static_data(public_test_sets)}")
@public_test_sets = test_set_static_data(public_test_sets)
private_test_sets = test_sets.where(:is_public => false)
@private_test_sets = test_set_static_data(private_test_sets)
end
logger.info("#################################{@public_test_sets}")
error_position = Output.where(:game_id => @game.id, :result => false).first
@error_position = error_position.blank? ? 0 : error_position.try(:test_set_id).to_i
@passed_teststest = test_sets.where(:result => true).count
@test_sets_count = test_sets.count
(@myshixun.games.count == @game_challenge.position && @game.status ==2) ? @had_done = 1 : @had_done = 0
@test_sets_hidden_count = private_test_sets.count
@final_score = @game.final_score.to_i
@game_outputs_count = Output.where(:game_id => @game.id).count
@latest_output = @game.latest_output.try(:out_put)
respond_to do |format|
format.html
format.js
end
rescue Exception => e
logger.error("##############{e.message}")
flash[:error] = e.message
end
# 代码预览
def entry
entry_and_raw(false)
@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].strip
@g.edit_file(@myshixun.gpid, :content => params[:content], :file_path => @path, :branch_name => @rev, :commit_message => "shixun exec")
respond_to do |format|
format.js{redirect_to entry_myshixun_game_path(@game, :myshixun_id => @myshixun, :path => @path)}
end
rescue Exception => e
puts e.message
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
# status 0: 未提交测评或者提交测评失败后报错1中间状态还没返回值2返回值并成功
def game_build
game_challenge = @game.challenge
gitUrl = git_repository_url(@myshixun, "Myshixun")
gitUrl = Base64.encode64(gitUrl)
taskId = params[:id]
jobName = "myshixun_#{@myshixun.id}"
ActiveRecord::Base.transaction do
@game.update_attributes!(:status => 1)
jenkins_shixuns = Redmine::Configuration['jenkins_shixuns']
step = game_challenge.try(:position)
params = {:jobNameForInstance => "#{jobName}", :buildID => "#{taskId}", :step => "#{step}", :instanceGitURL => "#{gitUrl}", :instanceChallenge => "#{step}"}
uri = URI("#{jenkins_shixuns}/jenkins-exec/api/buildJobForInstance")
res = uri_exec uri, params
if (res && res['code'] != 0)
raise("Build job failed")
end
render :json => {:result => "success"}
end
rescue
raise ActiveRecord::Rollback
#REDO Jenkins服务异常弹框抛出
redirect_to myshixun_game_path(@game, :myshixun_id => @myshixun)
end
def game_status
game_challenge = @game.challenge
(@myshixun.games.count == game_challenge.position && @game.status ==2) ? had_done = 1 : had_done = 0
# 下一关自动开启
if had_done != 1 && @game.status == 2
@game.next_game.update_attribute(:status, 0)
end
test_sets = game_challenge.test_sets
unless test_sets.blank?
public_test_sets = test_sets.where(:is_public => true)
@public_test_sets = test_set_static_data(public_test_sets).blank? ? [] : test_set_static_data(public_test_sets)
private_test_sets = test_sets.where(:is_public => false)
@private_test_sets = test_set_static_data(private_test_sets).blank? ? [] : test_set_static_data(private_test_sets)
end
latest_output = @game.latest_output.try(:out_put)
error_position = Output.where(:game_id => @game.id, :result => false).first
error_position = error_position.blank? ? 0 : error_position.try(:test_set_id).to_i
passed_teststest = test_sets.where(:result => true).count
test_sets_count = test_sets.count
test_sets_hidden_count = private_test_sets.count
game_outputs_count = Output.where(:game_id => @game.id).count
final_score = @game.final_score.to_i
render :json => {status: @game.status, had_done: had_done, latest_output: latest_output,
error_position: error_position, passed_teststest:passed_teststest, test_sets_count:test_sets_count, test_sets_hidden_count:test_sets_hidden_count,
final_score:final_score, game_outputs_count:game_outputs_count}
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
# 自动推送下一个任务
def next_step
render_403 if @game.status != 2
next_game = @game.next_game
next_game.update_attributes(:status => 0, :open_time => Time.now) if next_game.status == 3
redirect_to myshixun_game_path(next_game, :myshixun_id => @myshixun.id)
end
private
def test_set_static_data test_sets
result = []
unless test_sets.blank?
test_sets.each do |test_set|
output = Output.where(:game_id => @game.id, :test_set_id => test_set.position)
actual_output = output.blank? ? test_set.actual_output : output.first.try(:expect_output)
public_result = {:is_public => (test_set.is_public ? 1 : 0), :result => (test_set.result ? 1 : 0), :input => test_set.input,
:actual_output => actual_output, :output => test_set.output}
result << public_result.to_json
end
end
return 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
render_403 if @game.status == 3
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(myshixun_id)
rescue ActiveRecord::RecordNotFound
render_404
end
def find_game
@game = Game.find(params[:id])
@myshixun = @game.myshixun
rescue ActiveRecord::RecordNotFound
render_404
end
end