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
@@ -1,87 +1,96
1 1 class ApplicationController < ActionController::Base
2 2 protect_from_forgery
3 3
4 4 before_filter :current_user
5 5
6 6 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
7 7 MULTIPLE_IP_LOGIN_CONF_KEY = 'right.multiple_ip_login'
8 8
9 9 #report and redirect for unauthorized activities
10 10 def unauthorized_redirect
11 11 flash[:notice] = 'You are not authorized to view the page you requested'
12 12 redirect_to :controller => 'main', :action => 'login'
13 13 end
14 14
15 15 # Returns the current logged-in user (if any).
16 16 def current_user
17 17 return nil unless session[:user_id]
18 18 @current_user ||= User.find(session[:user_id])
19 19 end
20 20
21 21 def admin_authorization
22 22 return false unless authenticate
23 23 user = User.includes(:roles).find(session[:user_id])
24 24 unless user.admin?
25 25 unauthorized_redirect
26 26 return false
27 27 end
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
52 61 # check if run in single user mode
53 62 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
54 63 user = User.find_by_id(session[:user_id])
55 64 if user==nil or (not user.admin?)
56 65 flash[:notice] = 'You cannot log in at this time'
57 66 redirect_to :controller => 'main', :action => 'login'
58 67 return false
59 68 end
60 69 unless user.enabled?
61 70 flash[:notice] = 'Your account is disabled'
62 71 redirect_to :controller => 'main', :action => 'login'
63 72 return false
64 73 end
65 74 return true
66 75 end
67 76
68 77 if GraderConfiguration.multicontests?
69 78 user = User.find(session[:user_id])
70 79 return true if user.admin?
71 80 begin
72 81 if user.contest_stat(true).forced_logout
73 82 flash[:notice] = 'You have been automatically logged out.'
74 83 redirect_to :controller => 'main', :action => 'index'
75 84 end
76 85 rescue
77 86 end
78 87 end
79 88 return true
80 89 end
81 90
82 91 def authenticate_by_ip_address
83 92 #this assume that we have already authenticate normally
84 93 unless GraderConfiguration[MULTIPLE_IP_LOGIN_CONF_KEY]
85 94 user = User.find(session[:user_id])
86 95 if (not user.admin? and user.last_ip and user.last_ip != request.remote_ip)
87 96 flash[:notice] = "You cannot use the system from #{request.remote_ip}. Your last ip is #{user.last_ip}"
@@ -1,51 +1,52
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,
16 17 :do_import,
17 18 ],
18 19 :redirect_to => { :action => :index }
19 20
20 21 def show
21 22 @problem = Problem.find(params[:id])
22 23 end
23 24
24 25 def new
25 26 @problem = Problem.new
26 27 @description = nil
27 28 end
28 29
29 30 def create
30 31 @problem = Problem.new(params[:problem])
31 32 @description = Description.new(params[:description])
32 33 if @description.body!=''
33 34 if !@description.save
34 35 render :action => new and return
35 36 end
36 37 else
37 38 @description = nil
38 39 end
39 40 @problem.description = @description
40 41 if @problem.save
41 42 flash[:notice] = 'Problem was successfully created.'
42 43 redirect_to action: :index
43 44 else
44 45 render :action => 'new'
45 46 end
46 47 end
47 48
48 49 def quick_create
49 50 @problem = Problem.new(params[:problem])
50 51 @problem.full_name = @problem.name if @problem.full_name == ''
51 52 @problem.full_score = 100
@@ -176,96 +177,100
176 177 def manage
177 178 @problems = Problem.order(date_added: :desc)
178 179 end
179 180
180 181 def do_manage
181 182 if params.has_key? 'change_date_added'
182 183 change_date_added
183 184 elsif params.has_key? 'add_to_contest'
184 185 add_to_contest
185 186 elsif params.has_key? 'enable_problem'
186 187 set_available(true)
187 188 elsif params.has_key? 'disable_problem'
188 189 set_available(false)
189 190 end
190 191 redirect_to :action => 'manage'
191 192 end
192 193
193 194 def import
194 195 @allow_test_pair_import = allow_test_pair_import?
195 196 end
196 197
197 198 def do_import
198 199 old_problem = Problem.find_by_name(params[:name])
199 200 if !allow_test_pair_import? and params.has_key? :import_to_db
200 201 params.delete :import_to_db
201 202 end
202 203 @problem, import_log = Problem.create_from_import_form_params(params,
203 204 old_problem)
204 205
205 206 if !@problem.errors.empty?
206 207 render :action => 'import' and return
207 208 end
208 209
209 210 if old_problem!=nil
210 211 flash[:notice] = "The test data has been replaced for problem #{@problem.name}"
211 212 end
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
236 241 problems = get_problems_from_params
237 242 year = params[:date_added][:year].to_i
238 243 month = params[:date_added][:month].to_i
239 244 day = params[:date_added][:day].to_i
240 245 date = Date.new(year,month,day)
241 246 problems.each do |p|
242 247 p.date_added = date
243 248 p.save
244 249 end
245 250 end
246 251
247 252 def add_to_contest
248 253 problems = get_problems_from_params
249 254 contest = Contest.find(params[:contest][:id])
250 255 if contest!=nil and contest.enabled
251 256 problems.each do |p|
252 257 p.contests << contest
253 258 end
254 259 end
255 260 end
256 261
257 262 def set_available(avail)
258 263 problems = get_problems_from_params
259 264 problems.each do |p|
260 265 p.available = avail
261 266 p.save
262 267 end
263 268 end
264 269
265 270 def get_problems_from_params
266 271 problems = []
267 272 params.keys.each do |k|
268 273 if k.index('prob-')==0
269 274 name, id, order = k.split('-')
270 275 problems << Problem.find(id)
271 276 end
@@ -1,120 +1,125
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
25 26
26 27 def self.get(key)
27 28 if GraderConfiguration.config_cached?
28 29 if GraderConfiguration.config_cache == nil
29 30 self.read_config
30 31 end
31 32 return GraderConfiguration.config_cache[key]
32 33 else
33 34 return GraderConfiguration.read_one_key(key)
34 35 end
35 36 end
36 37
37 38 def self.[](key)
38 39 self.get(key)
39 40 end
40 41
41 42 def self.reload
42 43 self.read_config
43 44 end
44 45
45 46 def self.clear
46 47 GraderConfiguration.config_cache = nil
47 48 end
48 49
49 50 #
50 51 # View decision
51 52 #
52 53 def self.show_submitbox_to?(user)
53 54 mode = get(SYSTEM_MODE_CONF_KEY)
54 55 return false if mode=='analysis'
55 56 if (mode=='contest')
56 57 return false if (user.site!=nil) and
57 58 ((user.site.started!=true) or (user.site.finished?))
58 59 end
59 60 return true
60 61 end
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
85 90 def self.task_grading_info
86 91 if GraderConfiguration.task_grading_info_cache==nil
87 92 read_grading_info
88 93 end
89 94 return GraderConfiguration.task_grading_info_cache
90 95 end
91 96
92 97 def self.standard_mode?
93 98 return get(SYSTEM_MODE_CONF_KEY) == 'standard'
94 99 end
95 100
96 101 def self.contest_mode?
97 102 return get(SYSTEM_MODE_CONF_KEY) == 'contest'
98 103 end
99 104
100 105 def self.indv_contest_mode?
101 106 return get(SYSTEM_MODE_CONF_KEY) == 'indv-contest'
102 107 end
103 108
104 109 def self.multicontests?
105 110 return get(MULTICONTESTS_KEY) == true
106 111 end
107 112
108 113 def self.time_limit_mode?
109 114 mode = get(SYSTEM_MODE_CONF_KEY)
110 115 return ((mode == 'contest') or (mode == 'indv-contest'))
111 116 end
112 117
113 118 def self.analysis_mode?
114 119 return get(SYSTEM_MODE_CONF_KEY) == 'analysis'
115 120 end
116 121
117 122 def self.contest_time_limit
118 123 contest_time_str = GraderConfiguration[CONTEST_TIME_LIMIT_KEY]
119 124
120 125 if not defined? GraderConfiguration.contest_time_str
@@ -1,27 +1,29
1 1
2 2 - if submission.nil?
3 3 = "-"
4 4 - else
5 5 - unless submission.graded_at
6 6 = t 'main.submitted_at'
7 7 = format_short_time(submission.submitted_at.localtime)
8 8 - else
9 9 %strong= t 'main.graded_at'
10 10 = "#{format_short_time(submission.graded_at.localtime)} "
11 11 %br
12 12 - if GraderConfiguration['ui.show_score']
13 13 %strong=t 'main.score'
14 14 = "#{(submission.points*100/submission.problem.full_score).to_i} "
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
@@ -1,75 +1,83
1 1 CafeGrader::Application.routes.draw do
2 2 get "sources/direct_edit"
3 3
4 4 root :to => 'main#login'
5 5
6 6 resources :contests
7 7
8 8 resources :sites
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
40 48 member do
41 49 get 'download'
42 50 get 'compiler_msg'
43 51 end
44 52 collection do
45 53 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
46 54 get 'direct_edit_problem/:problem_id', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
47 55 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
48 56 end
49 57 end
50 58
51 59 get 'tasks/view/:file.:ext' => 'tasks#view'
52 60 get 'tasks/download/:id/:file.:ext' => 'tasks#download'
53 61 get 'heartbeat/:id/edit' => 'heartbeat#edit'
54 62
55 63 #main
56 64 get "main/list"
57 65 get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
58 66
59 67 #report
60 68 get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
61 69 get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
62 70 get "report/login"
63 71 get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
64 72 post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
65 73
66 74 #grader
67 75 get 'graders/list', to: 'graders#list', as: 'grader_list'
68 76
69 77
70 78 get 'heartbeat/:id/edit' => 'heartbeat#edit'
71 79
72 80 # See how all your routes lay out with "rake routes"
73 81
74 82 # This is a legacy wild controller route that's not recommended for RESTful applications.
75 83 # Note: This route will make all actions in every controller accessible via GET requests.
@@ -44,96 +44,102
44 44 :value_type => 'string',
45 45 :default_value => 'Grader',
46 46 :description => 'This name will be shown on the user header bar.'
47 47 },
48 48
49 49 {
50 50 :key => 'contest.multisites',
51 51 :value_type => 'boolean',
52 52 :default_value => 'false',
53 53 :description => 'If the server is in contest mode and this option is true, on the log in of the admin a menu for site selections is shown.'
54 54 },
55 55
56 56 #---------------------------- right --------------------------------
57 57 {
58 58 :key => 'right.user_hall_of_fame',
59 59 :value_type => 'boolean',
60 60 :default_value => 'false',
61 61 :description => 'If true, any user can access hall of fame page.'
62 62 },
63 63
64 64 {
65 65 :key => 'right.multiple_ip_login',
66 66 :value_type => 'boolean',
67 67 :default_value => 'true',
68 68 :description => 'When change from true to false, a user can login from the first IP they logged into afterward.'
69 69 },
70 70
71 71 {
72 72 :key => 'right.user_view_submission',
73 73 :value_type => 'boolean',
74 74 :default_value => 'false',
75 75 :description => 'If true, any user can view submissions of every one.'
76 76 },
77 77
78 78 {
79 79 :key => 'right.bypass_agreement',
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',
104 110 :default_value => 'your.email@address'
105 111 },
106 112
107 113 {
108 114 :key => 'system.admin_email',
109 115 :value_type => 'string',
110 116 :default_value => 'admin@admin.email'
111 117 },
112 118
113 119 {
114 120 :key => 'system.user_setting_enabled',
115 121 :value_type => 'boolean',
116 122 :default_value => 'true',
117 123 :description => 'If this option is true, users can change their settings'
118 124 },
119 125
120 126 {
121 127 :key => 'system.user_setting_enabled',
122 128 :value_type => 'boolean',
123 129 :default_value => 'true',
124 130 :description => 'If this option is true, users can change their settings'
125 131 },
126 132
127 133 # If Configuration['contest.test_request.early_timeout'] is true
128 134 # the user will not be able to use test request at 30 minutes
129 135 # before the contest ends.
130 136 {
131 137 :key => 'contest.test_request.early_timeout',
132 138 :value_type => 'boolean',
133 139 :default_value => 'false'
134 140 },
135 141
136 142 {
137 143 :key => 'system.multicontests',
138 144 :value_type => 'boolean',
139 145 :default_value => 'false'
@@ -4,55 +4,70
4 4 if defined? GRADER_ROOT_DIR
5 5 GRADER_ROOT_DIR != ''
6 6 else
7 7 false
8 8 end
9 9 end
10 10
11 11 def self.raw_dir
12 12 File.join GRADER_ROOT_DIR, "raw"
13 13 end
14 14
15 15 def self.call_grader(params)
16 16 if GraderScript.grader_control_enabled?
17 17 cmd = File.join(GRADER_ROOT_DIR, "scripts/grader") + " " + params
18 18 system(cmd)
19 19 end
20 20 end
21 21
22 22 def self.stop_grader(pid)
23 23 GraderScript.call_grader "stop #{pid}"
24 24 end
25 25
26 26 def self.stop_graders(pids)
27 27 pid_str = (pids.map { |process| process.pid.to_s }).join ' '
28 28 GraderScript.call_grader "stop #{pid_str}"
29 29 end
30 30
31 31 def self.start_grader(env)
32 32 GraderScript.call_grader "#{env} queue --err-log &"
33 33 GraderScript.call_grader "#{env} test_request -err-log &"
34 34 end
35 35
36 36 def self.call_import_problem(problem_name,
37 37 problem_dir,
38 38 time_limit=1,
39 39 memory_limit=32,
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
@@ -1,88 +1,91
1 1 require 'tmpdir'
2 2
3 3 class TestdataImporter
4 4
5 5 attr :log_msg
6 6
7 7 def initialize(problem)
8 8 @problem = problem
9 9 end
10 10
11 11 def import_from_file(tempfile,
12 12 time_limit,
13 13 memory_limit,
14 14 checker_name='text',
15 15 import_to_db=false)
16 16
17 17 dirname = extract(tempfile)
18 18 return false if not dirname
19 19 if not import_to_db
20 20 @log_msg = GraderScript.call_import_problem(@problem.name,
21 21 dirname,
22 22 time_limit,
23 23 memory_limit,
24 24 checker_name)
25 25 else
26 26 # Import test data to test pairs.
27 27
28 28 @problem.test_pairs.clear
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)
53 56 testdata_filename = save_testdata_file(tempfile)
54 57 ext = TestdataImporter.long_ext(tempfile.original_filename)
55 58
56 59 extract_dir = File.join(GraderScript.raw_dir, @problem.name)
57 60 if File.exists? extract_dir
58 61 backup_count = 0
59 62 begin
60 63 backup_count += 1
61 64 backup_dirname = "#{extract_dir}.backup.#{backup_count}"
62 65 end while File.exists? backup_dirname
63 66 File.rename(extract_dir, backup_dirname)
64 67 end
65 68 Dir.mkdir extract_dir
66 69
67 70 if ext=='.tar.gz' or ext=='.tgz'
68 71 cmd = "tar -zxvf #{testdata_filename} -C #{extract_dir}"
69 72 elsif ext=='.tar'
70 73 cmd = "tar -xvf #{testdata_filename} -C #{extract_dir}"
71 74 elsif ext=='.zip'
72 75 cmd = "unzip -o #{testdata_filename} -d #{extract_dir}"
73 76 else
74 77 return nil
75 78 end
76 79
77 80 system(cmd)
78 81
79 82 files = Dir["#{extract_dir}/**/*1*.in"]
80 83 return nil if files.length==0
81 84
82 85 File.delete(testdata_filename)
83 86
84 87 return File.dirname(files[0])
85 88 end
86 89
87 90 def save_testdata_file(tempfile)
88 91 ext = TestdataImporter.long_ext(tempfile.original_filename)
You need to be logged in to leave comments. Login now