Description:
added problem list auto update
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r257:76846842a151 - - 3 files changed: 14 inserted, 2 deleted

@@ -87,384 +87,393
87 87 submission = Submission.find(params[:id])
88 88 if submission.user_id == session[:user_id]
89 89 send_data(submission.source,
90 90 {:filename => submission.download_filename,
91 91 :type => 'text/plain'})
92 92 else
93 93 flash[:notice] = 'Error viewing source'
94 94 redirect_to :action => 'list'
95 95 end
96 96 end
97 97
98 98 def compiler_msg
99 99 @submission = Submission.find(params[:id])
100 100 if @submission.user_id == session[:user_id]
101 101 render :action => 'compiler_msg', :layout => 'empty'
102 102 else
103 103 flash[:notice] = 'Error viewing source'
104 104 redirect_to :action => 'list'
105 105 end
106 106 end
107 107
108 108 def submission
109 109 # protect the action for Code Jom
110 110 redirect_to :action => 'list'
111 111
112 112 @user = User.find(session[:user_id])
113 113 @problems = Problem.find_available_problems
114 114 if params[:id]==nil
115 115 @problem = nil
116 116 @submissions = nil
117 117 else
118 118 @problem = Problem.find_by_name(params[:id])
119 119 if not @problem.available
120 120 redirect_to :action => 'list'
121 121 flash[:notice] = 'Error: submissions for that problem are not viewable.'
122 122 return
123 123 end
124 124 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
125 125 end
126 126 end
127 127
128 128 def result
129 129 if !Configuration.show_grading_result
130 130 redirect_to :action => 'list' and return
131 131 end
132 132 @user = User.find(session[:user_id])
133 133 @submission = Submission.find(params[:id])
134 134 if @submission.user!=@user
135 135 flash[:notice] = 'You are not allowed to view result of other users.'
136 136 redirect_to :action => 'list' and return
137 137 end
138 138 prepare_grading_result(@submission)
139 139 end
140 140
141 141 def load_output
142 142 if !Configuration.show_grading_result or params[:num]==nil
143 143 redirect_to :action => 'list' and return
144 144 end
145 145 @user = User.find(session[:user_id])
146 146 @submission = Submission.find(params[:id])
147 147 if @submission.user!=@user
148 148 flash[:notice] = 'You are not allowed to view result of other users.'
149 149 redirect_to :action => 'list' and return
150 150 end
151 151 case_num = params[:num].to_i
152 152 out_filename = output_filename(@user.login,
153 153 @submission.problem.name,
154 154 @submission.id,
155 155 case_num)
156 156 if !FileTest.exists?(out_filename)
157 157 flash[:notice] = 'Output not found.'
158 158 redirect_to :action => 'list' and return
159 159 end
160 160
161 161 response.headers['Content-Type'] = "application/force-download"
162 162 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
163 163 response.headers["X-Sendfile"] = out_filename
164 164 response.headers['Content-length'] = File.size(out_filename)
165 165 render :nothing => true
166 166 end
167 167
168 168 def error
169 169 @user = User.find(session[:user_id])
170 170 end
171 171
172 172 # announcement refreshing and hiding methods
173 173
174 174 def announcements
175 175 if params.has_key? 'recent'
176 176 prepare_announcements(params[:recent])
177 177 else
178 178 prepare_announcements
179 179 end
180 180 render(:partial => 'announcement',
181 181 :collection => @announcements,
182 182 :locals => {:announcement_effect => true})
183 183 end
184 184
185 185 #
186 186 # actions for Code Jom
187 187 #
188 188 def download_input
189 189 user = User.find(session[:user_id])
190 190
191 191 if Configuration.time_limit_mode? and user.contest_finished?
192 192 redirect_to :action => 'list' and return
193 193 end
194 194
195 195 problem = Problem.find(params[:id])
196 196 if user.can_request_new_test_pair_for? problem
197 197 assignment = user.get_new_test_pair_assignment_for problem
198 198 assignment.save
199 199
200 200 send_data(assignment.test_pair.input,
201 201 { :filename => "#{problem.name}-#{assignment.request_number}.in",
202 202 :type => 'text/plain' })
203 203 else
204 204 recent_assignment = user.get_recent_test_pair_assignment_for problem
205 205 send_data(recent_assignment.test_pair.input,
206 206 { :filename => "#{problem.name}-#{recent_assignment.request_number}.in",
207 207 :type => 'text/plain' })
208 208 end
209 209 end
210 210
211 211 def submit_solution
212 212 problem = Problem.find(params[:id])
213 213 user = User.find(session[:user_id])
214 214 recent_assignment = user.get_recent_test_pair_assignment_for problem
215 215
216 216 if Configuration.time_limit_mode? and user.contest_finished?
217 217 redirect_to :action => 'list' and return
218 218 end
219 219
220 220 if recent_assignment == nil
221 221 flash[:notice] = 'You have not requested for any input data for this problem. Please download an input first.'
222 222 session[:current_problem_id] = problem.id
223 223 redirect_to :action => 'list' and return
224 224 end
225 225
226 226 if recent_assignment.expired?
227 227 flash[:notice] = 'The current input is expired. Please download a new input data.'
228 228 session[:current_problem_id] = problem.id
229 229 redirect_to :action => 'list' and return
230 230 end
231 231
232 232 if recent_assignment.submitted
233 233 flash[:notice] = 'You have already submitted an incorrect solution for this input. Please download a new input data.'
234 234 session[:current_problem_id] = problem.id
235 235 redirect_to :action => 'list' and return
236 236 end
237 237
238 238 if params[:file] == nil
239 239 flash[:notice] = 'You have not submitted any output.'
240 240 session[:current_problem_id] = problem.id
241 241 redirect_to :action => 'list' and return
242 242 end
243 243
244 244 submitted_solution = params[:file].read
245 245 test_pair = recent_assignment.test_pair
246 246 passed = test_pair.grade(submitted_solution)
247 247 points = passed ? 100 : 0
248 248 submission = Submission.new(:user => user,
249 249 :problem => problem,
250 250 :source => submitted_solution,
251 251 :source_filename => params['file'].original_filename,
252 252 :language_id => 0,
253 253 :submitted_at => Time.new.gmtime,
254 254 :graded_at => Time.new.gmtime,
255 255 :points => points)
256 256 submission.save
257 257 recent_assignment.submitted = true
258 258 recent_assignment.save
259 259
260 260 status = user.get_submission_status_for(problem)
261 261 if status == nil
262 262 status = SubmissionStatus.new :user => user, :problem => problem, :submission_count => 0
263 263 end
264 264
265 265 status.submission_count += 1
266 266 status.passed = passed
267 267 status.save
268 268
269 269 if passed
270 270 flash[:notice] = 'Correct solution.'
271 271 user.update_codejom_status
272 272 else
273 273 session[:current_problem_id] = problem.id
274 274 flash[:notice] = 'Incorrect solution.'
275 275 end
276 276 redirect_to :action => 'list'
277 277 end
278 278
279 + def problems
280 + prepare_list_information
281 + render :partial => 'problem_title', :collection => @problems, :as => :problem
282 + end
283 +
284 + def splash
285 + render :text => '<div class="notice">Most recent task:</span>'
286 + end
287 +
279 288 protected
280 289
281 290 def prepare_announcements(recent=nil)
282 291 if Configuration.show_tasks_to?(@user)
283 292 @announcements = Announcement.find_published(true)
284 293 else
285 294 @announcements = Announcement.find_published
286 295 end
287 296 if recent!=nil
288 297 recent_id = recent.to_i
289 298 @announcements = @announcements.find_all { |a| a.id > recent_id }
290 299 end
291 300 end
292 301
293 302 def prepare_timeout_information(problems)
294 303 @submission_timeouts = {}
295 304 problems.each do |problem|
296 305 assignment = @user.get_recent_test_pair_assignment_for(problem)
297 306 if assignment == nil
298 307 timeout = nil
299 308 else
300 309 if (assignment.expired?) or (assignment.submitted)
301 310 timeout = 0
302 311 else
303 312 timeout = assignment.created_at + TEST_ASSIGNMENT_EXPIRATION_DURATION - Time.new.gmtime
304 313 end
305 314 end
306 315 @submission_timeouts[problem.id] = timeout
307 316 end
308 317 @submission_timeouts.each_pair {|k,v| puts "#{k} => #{v}"}
309 318 end
310 319
311 320 def prepare_list_information
312 321 @user = User.find(session[:user_id])
313 322
314 323 all_problems = Problem.find_available_problems
315 324
316 325 passed = {}
317 326 sub_count = {}
318 327 @user.submission_statuses.each do |status|
319 328 if status.passed
320 329 passed[status.problem_id] = true
321 330 end
322 331 sub_count[status.problem_id] = status.submission_count
323 332 end
324 333
325 334 if session.has_key? :current_problem_id
326 335 @current_problem_id = session[:current_problem_id]
327 336 session.delete(:current_problem_id)
328 337 else
329 338 @current_problem_id = nil
330 339 end
331 340
332 341 @problems = all_problems.reject { |problem| passed.has_key? problem.id }
333 342
334 343 prepare_timeout_information(@problems)
335 344
336 345 @prob_submissions = Array.new
337 346 @problems.each do |p|
338 347 if sub_count.has_key? p.id
339 348 @prob_submissions << { :count => sub_count[p.id] }
340 349 else
341 350 @prob_submissions << { :count => 0 }
342 351 end
343 352 end
344 353 prepare_announcements
345 354 end
346 355
347 356 def check_viewability
348 357 @user = User.find(session[:user_id])
349 358 if (!Configuration.show_tasks_to?(@user)) and
350 359 ((action_name=='submission') or (action_name=='submit'))
351 360 redirect_to :action => 'list' and return
352 361 end
353 362 end
354 363
355 364 def prepare_grading_result(submission)
356 365 if Configuration.task_grading_info.has_key? submission.problem.name
357 366 grading_info = Configuration.task_grading_info[submission.problem.name]
358 367 else
359 368 # guess task info from problem.full_score
360 369 cases = submission.problem.full_score / 10
361 370 grading_info = {
362 371 'testruns' => cases,
363 372 'testcases' => cases
364 373 }
365 374 end
366 375 @test_runs = []
367 376 if grading_info['testruns'].is_a? Integer
368 377 trun_count = grading_info['testruns']
369 378 trun_count.times do |i|
370 379 @test_runs << [ read_grading_result(@user.login,
371 380 submission.problem.name,
372 381 submission.id,
373 382 i+1) ]
374 383 end
375 384 else
376 385 grading_info['testruns'].keys.sort.each do |num|
377 386 run = []
378 387 testrun = grading_info['testruns'][num]
379 388 testrun.each do |c|
380 389 run << read_grading_result(@user.login,
381 390 submission.problem.name,
382 391 submission.id,
383 392 c)
384 393 end
385 394 @test_runs << run
386 395 end
387 396 end
388 397 end
389 398
390 399 def grading_result_dir(user_name, problem_name, submission_id, case_num)
391 400 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
392 401 end
393 402
394 403 def output_filename(user_name, problem_name, submission_id, case_num)
395 404 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
396 405 return "#{dir}/output.txt"
397 406 end
398 407
399 408 def read_grading_result(user_name, problem_name, submission_id, case_num)
400 409 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
401 410 result_file_name = "#{dir}/result"
402 411 if !FileTest.exists?(result_file_name)
403 412 return {:num => case_num, :msg => 'program did not run'}
404 413 else
405 414 results = File.open(result_file_name).readlines
406 415 run_stat = extract_running_stat(results)
407 416 output_filename = "#{dir}/output.txt"
408 417 if FileTest.exists?(output_filename)
409 418 output_file = true
410 419 output_size = File.size(output_filename)
411 420 else
412 421 output_file = false
413 422 output_size = 0
414 423 end
415 424
416 425 return {
417 426 :num => case_num,
418 427 :msg => results[0],
419 428 :run_stat => run_stat,
420 429 :output => output_file,
421 430 :output_size => output_size
422 431 }
423 432 end
424 433 end
425 434
426 435 # copied from grader/script/lib/test_request_helper.rb
427 436 def extract_running_stat(results)
428 437 running_stat_line = results[-1]
429 438
430 439 # extract exit status line
431 440 run_stat = ""
432 441 if !(/[Cc]orrect/.match(results[0]))
433 442 run_stat = results[0].chomp
434 443 else
435 444 run_stat = 'Program exited normally'
436 445 end
437 446
438 447 logger.info "Stat line: #{running_stat_line}"
439 448
440 449 # extract running time
441 450 if res = /r(.*)u(.*)s/.match(running_stat_line)
442 451 seconds = (res[1].to_f + res[2].to_f)
443 452 time_stat = "Time used: #{seconds} sec."
444 453 else
445 454 seconds = nil
446 455 time_stat = "Time used: n/a sec."
447 456 end
448 457
449 458 # extract memory usage
450 459 if res = /s(.*)m/.match(running_stat_line)
451 460 memory_used = res[1].to_i
452 461 else
453 462 memory_used = -1
454 463 end
455 464
456 465 return {
457 466 :msg => "#{run_stat}\n#{time_stat}",
458 467 :running_time => seconds,
459 468 :exit_status => run_stat,
460 469 :memory_usage => memory_used
461 470 }
462 471 end
463 472
464 473 def update_user_start_time
465 474 user = User.find(session[:user_id])
466 475 UserContestStat.update_user_start_time(user)
467 476 end
468 477
469 478 def reject_announcement_refresh_when_logged_out
470 479 if not session[:user_id]
@@ -1,39 +1,42
1 1 - content_for :head do
2 2 = javascript_include_tag :defaults
3 3 = javascript_include_tag 'announcement_refresh.js'
4 4 = javascript_include_tag 'codejom_timeout.js'
5 5
6 6 = user_title_bar(@user)
7 7
8 8 .announcementbox{:style => (@announcements.length==0 ? "display:none" : "")}
9 9 %span{:class => 'title'}
10 10 Announcements
11 11 #announcementbox-body
12 12 = render :partial => 'announcement', :collection => @announcements
13 13
14 14 %hr/
15 15
16 16 - if (Configuration.contest_mode?) and (@user.site!=nil) and (@user.site.started!=true)
17 17 %p=t 'main.start_soon'
18 18
19 19 - if Configuration.show_tasks_to?(@user)
20 - .problem-list
20 + .problem-list{:id => 'problem-list'}
21 21 = render :partial => 'problem_title', :collection => @problems, :as => :problem
22 22 .problem-content
23 23 %span{:id => "problem-panel-filler", :style => (@current_problem_id!=nil) ? "display:none" : ""}
24 24 %h2
25 25 Welcome to Code Jom
26 26 %br/
27 27 Choose problems from the list on the right.
28 28 = render :partial => 'problem', :collection => @problems
29 29
30 30 %br{:clear=>'both'}/
31 31 %hr/
32 32
33 33 %script{:type => 'text/javascript'}
34 34 = "Announcement.refreshUrl = '#{url_for :controller => 'main', :action => 'announcements'}';"
35 35 Announcement.registerRefreshEventTimer();
36 36 = render :partial => 'submission_timeouts'
37 37 CodejomTimeout.updateProblemMessages();
38 38 CodejomTimeout.registerRefreshEvent();
39 39
40 + = periodically_call_remote(:url => { :action => 'problems' }, :update => 'problem-list')
41 +
42 +
@@ -146,193 +146,193
146 146
147 147 .task-menu
148 148 text-align: center
149 149 font-size: 13px
150 150 line-height: 1.75em
151 151 font-weight: bold
152 152 border-top: 1px dashed gray
153 153 border-bottom: 1px dashed gray
154 154 margin-top: 2px
155 155 margin-bottom: 4px
156 156
157 157
158 158 table.taskdesc
159 159 border: 2px solid #dddddd
160 160 border-collapse: collapse
161 161 margin: 10px auto
162 162 width: 90%
163 163 font-size: 13px
164 164
165 165 p
166 166 font-size: 13px
167 167
168 168 tr.name
169 169 border: 2px solid #dddddd
170 170 background: #dddddd
171 171 color: #333333
172 172 font-weight: bold
173 173 font-size: 14px
174 174 line-height: 1.5em
175 175 text-align: center
176 176
177 177 td
178 178 &.desc-odd
179 179 padding: 5px
180 180 padding-left: 20px
181 181 background: #fefeee
182 182
183 183 &.desc-even
184 184 padding: 5px
185 185 padding-left: 20px
186 186 background: #feeefe
187 187
188 188
189 189 .announcementbox
190 190 margin: 10px 0px
191 191 background: #bbddee
192 192 padding: 1px
193 193
194 194 span.title
195 195 font-weight: bold
196 196 color: #224455
197 197 padding-left: 10px
198 198 line-height: 1.6em
199 199
200 200 .announcement
201 201 margin: 2px
202 202 background: white
203 203 padding: 1px
204 204 padding-left: 10px
205 205 padding-right: 10px
206 206 padding-top: 5px
207 207 padding-bottom: 5px
208 208
209 209 p
210 210 font-size: 12px
211 211 margin: 2px
212 212
213 213
214 214 .pub-info
215 215 text-align: right
216 216 font-style: italic
217 217 font-size: 9px
218 218
219 219 p
220 220 text-align: right
221 221 font-style: italic
222 222 font-size: 9px
223 223
224 224
225 225 .announcement
226 226 .toggles
227 227 font-weight: normal
228 228 float: right
229 229 font-size: 80%
230 230
231 231 .announcement-title
232 232 font-weight: bold
233 233
234 234
235 235 .message
236 236 margin: 10px 0 0
237 237
238 238 .message
239 239 margin: 0 0 0 30px
240 240
241 241 .stat
242 242 font-size: 10px
243 243 line-height: 1.75em
244 244 padding: 0 5px
245 245 color: #444444
246 246 background: #bbbbbb
247 247 font-weight: bold
248 248
249 249 .body
250 250 border: 2px solid #dddddd
251 251 background: #fff8f8
252 252 padding-left: 5px
253 253
254 254 .reply-body
255 255 border: 2px solid #bbbbbb
256 256 background: #fffff8
257 257 padding-left: 5px
258 258
259 259 .stat
260 260 font-size: 10px
261 261 line-height: 1.75em
262 262 padding: 0 5px
263 263 color: #333333
264 264 background: #dddddd
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 313
314 314 .notice-bar
315 315 margin-top: 3px
316 316 margin-bottom: 3px
317 317 text-align: center
318 318
319 319 span.notice
320 320 color: white
321 321 font-weight: bold
322 322 background: #000070
323 323 padding: 3px 20px 3px 20px
324 324 -moz-border-radius: 2px
325 325 -webkit-border-radius: 5px
326 326 border-radius: 5px
327 327
328 328 table.codejom-problems
329 329 th
330 330 background: #000070
331 331 color: white
332 332 td
333 333 width: 200px
334 334 vertical-align: top
335 335 text-align: center
336 336
337 337 &.random-button
338 - background: lightgrey No newline at end of file
338 + background: lightgrey
You need to be logged in to leave comments. Login now