Description:
added timeout related javascripts
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r228:9e664dd71888 - - 5 files changed: 91 inserted, 2 deleted

@@ -0,0 +1,7
1 + CodejomTimeout.timeouts = [
2 + - @submission_timeouts.each_pair do |id, t|
3 + - if t!=nil
4 + = "{problem: #{id}, timeout: #{t}},"
5 + - else
6 + = "{problem: #{id}, timeout: null},"
7 + ];
@@ -0,0 +1,58
1 + var CodejomTimeout = {
2 +
3 + timeStarted: null,
4 +
5 + inputDataDuration: 5, // 5 minutes
6 +
7 + timeouts: [],
8 +
9 + updateProblemMessages: function() {
10 + CodejomTimeout.timeouts.each(function(data) {
11 + if(data.timeout==null) {
12 + $("problem-submission-form-" + data.problem).hide();
13 + } else if(data.timeout==0) {
14 + $("problem-timing-message-" + data.problem).innerHTML =
15 + "The recent input data is expired. Please download a new one. You'll have 5 minute to submit.";
16 + $("problem-submission-form-" + data.problem).hide();
17 + } else {
18 + $("problem-timing-message-" + data.problem).innerHTML =
19 + "You have about " + parseInt(data.timeout/60) + " minute(s) and " + parseInt(data.timeout % 60) + " second(s) to submit.";
20 + $("problem-submission-form-" + data.problem).show();
21 + }
22 + });
23 + },
24 +
25 + refreshProblemMessages: function() {
26 + var timeElapsed = ((new Date()).getTime() - CodejomTimeout.timeStarted)/1000;
27 + // update timeout info
28 + CodejomTimeout.timeouts.each(function(data) {
29 + if(data.timeout > timeElapsed) {
30 + data.timeout -= timeElapsed;
31 + } else if(data.timeout > 0) {
32 + data.timeout = 0;
33 + }
34 + });
35 +
36 + CodejomTimeout.updateProblemMessages();
37 + CodejomTimeout.registerRefreshEvent();
38 + },
39 +
40 + registerRefreshEvent: function() {
41 + CodejomTimeout.timeStarted = (new Date()).getTime(),
42 + setTimeout(function () {
43 + CodejomTimeout.refreshProblemMessages();
44 + }, 2700);
45 + },
46 +
47 + updateTimeoutAfterDownloadClick: function(problem) {
48 + CodejomTimeout.timeouts
49 + .filter(function(data) { return data.problem==problem; })
50 + .each(function(data) {
51 + if(data.timeout==0 || data.timeout==null) {
52 + // TODO: use value from rails app.
53 + data.timeout = CodejomTimeout.inputDataDuration * 60;
54 + }
55 + });
56 + CodejomTimeout.updateProblemMessages();
57 + },
58 + };
@@ -179,215 +179,235
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
202 202 if recent_assignment == nil
203 203 flash[:notice] = 'You have not requested for any input data for this problem. Please download an input first.'
204 204 session[:current_problem_id] = problem.id
205 205 redirect_to :action => 'list' and return
206 206 end
207 207
208 208 if recent_assignment.expired?
209 209 flash[:notice] = 'The current input is expired. Please download a new input data.'
210 210 session[:current_problem_id] = problem.id
211 211 redirect_to :action => 'list' and return
212 212 end
213 213
214 214 if recent_assignment.submitted
215 215 flash[:notice] = 'You have already submitted an incorrect solution for this input. Please download a new input data.'
216 216 session[:current_problem_id] = problem.id
217 217 redirect_to :action => 'list' and return
218 218 end
219 219
220 220 if params[:file] == nil
221 221 flash[:notice] = 'You have not submitted any output.'
222 222 session[:current_problem_id] = problem.id
223 223 redirect_to :action => 'list' and return
224 224 end
225 225
226 226 submitted_solution = params[:file].read
227 227 test_pair = recent_assignment.test_pair
228 228 passed = test_pair.grade(submitted_solution)
229 229 points = passed ? 100 : 0
230 230 submission = Submission.new(:user => user,
231 231 :problem => problem,
232 232 :source => submitted_solution,
233 233 :source_filename => params['file'].original_filename,
234 234 :language_id => 0,
235 235 :submitted_at => Time.new.gmtime,
236 236 :graded_at => Time.new.gmtime,
237 237 :points => points)
238 238 submission.save
239 239 recent_assignment.submitted = true
240 240 recent_assignment.save
241 241
242 242 status = user.get_submission_status_for(problem)
243 243 if status == nil
244 244 status = SubmissionStatus.new :user => user, :problem => problem, :submission_count => 0
245 245 end
246 246
247 247 status.submission_count += 1
248 248 status.passed = passed
249 249 status.save
250 250
251 251 if passed
252 252 flash[:notice] = 'Correct solution.'
253 253 user.update_codejom_status
254 254 else
255 255 session[:current_problem_id] = problem.id
256 256 flash[:notice] = 'Incorrect solution.'
257 257 end
258 258 redirect_to :action => 'list'
259 259 end
260 260
261 261 protected
262 262
263 263 def prepare_announcements(recent=nil)
264 264 if Configuration.show_tasks_to?(@user)
265 265 @announcements = Announcement.find_published(true)
266 266 else
267 267 @announcements = Announcement.find_published
268 268 end
269 269 if recent!=nil
270 270 recent_id = recent.to_i
271 271 @announcements = @announcements.find_all { |a| a.id > recent_id }
272 272 end
273 273 end
274 274
275 + def prepare_timeout_information(problems)
276 + @submission_timeouts = {}
277 + problems.each do |problem|
278 + assignment = @user.get_recent_test_pair_assignment_for(problem)
279 + if assignment == nil
280 + timeout = nil
281 + else
282 + if assignment.expired?
283 + timeout = 0
284 + else
285 + timeout = assignment.created_at + TEST_ASSIGNMENT_EXPIRATION_DURATION - Time.new.gmtime
286 + end
287 + end
288 + @submission_timeouts[problem.id] = timeout
289 + end
290 + @submission_timeouts.each_pair {|k,v| puts "#{k} => #{v}"}
291 + end
292 +
275 293 def prepare_list_information
276 294 @user = User.find(session[:user_id])
277 295
278 296 all_problems = Problem.find_available_problems
279 297
280 298 passed = {}
281 299 sub_count = {}
282 300 @user.submission_statuses.each do |status|
283 301 if status.passed
284 302 passed[status.problem_id] = true
285 303 end
286 304 sub_count[status.problem_id] = status.submission_count
287 305 end
288 306
289 307 if session.has_key? :current_problem_id
290 308 @current_problem_id = session[:current_problem_id]
291 309 session.delete(:current_problem_id)
292 310 else
293 311 @current_problem_id = nil
294 312 end
295 313
296 314 @problems = all_problems.reject { |problem| passed.has_key? problem.id }
297 315
316 + prepare_timeout_information(@problems)
317 +
298 318 @prob_submissions = Array.new
299 319 @problems.each do |p|
300 320 if sub_count.has_key? p.id
301 321 @prob_submissions << { :count => sub_count[p.id] }
302 322 else
303 323 @prob_submissions << { :count => 0 }
304 324 end
305 325 end
306 326 prepare_announcements
307 327 end
308 328
309 329 def check_viewability
310 330 @user = User.find(session[:user_id])
311 331 if (!Configuration.show_tasks_to?(@user)) and
312 332 ((action_name=='submission') or (action_name=='submit'))
313 333 redirect_to :action => 'list' and return
314 334 end
315 335 end
316 336
317 337 def prepare_grading_result(submission)
318 338 if Configuration.task_grading_info.has_key? submission.problem.name
319 339 grading_info = Configuration.task_grading_info[submission.problem.name]
320 340 else
321 341 # guess task info from problem.full_score
322 342 cases = submission.problem.full_score / 10
323 343 grading_info = {
324 344 'testruns' => cases,
325 345 'testcases' => cases
326 346 }
327 347 end
328 348 @test_runs = []
329 349 if grading_info['testruns'].is_a? Integer
330 350 trun_count = grading_info['testruns']
331 351 trun_count.times do |i|
332 352 @test_runs << [ read_grading_result(@user.login,
333 353 submission.problem.name,
334 354 submission.id,
335 355 i+1) ]
336 356 end
337 357 else
338 358 grading_info['testruns'].keys.sort.each do |num|
339 359 run = []
340 360 testrun = grading_info['testruns'][num]
341 361 testrun.each do |c|
342 362 run << read_grading_result(@user.login,
343 363 submission.problem.name,
344 364 submission.id,
345 365 c)
346 366 end
347 367 @test_runs << run
348 368 end
349 369 end
350 370 end
351 371
352 372 def grading_result_dir(user_name, problem_name, submission_id, case_num)
353 373 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
354 374 end
355 375
356 376 def output_filename(user_name, problem_name, submission_id, case_num)
357 377 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
358 378 return "#{dir}/output.txt"
359 379 end
360 380
361 381 def read_grading_result(user_name, problem_name, submission_id, case_num)
362 382 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
363 383 result_file_name = "#{dir}/result"
364 384 if !FileTest.exists?(result_file_name)
365 385 return {:num => case_num, :msg => 'program did not run'}
366 386 else
367 387 results = File.open(result_file_name).readlines
368 388 run_stat = extract_running_stat(results)
369 389 output_filename = "#{dir}/output.txt"
370 390 if FileTest.exists?(output_filename)
371 391 output_file = true
372 392 output_size = File.size(output_filename)
373 393 else
374 394 output_file = false
375 395 output_size = 0
376 396 end
377 397
378 398 return {
379 399 :num => case_num,
380 400 :msg => results[0],
381 401 :run_stat => run_stat,
382 402 :output => output_file,
383 403 :output_size => output_size
384 404 }
385 405 end
386 406 end
387 407
388 408 # copied from grader/script/lib/test_request_helper.rb
389 409 def extract_running_stat(results)
390 410 running_stat_line = results[-1]
391 411
392 412 # extract exit status line
393 413 run_stat = ""
@@ -1,21 +1,21
1 1 .problem-panel{:id => "problem-panel-#{problem.id}", :style => "#{(problem.id != @current_problem_id) ? "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 - %input{:type => "submit", :value => "Download input"}
5 + %input{:type => "submit", :value => "Download input", :onclick => "CodejomTimeout.updateTimeoutAfterDownloadClick(#{problem.id}); return true;"}
6 6 %span{:id => "problem-timing-message-#{problem.id}"}
7 7 = "After downloading, you have #{TEST_ASSIGNMENT_EXPIRATION_DURATION/60} minutes to submit."
8 8 %div{:id => "problem-submission-form-#{problem.id}"}
9 9 - form_tag({ :action => 'submit_solution', :id => problem.id }, :method => :post, :multipart => true) do
10 10 %b Submit output:
11 11 %input{:type => "file", :name => "file"}
12 12 %input{:type => "submit", :value => "Submit solution"}
13 13
14 14 .problem-description
15 15 - if problem.description!=nil
16 16 - if problem.description.markdowned
17 17 = markdown(problem.description.body)
18 18 - else
19 19 = problem.description.body
20 20 - else
21 21 (not available)
@@ -1,33 +1,37
1 1 - content_for :head do
2 2 = javascript_include_tag :defaults
3 3 = javascript_include_tag 'announcement_refresh.js'
4 + = javascript_include_tag 'codejom_timeout.js'
4 5
5 6 = user_title_bar(@user)
6 7
7 8 .announcementbox{:style => (@announcements.length==0 ? "display:none" : "")}
8 9 %span{:class => 'title'}
9 10 Announcements
10 11 #announcementbox-body
11 12 = render :partial => 'announcement', :collection => @announcements
12 13
13 14 %hr/
14 15
15 16 - if (Configuration.contest_mode?) and (@user.site!=nil) and (@user.site.started!=true)
16 17 %p=t 'main.start_soon'
17 18
18 19 - if Configuration.show_tasks_to?(@user)
19 20 .problem-list
20 21 = render :partial => 'problem_title', :collection => @problems, :as => :problem
21 22 .problem-content
22 23 %span{:id => "problem-panel-filler", :style => (@current_problem_id!=nil) ? "display:none" : ""}
23 24 %b Welcome to Code Jom
24 25 %br/
25 26 Choose problems from the list on the right.
26 27 = render :partial => 'problem', :collection => @problems
27 28
28 29 %br{:clear=>'both'}/
29 30 %hr/
30 31
31 - :javascript
32 + %script{:type => "text/javascript"}
32 33 Announcement.registerRefreshEventTimer();
34 + = render :partial => 'submission_timeouts'
35 + CodejomTimeout.updateProblemMessages();
36 + CodejomTimeout.registerRefreshEvent();
33 37
You need to be logged in to leave comments. Login now