Description:
add show testcase feature
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r625:7645a0f771ce - - 12 files changed: 113 inserted, 2 deleted

@@ -0,0 +1,24
1 + class TestcasesController < ApplicationController
2 + before_action :set_testcase, only: [:download_input,:download_sol]
3 + before_action :testcase_authorization
4 +
5 + def download_input
6 + send_data @testcase.input, type: 'text/plain', filename: "#{@testcase.problem.name}.#{@testcase.num}.in"
7 + end
8 +
9 + def download_sol
10 + send_data @testcase.sol, type: 'text/plain', filename: "#{@testcase.problem.name}.#{@testcase.num}.sol"
11 + end
12 +
13 +
14 + private
15 + # Use callbacks to share common setup or constraints between actions.
16 + def set_testcase
17 + @testcase = Testcase.find(params[:id])
18 + end
19 +
20 + # Only allow a trusted parameter "white list" through.
21 + def testcase_params
22 + params[:testcase]
23 + end
24 + end
@@ -0,0 +1,2
1 + module TestcasesHelper
2 + end
@@ -0,0 +1,25
1 + %h1 Test cases
2 + %h2= @problem.long_name
3 +
4 + /navbar
5 + %ul.nav.nav-pills{role: :tablist}
6 + - @problem.testcases.each.with_index do |tc,id|
7 + %li{role: :presentation, class: ('active' if id == 0)}
8 + %a{href:"#tc#{tc.id}", role: 'tab', data: {toggle: 'tab'}}= tc.num
9 +
10 + /actual data
11 + .tab-content
12 + - @problem.testcases.each.with_index do |tc,id|
13 + .tab-pane{id: "tc#{tc.id}",class: ('active' if id == 0)}
14 + .row
15 + .col-md-6
16 + %h3 Input
17 + = link_to "Download",download_input_problem_testcase_path(@problem,tc),class: 'btn btn-info btn-sm'
18 + .col-md-6
19 + %h3 Output
20 + = link_to "Download",download_sol_problem_testcase_path(@problem,tc),class: 'btn btn-info btn-sm'
21 + .row
22 + .col-md-6
23 + %textarea{ rows: 25,readonly: true,style: "width:100%;resize=none;overflow-y: scroll;"}= tc.input
24 + .col-md-6
25 + %textarea{ rows: 25,readonly: true,style: "width:100%;resize=none;overflow-y: scroll;"}= tc.sol
@@ -0,0 +1,7
1 + require 'test_helper'
2 +
3 + class TestcasesControllerTest < ActionController::TestCase
4 + setup do
5 + @testcase = testcases(:one)
6 + end
7 + end
@@ -28,24 +28,33
28 28 return true
29 29 end
30 30
31 31 def authorization_by_roles(allowed_roles)
32 32 return false unless authenticate
33 33 user = User.find(session[:user_id])
34 34 unless user.roles.detect { |role| allowed_roles.member?(role.name) }
35 35 unauthorized_redirect
36 36 return false
37 37 end
38 38 end
39 39
40 + def testcase_authorization
41 + #admin always has privileged
42 + if @current_user.admin?
43 + return true
44 + end
45 +
46 + unauthorized_redirect if GraderConfiguration["right.view_testcase"]
47 + end
48 +
40 49 protected
41 50
42 51 def authenticate
43 52 unless session[:user_id]
44 53 flash[:notice] = 'You need to login'
45 54 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
46 55 flash[:notice] = 'You need to login but you cannot log in at this time'
47 56 end
48 57 redirect_to :controller => 'main', :action => 'login'
49 58 return false
50 59 end
51 60
@@ -1,15 +1,16
1 1 class ProblemsController < ApplicationController
2 2
3 - before_filter :authenticate, :authorization
3 + before_action :authenticate, :authorization
4 + before_action :testcase_authorization, only: [:show_testcase]
4 5
5 6 in_place_edit_for :problem, :name
6 7 in_place_edit_for :problem, :full_name
7 8 in_place_edit_for :problem, :full_score
8 9
9 10 def index
10 11 @problems = Problem.order(date_added: :desc)
11 12 end
12 13
13 14 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
14 15 verify :method => :post, :only => [ :create, :quick_create,
15 16 :do_manage,
@@ -212,24 +213,28
212 213 @log = import_log
213 214 end
214 215
215 216 def remove_contest
216 217 problem = Problem.find(params[:id])
217 218 contest = Contest.find(params[:contest_id])
218 219 if problem!=nil and contest!=nil
219 220 problem.contests.delete(contest)
220 221 end
221 222 redirect_to :action => 'manage'
222 223 end
223 224
225 + def show_testcase
226 + @problem = Problem.includes(:testcases).find(params[:id])
227 + end
228 +
224 229 ##################################
225 230 protected
226 231
227 232 def allow_test_pair_import?
228 233 if defined? ALLOW_TEST_PAIR_IMPORT
229 234 return ALLOW_TEST_PAIR_IMPORT
230 235 else
231 236 return false
232 237 end
233 238 end
234 239
235 240 def change_date_added
@@ -1,24 +1,25
1 1 require 'yaml'
2 2
3 3 #
4 4 # This class also contains various login of the system.
5 5 #
6 6 class GraderConfiguration < ActiveRecord::Base
7 7
8 8 SYSTEM_MODE_CONF_KEY = 'system.mode'
9 9 TEST_REQUEST_EARLY_TIMEOUT_KEY = 'contest.test_request.early_timeout'
10 10 MULTICONTESTS_KEY = 'system.multicontests'
11 11 CONTEST_TIME_LIMIT_KEY = 'contest.time_limit'
12 12 MULTIPLE_IP_LOGIN_KEY = 'right.multiple_ip_login'
13 + VIEW_TESTCASE = 'right.view_testcase'
13 14
14 15 cattr_accessor :config_cache
15 16 cattr_accessor :task_grading_info_cache
16 17 cattr_accessor :contest_time_str
17 18 cattr_accessor :contest_time
18 19
19 20 GraderConfiguration.config_cache = nil
20 21 GraderConfiguration.task_grading_info_cache = nil
21 22
22 23 def self.config_cached?
23 24 (defined? CONFIGURATION_CACHE_ENABLED) and (CONFIGURATION_CACHE_ENABLED)
24 25 end
@@ -61,24 +62,28
61 62
62 63 def self.show_tasks_to?(user)
63 64 if time_limit_mode?
64 65 return false if not user.contest_started?
65 66 end
66 67 return true
67 68 end
68 69
69 70 def self.show_grading_result
70 71 return (get(SYSTEM_MODE_CONF_KEY)=='analysis')
71 72 end
72 73
74 + def self.show_testcase
75 + return get(VIEW_TESTCASE)
76 + end
77 +
73 78 def self.allow_test_request(user)
74 79 mode = get(SYSTEM_MODE_CONF_KEY)
75 80 early_timeout = get(TEST_REQUEST_EARLY_TIMEOUT_KEY)
76 81 if (mode=='contest')
77 82 return false if ((user.site!=nil) and
78 83 ((user.site.started!=true) or
79 84 (early_timeout and (user.site.time_left < 30.minutes))))
80 85 end
81 86 return false if mode=='analysis'
82 87 return true
83 88 end
84 89
@@ -15,13 +15,15
15 15 = " ["
16 16 %tt
17 17 = submission.grader_comment
18 18 = "]"
19 19 %br
20 20 %strong View:
21 21 - if GraderConfiguration.show_grading_result
22 22 = link_to '[detailed result]', :action => 'result', :id => submission.id
23 23 /= link_to "#{t 'main.cmp_msg'}", {:action => 'compiler_msg', :id => submission.id}, {popup: true,class: 'btn btn-xs btn-info'}
24 24 = link_to "#{t 'main.cmp_msg'}", compiler_msg_submission_path(submission.id), {popup: true,remote: true,class: 'btn btn-xs btn-info'}
25 25 = link_to "#{t 'main.src_link'}",{:action => 'source', :id => submission.id}, class: 'btn btn-xs btn-info'
26 26 = link_to "#{t 'main.submissions_link'}", problem_submissions_path(problem_id), class: 'btn btn-xs btn-info'
27 + - if GraderConfiguration.show_testcase
28 + = link_to "testcases", show_testcase_problem_path(problem_id), class: 'btn btn-xs btn-info'
27 29
@@ -9,31 +9,39
9 9
10 10 resources :announcements do
11 11 member do
12 12 get 'toggle','toggle_front'
13 13 end
14 14 end
15 15
16 16 resources :problems do
17 17 member do
18 18 get 'toggle'
19 19 get 'toggle_test'
20 20 get 'stat'
21 + get 'show_testcase'
21 22 end
22 23 collection do
23 24 get 'turn_all_off'
24 25 get 'turn_all_on'
25 26 get 'import'
26 27 get 'manage'
27 28 end
29 +
30 + resources :testcases, only: [] do
31 + member do
32 + get 'download_input'
33 + get 'download_sol'
34 + end
35 + end
28 36 end
29 37
30 38 resources :grader_configuration, controller: 'configurations'
31 39
32 40 resources :users do
33 41 member do
34 42 get 'toggle_activate', 'toggle_enable'
35 43 get 'stat'
36 44 end
37 45 end
38 46
39 47 resources :submissions do
@@ -80,24 +80,30
80 80 :value_type => 'boolean',
81 81 :default_value => 'true',
82 82 :description => 'When false, a user must accept usage agreement before login'
83 83 },
84 84
85 85 {
86 86 :key => 'right.heartbeat_response',
87 87 :value_type => 'string',
88 88 :default_value => 'OK',
89 89 :description => 'Heart beat response text'
90 90 },
91 91
92 + {
93 + :key => 'right.view_testcase',
94 + :value_type => 'boolean',
95 + :default_value => 'false',
96 + :description => 'When true, any user can view/download test data'
97 + },
92 98 # If Configuration['system.online_registration'] is true, the
93 99 # system allows online registration, and will use these
94 100 # information for sending confirmation emails.
95 101 {
96 102 :key => 'system.online_registration.smtp',
97 103 :value_type => 'string',
98 104 :default_value => 'smtp.somehost.com'
99 105 },
100 106
101 107 {
102 108 :key => 'system.online_registration.from',
103 109 :value_type => 'string',
@@ -40,19 +40,34
40 40 checker_name='text')
41 41 if GraderScript.grader_control_enabled?
42 42 cur_dir = `pwd`.chomp
43 43 Dir.chdir(GRADER_ROOT_DIR)
44 44
45 45 script_name = File.join(GRADER_ROOT_DIR, "scripts/import_problem")
46 46 cmd = "#{script_name} #{problem_name} #{problem_dir} #{checker_name}" +
47 47 " -t #{time_limit} -m #{memory_limit}"
48 48
49 49 output = `#{cmd}`
50 50
51 51 Dir.chdir(cur_dir)
52 -
52 +
53 53 return "import CMD: #{cmd}\n" + output
54 54 end
55 55 return ''
56 56 end
57 57
58 + def self.call_import_testcase(problem_name)
59 + if GraderScript.grader_control_enabled?
60 + cur_dir = `pwd`.chomp
61 + Dir.chdir(GRADER_ROOT_DIR)
62 +
63 + script_name = File.join(GRADER_ROOT_DIR, "scripts/load_testcase")
64 + cmd = "#{script_name} #{problem_name}"
65 +
66 + output = `#{cmd}`
67 +
68 + Dir.chdir(cur_dir)
69 + return "Testcase import result:\n" + output
70 + end
71 + end
72 +
58 73 end
@@ -29,24 +29,27
29 29 if import_test_pairs(dirname)
30 30 test_pair_count = TestPair.count :conditions => "problem_id = #{@problem.id}"
31 31 @log_msg = "Importing test pair successful. (#{test_pair_count} test pairs imported)"
32 32 else
33 33 @log_msg = "Importing test pair failed. (0 test pairs imported)"
34 34 end
35 35 end
36 36
37 37 @log_msg << import_problem_description(dirname)
38 38 @log_msg << import_problem_pdf(dirname)
39 39 @log_msg << import_full_score(dirname)
40 40
41 + #import test data
42 + @log_msg << GraderScript.call_import_testcase(@problem.name)
43 +
41 44 return true
42 45 end
43 46
44 47 protected
45 48
46 49 def self.long_ext(filename)
47 50 i = filename.index('.')
48 51 len = filename.length
49 52 return filename.slice(i..len)
50 53 end
51 54
52 55 def extract(tempfile)
You need to be logged in to leave comments. Login now