Description:
saves submitted output, checks time outs; updated submission front-end flows
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r383:31aa87b1b1e9 - - 8 files changed: 116 inserted, 20 deleted

@@ -0,0 +1,5
1 + class AddOutputToSubmissions < ActiveRecord::Migration
2 + def change
3 + add_column :submissions, :output, :text
4 + end
5 + end
@@ -1,7 +1,9
1 1 var TOIContest = {
2 2 NO_TIMEOUT: -1,
3 + SUBMISSION_TIMEOUT: 300,
3 4
4 5 timeOuts: {},
6 + timeStarted: 0,
5 7
6 8 problemSelectClick: function() {
7 9 $$(".submission-submit-divs").each(function(item) {
@@ -14,8 +16,18
14 16 $("submission_submit_div_" + problem_id + "_id").show();
15 17 },
16 18
17 - confirmDownload: function() {
18 - return confirm("แน่ใจ?");
19 + confirmDownload: function(pid) {
20 + result = confirm("คุณแน่ใจที่จะส่งข้อนี้หรือไม่?\nเมื่อคุณดาวน์โหลดข้อมูลชุดทดสอบแล้ว คุณจะต้องส่งข้อมูลส่งออกและโปรแกรมภายในเวลา 5 นาที");
21 + if ( result ) {
22 + if ( TOIContest.timeOuts[ pid ] == TOIContest.NO_TIMEOUT ) {
23 + TOIContest.refreshTimeOuts();
24 +
25 + TOIContest.timeOuts[ pid ] = TOIContest.SUBMISSION_TIMEOUT;
26 +
27 + TOIContest.refreshTimeOutMessages();
28 + }
29 + }
30 + return result;
19 31 },
20 32
21 33 refreshTimeOutMessages: function() {
@@ -26,12 +38,40
26 38 var minLeft = parseInt(timeOut / 60);
27 39 var secLeft = parseInt(timeOut % 60);
28 40 $('submission_time_left_' + pid + '_id').innerHTML = '| <b>เหลือเวลาอีก ' + minLeft + ':' + secLeft + ' นาที</b>';
41 + $('submission_form_'+ pid + '_id').show();
29 42 } else {
30 43 $('submission_time_left_' + pid + '_id').innerHTML = '| <b>หมดเวลาส่ง</a>';
31 44 $('submission_form_'+ pid + '_id').hide();
32 45 }
46 + } else {
47 + $('submission_form_'+ pid + '_id').hide();
33 48 }
34 49 }
35 - }
50 + },
51 +
52 + refreshTimeOuts: function() {
53 + if ( TOIContest.timeStarted == 0 ) {
54 + TOIContest.timeStarted = (new Date()).getTime();
55 + }
56 +
57 + var timeElapsed = ((new Date()).getTime() - TOIContest.timeStarted)/1000;
58 + for ( var pid in TOIContest.timeOuts ) {
59 + var timeOut = TOIContest.timeOuts[ pid ];
60 + if ( timeOut > timeElapsed ) {
61 + TOIContest.timeOuts[ pid ] -= timeElapsed;
62 + } else if ( timeOut > 0 ) {
63 + TOIContest.timeOuts[ pid ] = 0;
64 + }
65 + }
66 + },
67 +
68 + registerRefreshEvent: function() {
69 + TOIContest.timeStarted = (new Date()).getTime();
70 + setTimeout(function () {
71 + TOIContest.refreshTimeOuts();
72 + TOIContest.refreshTimeOutMessages();
73 + TOIContest.registerRefreshEvent();
74 + }, 1000);
75 + },
36 76 };
37 77
@@ -1,3 +1,4
1 + # coding: utf-8
1 2 class MainController < ApplicationController
2 3
3 4 before_filter :authenticate, :except => [:index, :login]
@@ -48,6 +49,10
48 49 end
49 50
50 51 def list
52 + if session[:current_problem_id]
53 + @current_problem = Problem.find(session[:current_problem_id])
54 + session[:current_problem_id] = nil
55 + end
51 56 prepare_list_information
52 57 end
53 58
@@ -59,13 +64,35
59 64 user = User.find(session[:user_id])
60 65
61 66 @submission = Submission.new
62 - @submission.problem_id = params[:submission][:problem_id]
67 + @current_problem = Problem.find(params[:submission][:problem_id])
68 +
69 + if !@current_problem
70 + flash[:notice] = 'Error: คุณยังไม่ได้ระบุข้อที่ต้องการส่ง'
71 + redirect_to :action => 'list'
72 + end
73 +
74 + assignment = user.get_test_pair_assignment_for(@current_problem)
75 + if !assignment
76 + flash[:notice] = 'Error: คุณยังไม่ได้ดาวน์โหลดข้อมูลทดสอบ'
77 + prepare_list_information
78 + render :action => 'list' and return
79 + end
80 + if assignment.expired?
81 + flash[:notice] = 'Error: หมดเวลาส่งสำหรับข้อนี้'
82 + prepare_list_information
83 + render :action => 'list' and return
84 + end
85 +
86 + @submission.problem = @current_problem
63 87 @submission.user = user
64 88 @submission.language_id = 0
65 89 if (params['file']) and (params['file']!='')
66 90 @submission.source = params['file'].read
67 91 @submission.source_filename = params['file'].original_filename
68 92 end
93 + if (params['output_file']) and (params['output_file']!='')
94 + @submission.output = params['output_file'].read
95 + end
69 96 @submission.submitted_at = Time.new.gmtime
70 97
71 98 if GraderConfiguration.time_limit_mode? and user.contest_finished?
@@ -80,11 +107,17
80 107 elsif Task.create(:submission_id => @submission.id,
81 108 :status => Task::STATUS_INQUEUE) == false
82 109 flash[:notice] = 'Error adding your submission to task queue'
110 + else
111 + flash[:notice] = 'จัดเก็บคำตอบและโปรแกรมที่คุณส่งเรียบร้อย'
83 112 end
84 113 else
85 114 prepare_list_information
86 115 render :action => 'list' and return
87 116 end
117 +
118 + if @current_problem
119 + session[:current_problem_id] = @current_problem.id
120 + end
88 121 redirect_to :action => 'list'
89 122 end
90 123
@@ -225,15 +258,11
225 258 test_pair = TestPair.get_for(problem, true)
226 259
227 260 user = User.find(session[:user_id])
228 - assignent = user.get_test_pair_assignment_for(problem)
261 + assignment = user.get_test_pair_assignment_for(problem)
229 262
230 - if !assignent
231 - assignent = TestPairAssignment.new
232 - assignent.user = user
233 - assignent.problem = problem
234 - assignent.test_pair = test_pair
235 - assignent.submitted = false
236 - assignent.save
263 + if !assignment
264 + assignment = TestPairAssignment.create_for(user, problem, test_pair)
265 + assignment.save
237 266 end
238 267
239 268 send_data(test_pair.input,
@@ -252,17 +281,18
252 281 redirect_to :action => 'list' and return
253 282 end
254 283
284 + @current_problem = problem
255 285 test_pair = TestPair.get_for(problem, false)
256 286 if (params['output_file']) and (params['output_file']!='')
257 287 output = params['output_file'].read
258 288
259 - @current_problem = problem
260 289 @grading_result = grade(output, test_pair.solution)
261 290 prepare_list_information
262 291 render :action => 'list' and return
263 292 else
264 293 flash[:notice] = 'Error: output file errors'
265 - redirect_to :action => 'list'
294 + prepare_list_information
295 + render :action => 'list' and return
266 296 end
267 297 end
268 298
@@ -10,6 +10,11
10 10 validates_presence_of :source
11 11 validates_length_of :source, :maximum => 100_000, :allow_blank => true, :message => 'too long'
12 12 validates_length_of :source, :minimum => 1, :allow_blank => true, :message => 'too short'
13 +
14 + validates_presence_of :output
15 + validates_length_of :output, :maximum => 100_000, :allow_blank => true, :message => 'too long'
16 + validates_length_of :output, :minimum => 1, :allow_blank => true, :message => 'too short'
17 +
13 18 validate :must_have_valid_problem
14 19 validate :must_specify_language
15 20
@@ -6,4 +6,14
6 6 def expired?
7 7 return created_at + TEST_ASSIGNMENT_EXPIRATION_DURATION < Time.new.gmtime
8 8 end
9 +
10 + def self.create_for(user, problem, test_pair)
11 + assignment = TestPairAssignment.new
12 + assignment.user = user
13 + assignment.problem = problem
14 + assignment.test_pair = test_pair
15 + assignment.submitted = false
16 + assignment.save
17 + return assignment
18 + end
9 19 end
@@ -1,13 +1,14
1 + <% selected_problem_id = @current_problem ? @current_problem.id : -1 %>
1 2 <div class="submitbox">
2 3 <b>Problem:</b> <%= select 'submission', 'problem_id',
3 4 [['กรุณาเลือกข้อที่ต้องการส่งหรือทดสอบ','-1']] +
4 5 @problems.collect {|p| [p.full_name, p.id]},
5 - { :selected => '-1' },
6 + { :selected => selected_problem_id },
6 7 { :onchange => 'TOIContest.problemSelectClick()' } %>
7 8 </div>
8 9
9 10 <% @problems.each do |problem| %>
10 - <div class="submission-submit-divs" id="submission_submit_div_<%= problem.id %>_id" style="displanny: none;">
11 + <div class="submission-submit-divs" id="submission_submit_div_<%= problem.id %>_id" style="display: none;">
11 12 <div style="border: 1px solid #c0c0c0; padding: 5px; margin: 5px 0 5px 0;">
12 13 <b><%= problem.full_name %>: ข้อมูลสำหรับตรวจสอบ</b> (สามารถดาวน์โหลดและส่งกี่ครั้งก็ได้,ไม่มีคะแนน):
13 14 <%= link_to 'ดาวน์โหลด input', :action => 'verifying_testcase', :id => problem.id %>
@@ -24,11 +25,12
24 25 </div>
25 26 <div style="border: 1px solid #c0c0c0; padding: 5px; margin: 5px 0 5px 0;">
26 27 <b><%= problem.full_name %>: ข้อมูลทดสอบจริง</b> (ส่งกี่ครั้งก็ได้ภายในเวลา 5 นาทีหลังดาวน์โหลด):
27 - <%= link_to 'ดาวน์โหลด input และเริ่มจับเวลา', { :action => 'testcase', :id => problem.id}, { :onclick => 'return TOIContest.confirmDownload()' } %>
28 + <%= link_to 'ดาวน์โหลด input และเริ่มจับเวลา', { :action => 'testcase', :id => problem.id}, { :onclick => "return TOIContest.confirmDownload(#{problem.id})" } %>
28 29 <span id="submission_time_left_<%= problem.id %>_id"></span>
29 - <%= form_tag({:controller => 'main', :action => 'submit', :id => problem.id}, {:method => 'post', :multipart => true, :id => "submission_form_#{problem.id}_id" }) do %>
30 + <%= form_tag({:controller => 'main', :action => 'submit'}, {:method => 'post', :multipart => true, :id => "submission_form_#{problem.id}_id" }) do %>
31 + <%= hidden_field_tag 'submission[problem_id]', problem.id %>
30 32 ข้อมูลส่งออก: <%= file_field_tag 'output_file' %>
31 - โปรแกรมคำตอบ: <%= file_field_tag 'source_file' %>
33 + โปรแกรมคำตอบ: <%= file_field_tag 'file' %>
32 34 <%= submit_tag 'Submit' %>
33 35 <% end %>
34 36 </div>
@@ -49,6 +49,8
49 49 = "Announcement.refreshUrl = '#{url_for :controller => 'main', :action => 'announcements'}';"
50 50 Announcement.registerRefreshEventTimer();
51 51
52 + TOIContest.problemSelectClick()
53 +
52 54 TOIContest.timeOuts = {};
53 55 - @problems.each do |p|
54 56 - if (@submission_timeouts.has_key? p.id) and (@submission_timeouts[p.id] != nil)
@@ -57,3 +59,4
57 59 = "TOIContest.timeOuts[#{p.id}] = TOIContest.NO_TIMEOUT;"
58 60
59 61 TOIContest.refreshTimeOutMessages();
62 + TOIContest.registerRefreshEvent();
@@ -11,7 +11,7
11 11 #
12 12 # It's strongly recommended to check this file into your version control system.
13 13
14 - ActiveRecord::Schema.define(:version => 20150128165518) do
14 + ActiveRecord::Schema.define(:version => 20150129021221) do
15 15
16 16 create_table "announcements", :force => true do |t|
17 17 t.string "author"
@@ -166,6 +166,7
166 166 t.text "grader_comment"
167 167 t.integer "number"
168 168 t.string "source_filename"
169 + t.text "output"
169 170 end
170 171
171 172 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
You need to be logged in to leave comments. Login now