Description:
added test assignment time out
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r222:2b6293a64dbb - - 8 files changed: 42 inserted, 2 deleted

@@ -158,96 +158,101
158 158
159 159 def error
160 160 @user = User.find(session[:user_id])
161 161 end
162 162
163 163 # announcement refreshing and hiding methods
164 164
165 165 def announcements
166 166 if params.has_key? 'recent'
167 167 prepare_announcements(params[:recent])
168 168 else
169 169 prepare_announcements
170 170 end
171 171 render(:partial => 'announcement',
172 172 :collection => @announcements,
173 173 :locals => {:announcement_effect => true})
174 174 end
175 175
176 176 #
177 177 # actions for Code Jom
178 178 #
179 179 def download_input
180 180 problem = Problem.find(params[:id])
181 181 user = User.find(session[:user_id])
182 182 if user.can_request_new_test_pair_for? problem
183 183 assignment = user.get_new_test_pair_assignment_for problem
184 184 assignment.save
185 185
186 186 send_data(assignment.test_pair.input,
187 187 { :filename => "#{problem.name}-#{assignment.request_number}.in",
188 188 :type => 'text/plain' })
189 189 else
190 190 recent_assignment = user.get_recent_test_pair_assignment_for problem
191 191 send_data(recent_assignment.test_pair.input,
192 192 { :filename => "#{problem.name}-#{recent_assignment.request_number}.in",
193 193 :type => 'text/plain' })
194 194 end
195 195 end
196 196
197 197 def submit_solution
198 198 problem = Problem.find(params[:id])
199 199 user = User.find(session[:user_id])
200 200 recent_assignment = user.get_recent_test_pair_assignment_for problem
201 201 if recent_assignment == nil
202 202 flash[:notice] = 'You have not requested for any input data for this problem. Please download an input first.'
203 203 redirect_to :action => 'list' and return
204 204 end
205 205
206 + if recent_assignment.expired?
207 + flash[:notice] = 'The current input is expired. Please download a new input data.'
208 + redirect_to :action => 'list' and return
209 + end
210 +
206 211 if recent_assignment.submitted
207 212 flash[:notice] = 'You have already submitted an incorrect solution for this input. Please download a new input data.'
208 213 redirect_to :action => 'list' and return
209 214 end
210 215
211 216 if params[:file] == nil
212 217 flash[:notice] = 'You have not submitted any output.'
213 218 redirect_to :action => 'list' and return
214 219 end
215 220
216 221 submitted_solution = params[:file].read
217 222 test_pair = recent_assignment.test_pair
218 223 passed = test_pair.grade(submitted_solution)
219 224 points = passed ? 100 : 0
220 225 submission = Submission.new(:user => user,
221 226 :problem => problem,
222 227 :source => submitted_solution,
223 228 :source_filename => params['file'].original_filename,
224 229 :language_id => 0,
225 230 :submitted_at => Time.new.gmtime,
226 231 :graded_at => Time.new.gmtime,
227 232 :points => points)
228 233 submission.save
229 234 recent_assignment.submitted = true
230 235 recent_assignment.save
231 236
232 237 status = user.get_submission_status_for(problem)
233 238 if status == nil
234 239 status = SubmissionStatus.new :user => user, :problem => problem, :submission_count => 0
235 240 end
236 241
237 242 status.submission_count += 1
238 243 status.passed = passed
239 244 status.save
240 245
241 246 if passed
242 247 flash[:notice] = 'Correct solution.'
243 248 user.update_codejom_status
244 249 else
245 250 flash[:notice] = 'Incorrect solution.'
246 251 end
247 252 redirect_to :action => 'list'
248 253 end
249 254
250 255 protected
251 256
252 257 def prepare_announcements(recent=nil)
253 258 if Configuration.show_tasks_to?(@user)
@@ -1,5 +1,11
1 1 class TestPairAssignment < ActiveRecord::Base
2 +
2 3 belongs_to :user
3 4 belongs_to :test_pair
4 5 belongs_to :problem
6 +
7 + def expired?
8 + return created_at + TEST_ASSIGNMENT_EXPIRATION_DURATION < Time.new.gmtime
9 + end
10 +
5 11 end
@@ -51,97 +51,97
51 51
52 52 # these are for ytopc
53 53 # disable for now
54 54 #validates_presence_of :province
55 55
56 56 attr_accessor :password
57 57
58 58 before_save :encrypt_new_password
59 59 before_save :assign_default_site
60 60
61 61 def self.authenticate(login, password)
62 62 user = find_by_login(login)
63 63 return user if user && user.authenticated?(password)
64 64 end
65 65
66 66 def authenticated?(password)
67 67 if self.activated
68 68 hashed_password == User.encrypt(password,self.salt)
69 69 else
70 70 false
71 71 end
72 72 end
73 73
74 74 def admin?
75 75 self.roles.detect {|r| r.name == 'admin' }
76 76 end
77 77
78 78 # These are methods related to test pairs
79 79
80 80 def get_test_pair_assignments_for(problem)
81 81 test_pair_assignments.find_all { |a| a.problem_id == problem.id }
82 82 end
83 83
84 84 def get_recent_test_pair_assignment_for(problem)
85 85 assignments = get_test_pair_assignments_for problem
86 86 if assignments.length == 0
87 87 return nil
88 88 else
89 89 recent = assignments[0]
90 90 assignments.each do |a|
91 91 recent = a if a.request_number > recent.request_number
92 92 end
93 93 return recent
94 94 end
95 95 end
96 96
97 97 def can_request_new_test_pair_for?(problem)
98 98 recent = get_recent_test_pair_assignment_for problem
99 - return (recent == nil or recent.submitted)
99 + return (recent == nil or recent.submitted or recent.expired?)
100 100 end
101 101
102 102 def get_new_test_pair_assignment_for(problem)
103 103 previous_assignment_numbers =
104 104 get_test_pair_assignments_for(problem).collect {|a| a.test_pair_number }
105 105 test_pair = problem.random_test_pair(previous_assignment_numbers)
106 106 if test_pair
107 107 assignment = TestPairAssignment.new(:user => self,
108 108 :problem => problem,
109 109 :test_pair => test_pair,
110 110 :test_pair_number => test_pair.number,
111 111 :request_number =>
112 112 previous_assignment_numbers.length + 1,
113 113 :submitted => false)
114 114 return assignment
115 115 else
116 116 return nil
117 117 end
118 118 end
119 119
120 120 def get_submission_status_for(problem)
121 121 SubmissionStatus.find(:first,
122 122 :conditions => {
123 123 :user_id => id,
124 124 :problem_id => problem.id
125 125 })
126 126 end
127 127
128 128 def email_for_editing
129 129 if self.email==nil
130 130 "(unknown)"
131 131 elsif self.email==''
132 132 "(blank)"
133 133 else
134 134 self.email
135 135 end
136 136 end
137 137
138 138 def email_for_editing=(e)
139 139 self.email=e
140 140 end
141 141
142 142 def alias_for_editing
143 143 if self.alias==nil
144 144 "(unknown)"
145 145 elsif self.alias==''
146 146 "(blank)"
147 147 else
@@ -1,22 +1,22
1 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2 2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3 3
4 4 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5 5 <head>
6 6 <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
7 7 <title><%= Configuration['contest.name'] %></title>
8 8 <%= stylesheet_link_tag 'application' %>
9 9 <%= yield :head %>
10 10 </head>
11 11 <body>
12 12
13 13 <div class="userbar">
14 14 <%= user_header %>
15 15 </div>
16 16
17 - <%= content_tag(:p,flash[:notice],:style => "color:green") if flash[:notice]!=nil %>
17 + <% if flash[:notice]!=nil %><div class="notice-bar"><span class="notice"><%= flash[:notice] %></span></div><% end %>
18 18
19 19 <%= yield %>
20 20
21 21 </body>
22 22 </html>
@@ -1,18 +1,19
1 1 .problem-panel{:id => "problem-panel-#{problem.id}", :style => "display:none"}
2 2 .problem-form{:id => "problem-form-#{problem.id}"}
3 3 - form_tag({ :action => 'download_input', :id => problem.id }, :method => :post) do
4 4 %b Input:
5 5 %input{:type => "submit", :value => "Download input"}
6 + = "After downloading, you have #{TEST_ASSIGNMENT_EXPIRATION_DURATION/60} minutes to submit."
6 7 - form_tag({ :action => 'submit_solution', :id => problem.id }, :method => :post, :multipart => true) do
7 8 %b Submit output:
8 9 %input{:type => "file", :name => "file"}
9 10 %input{:type => "submit", :value => "Submit solution"}
10 11
11 12 .problem-description
12 13 - if problem.description!=nil
13 14 - if problem.description.markdowned
14 15 = markdown(problem.description.body)
15 16 - else
16 17 = problem.description.body
17 18 - else
18 19 (not available)
@@ -62,48 +62,49
62 62 # (all these examples are active by default):
63 63 # Inflector.inflections do |inflect|
64 64 # inflect.plural /^(ox)$/i, '\1en'
65 65 # inflect.singular /^(ox)en/i, '\1'
66 66 # inflect.irregular 'person', 'people'
67 67 # inflect.uncountable %w( fish sheep )
68 68 # end
69 69
70 70 # Add new mime types for use in respond_to blocks:
71 71 # Mime::Type.register "text/richtext", :rtf
72 72 # Mime::Type.register "application/x-mobile", :mobile
73 73
74 74 # Include your application configuration below
75 75
76 76 # If you want to manage graders through web interface, set the path to
77 77 # the grader directory below. This dir is where raw, ev, ev-exam,
78 78 # scripts reside. All grader scripts will be in
79 79 # #{GRADER_ROOT_DIR}/scripts.
80 80 GRADER_ROOT_DIR = ''
81 81
82 82 # These are where inputs and outputs of test requests are stored
83 83 TEST_REQUEST_INPUT_FILE_DIR = RAILS_ROOT + '/data/test_request/input'
84 84 TEST_REQUEST_OUTPUT_FILE_DIR = RAILS_ROOT + '/data/test_request/output'
85 85
86 86 # To use ANALYSIS MODE, provide the testcases/testruns breakdown,
87 87 # and the directory of the grading result (usually in judge's dir).
88 88 TASK_GRADING_INFO_FILENAME = RAILS_ROOT + '/config/tasks.yml'
89 89
90 90 # TODO: change this to where results are kept.
91 91 GRADING_RESULT_DIR = 'RESULT-DIR'
92 92
93 93 # Change this to allow importing testdata into database as test-pairs.
94 94 # This is mainly for Code Jom contest.
95 95 ALLOW_TEST_PAIR_IMPORT = false
96 96
97 97 # Uncomment so that the system validates user e-mails
98 98 # VALIDATE_USER_EMAILS = true
99 99
100 100 # Uncomment so that Apache X-Sendfile is used when delivering files
101 101 # (e.g., in /tasks/view).
102 102 # USE_APACHE_XSENDFILE = true
103 103
104 104 # Uncomment so that configuration is read only once when the server is loaded
105 105 # Configuration.enable_caching
106 106
107 107 # OPTIONS FOR CODE JOM
108 108 # --------------------
109 109 CODEJOM_MAX_ALIVE_LEVEL = 10
110 + TEST_ASSIGNMENT_EXPIRATION_DURATION = 5.minute
@@ -219,48 +219,61
219 219 color: #333333;
220 220 background: #dddddd;
221 221 font-weight: bold; }
222 222
223 223 .contest-title {
224 224 color: white;
225 225 text-align: center;
226 226 line-height: 2em; }
227 227
228 228 .registration-desc {
229 229 border: 1px dotted gray;
230 230 background: #f5f5f5;
231 231 padding: 5px;
232 232 margin: 10px 0;
233 233 font-size: 12px;
234 234 line-height: 1.5em; }
235 235
236 236 .test-desc {
237 237 border: 1px dotted gray;
238 238 background: #f5f5f5;
239 239 padding: 5px;
240 240 margin: 10px 0;
241 241 font-size: 12px;
242 242 line-height: 1.5em; }
243 243
244 244 .problem-list {
245 245 width: 200px;
246 246 float: left; }
247 247
248 248 .problem-bar {
249 249 margin-top: 5px;
250 250 padding: 5px;
251 251 background: #e0e0e0; }
252 252 .problem-bar span.problem-title {
253 253 font-weight: bold;
254 254 font-size: 110%; }
255 255
256 256 .problem-content {
257 257 float: left;
258 258 margin-left: 10px;
259 259 width: 700px; }
260 260
261 261 .problem-panel {
262 262 border: 1px black solid;
263 263 padding: 5px; }
264 264 .problem-panel .problem-form {
265 265 border: 1px dotted #99aaee;
266 266 background: #eeeeff; }
267 +
268 + .notice-bar {
269 + margin-top: 3px;
270 + margin-bottom: 3px;
271 + text-align: center; }
272 + .notice-bar span.notice {
273 + color: white;
274 + font-weight: bold;
275 + background: #000070;
276 + padding: 3px 20px 3px 20px;
277 + -moz-border-radius: 2px;
278 + -webkit-border-radius: 5px;
279 + border-radius: 5px; }
@@ -265,48 +265,62
265 265 font-weight: bold
266 266
267 267 .contest-title
268 268 color: white
269 269 text-align: center
270 270 line-height: 2em
271 271
272 272 .registration-desc
273 273 border: 1px dotted gray
274 274 background: #f5f5f5
275 275 padding: 5px
276 276 margin: 10px 0
277 277 font-size: 12px
278 278 line-height: 1.5em
279 279
280 280 .test-desc
281 281 border: 1px dotted gray
282 282 background: #f5f5f5
283 283 padding: 5px
284 284 margin: 10px 0
285 285 font-size: 12px
286 286 line-height: 1.5em
287 287
288 288 .problem-list
289 289 width: 200px
290 290 float: left
291 291
292 292 .problem-bar
293 293 margin-top: 5px
294 294 padding: 5px
295 295 background: #e0e0e0
296 296
297 297 span.problem-title
298 298 font-weight: bold
299 299 font-size: 110%
300 300
301 301 .problem-content
302 302 float: left
303 303 margin-left: 10px
304 304 width: 700px
305 305
306 306 .problem-panel
307 307 border: 1px black solid
308 308 padding: 5px
309 309
310 310 .problem-form
311 311 border: 1px dotted #99aaee
312 312 background: #eeeeff
313 +
314 + .notice-bar
315 + margin-top: 3px
316 + margin-bottom: 3px
317 + text-align: center
318 +
319 + span.notice
320 + color: white
321 + font-weight: bold
322 + background: #000070
323 + padding: 3px 20px 3px 20px
324 + -moz-border-radius: 2px
325 + -webkit-border-radius: 5px
326 + border-radius: 5px
You need to be logged in to leave comments. Login now