diff --git a/app/controllers/main_controller.rb b/app/controllers/main_controller.rb --- a/app/controllers/main_controller.rb +++ b/app/controllers/main_controller.rb @@ -125,6 +125,46 @@ end end + def result + if !Configuration.show_grading_result + redirect_to :action => 'list' and return + end + @user = User.find(session[:user_id]) + @submission = Submission.find(params[:id]) + if @submission.user!=@user + flash[:notice] = 'You are not allowed to view result of other users.' + redirect_to :action => 'list' and return + end + prepare_grading_result(@submission) + end + + def load_output + if !Configuration.show_grading_result or params[:num]==nil + redirect_to :action => 'list' and return + end + @user = User.find(session[:user_id]) + @submission = Submission.find(params[:id]) + if @submission.user!=@user + flash[:notice] = 'You are not allowed to view result of other users.' + redirect_to :action => 'list' and return + end + case_num = params[:num].to_i + out_filename = output_filename(@user.login, + @submission.problem.name, + @submission.id, + case_num) + if !FileTest.exists?(out_filename) + flash[:notice] = 'Output not found.' + redirect_to :action => 'list' and return + end + + response.headers['Content-Type'] = "application/force-download" + response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\"" + response.headers["X-Sendfile"] = out_filename + response.headers['Content-length'] = File.size(out_filename) + render :nothing => true + end + def error @user = User.find(session[:user_id]) end @@ -156,5 +196,105 @@ end end + def prepare_grading_result(submission) + grading_info = Configuration.task_grading_info[submission.problem.name] + @test_runs = [] + if grading_info['testruns'].is_a? Integer + trun_count = grading_info['testruns'] + trun_count.times do |i| + @test_runs << [ read_grading_result(@user.login, + submission.problem.name, + submission.id, + i+1) ] + end + else + grading_info['testruns'].keys.sort.each do |num| + run = [] + testrun = grading_info['testruns'][num] + testrun.each do |c| + run << read_grading_result(@user.login, + submission.problem.name, + submission.id, + c) + end + @test_runs << run + end + end + end + + def grading_result_dir(user_name, problem_name, submission_id, case_num) + return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}" + end + + def output_filename(user_name, problem_name, submission_id, case_num) + dir = grading_result_dir(user_name,problem_name, submission_id, case_num) + return "#{dir}/output.txt" + end + + def read_grading_result(user_name, problem_name, submission_id, case_num) + dir = grading_result_dir(user_name,problem_name, submission_id, case_num) + result_file_name = "#{dir}/result" + if !FileTest.exists?(result_file_name) + return {:num => case_num, :msg => 'program did not run'} + else + results = File.open(result_file_name).readlines + run_stat = extract_running_stat(results) + output_filename = "#{dir}/output.txt" + if FileTest.exists?(output_filename) + output_file = true + output_size = File.size(output_filename) + else + output_file = false + output_size = 0 + end + + return { + :num => case_num, + :msg => results[0], + :run_stat => run_stat, + :output => output_file, + :output_size => output_size + } + end + end + + # copied from grader/script/lib/test_request_helper.rb + def extract_running_stat(results) + running_stat_line = results[-1] + + # extract exit status line + run_stat = "" + if !(/[Cc]orrect/.match(results[0])) + run_stat = results[0].chomp + else + run_stat = 'Program exited normally' + end + + logger.info "Stat line: #{running_stat_line}" + + # extract running time + if res = /r(.*)u(.*)s/.match(running_stat_line) + seconds = (res[1].to_f + res[2].to_f) + time_stat = "Time used: #{seconds} sec." + else + seconds = nil + time_stat = "Time used: n/a sec." + end + + # extract memory usage + if res = /s(.*)m/.match(running_stat_line) + memory_used = res[1].to_i + else + memory_used = -1 + end + + return { + :msg => "#{run_stat}\n#{time_stat}", + :running_time => seconds, + :exit_status => run_stat, + :memory_usage => memory_used + } + end + end