# HG changeset patch # User Jittat Fakcharoenphol # Date 2015-01-28 19:23:50 # Node ID abc583474e72bb376ecaa7179f3708f822784810 # Parent 894c9826b6b5f9b5bc082c677773f9ff0186f099 shows test pair download and grade sample test cases diff --git a/app/controllers/main_controller.rb b/app/controllers/main_controller.rb --- a/app/controllers/main_controller.rb +++ b/app/controllers/main_controller.rb @@ -200,9 +200,88 @@ @user = user end end + + # thailandoi contests + + def verifying_testcase + problem = Problem.find(params[:id]) + if !problem.available + flash[:notice] = 'Error: problem is not available' + redirect_to :action => 'list' + else + test_pair = TestPair.get_for(problem, false) + send_data(test_pair.input, + {:filename => problem.name + '-verifying-input.txt', + :type => 'text/plain'}) + end + end + def testcase + problem = Problem.find(params[:id]) + if !problem.available + flash[:notice] = 'Error: problem is not available' + redirect_to :action => 'list' + else + test_pair = TestPair.get_for(problem, true) + + user = User.find(session[:user_id]) + assignent = user.get_test_pair_assignment_for(problem) + + if !assignent + assignent = TestPairAssignment.new + assignent.user = user + assignent.problem = problem + assignent.test_pair = test_pair + assignent.submitted = false + assignent.save + end + + send_data(test_pair.input, + {:filename => problem.name + '-input.txt', + :type => 'text/plain'}) + end + end + + def verifying_submit + user = User.find(session[:user_id]) + problem_id = params[:id] + problem = Problem.find(problem_id) + + if !problem or !problem.available + flash[:notice] = 'Error: problem is not available' + redirect_to :action => 'list' and return + end + + test_pair = TestPair.get_for(problem, false) + if (params['output_file']) and (params['output_file']!='') + output = params['output_file'].read + + @current_problem = problem + @grading_result = grade(output, test_pair.solution) + prepare_list_information + render :action => 'list' and return + else + flash[:notice] = 'Error: output file errors' + redirect_to :action => 'list' + end + end + protected + def grade(output, solution) + out_items = output.split + sol_items = solution.split + res = '' + sol_items.length.times do |i| + if out_items[i] == sol_items[i] + res = res + 'P' + else + res = res + '-' + end + end + return res + end + def prepare_announcements(recent=nil) if GraderConfiguration.show_tasks_to?(@user) @announcements = Announcement.find_published(true) @@ -215,6 +294,23 @@ end end + def prepare_timeout_information(problems) + @submission_timeouts = {} + problems.each do |problem| + assignment = @user.get_test_pair_assignment_for(problem) + if assignment == nil + timeout = nil + else + if (assignment.expired?) or (assignment.submitted) + timeout = 0 + else + timeout = assignment.created_at + TEST_ASSIGNMENT_EXPIRATION_DURATION - Time.new.gmtime + end + end + @submission_timeouts[problem.id] = timeout + end + end + def prepare_list_information @user = User.find(session[:user_id]) if not GraderConfiguration.multicontests? @@ -233,6 +329,7 @@ end end prepare_announcements + prepare_timeout_information(@problems) end def check_viewability diff --git a/app/models/test_pair.rb b/app/models/test_pair.rb --- a/app/models/test_pair.rb +++ b/app/models/test_pair.rb @@ -1,3 +1,8 @@ class TestPair < ActiveRecord::Base belongs_to :problem + + def self.get_for(problem, is_private) + return TestPair.where(:problem_id => problem.id, + :is_private => is_private).first + end end diff --git a/app/models/test_pair_assignment.rb b/app/models/test_pair_assignment.rb new file mode 100644 --- /dev/null +++ b/app/models/test_pair_assignment.rb @@ -0,0 +1,9 @@ +class TestPairAssignment < ActiveRecord::Base + belongs_to :problem + belongs_to :test_pair + belongs_to :user + + def expired? + return created_at + TEST_ASSIGNMENT_EXPIRATION_DURATION < Time.new.gmtime + end +end diff --git a/app/models/user.rb b/app/models/user.rb --- a/app/models/user.rb +++ b/app/models/user.rb @@ -254,6 +254,11 @@ end end + def get_test_pair_assignment_for(problem) + return TestPairAssignment.where(:problem_id => problem.id, + :user_id => id).first + end + protected def encrypt_new_password return if password.blank? diff --git a/app/views/main/_submission_box.html.erb b/app/views/main/_submission_box.html.erb --- a/app/views/main/_submission_box.html.erb +++ b/app/views/main/_submission_box.html.erb @@ -1,8 +1,51 @@ -<%= form_tag({:action => 'submit'}, :multipart => true) do %> -Problem: <%= select 'submission', 'problem_id', - [[(t 'main.specified_in_header'),'-1']] + - @problems.collect {|p| [p.full_name, p.id]}, - :selected => '-1' %> -File: <%= file_field_tag 'file' %> -<%= submit_tag 'Submit' %> +
+ Problem: <%= select 'submission', 'problem_id', + [['กรุณาเลือกข้อที่ต้องการส่งหรือทดสอบ','-1']] + + @problems.collect {|p| [p.full_name, p.id]}, + { :selected => '-1' }, + { :onchange => 'select_click()' } %> +
+ +<% @problems.each do |problem| %> +
+
+ <%= problem.full_name %>: ข้อมูลสำหรับตรวจสอบ (สามารถดาวน์โหลดและส่งกี่ครั้งก็ได้): + <%= link_to 'ดาวน์โหลด input', :action => 'verifying_testcase', :id => problem.id %> + <% if @current_problem.id == problem.id %> + <% if @grading_result %> + | ผลการตรวจ: <%= @grading_result %> + <% end %> + <% end %> + <%= form_tag({:controller => 'main', :action => 'verifying_submit', :id => problem.id}, {:method => 'post', :multipart => true}) do %> + ส่งคำตอบของข้อมูลสำหรับตรวจสอบ: + <%= file_field_tag 'output_file' %> + <%= submit_tag 'Submit' %> + <% end %> +
+
+ <%= problem.full_name %>: ข้อมูลทดสอบจริง (ส่งกี่ครั้งก็ได้ภายในเวลา 5 นาทีหลังดาวน์โหลด): + <%= link_to 'ดาวน์โหลด input และเริ่มจับเวลา', { :action => 'testcase', :id => problem.id}, { :onclick => 'return confirm_download()' } %> + + <%= form_tag do %> + ข้อมูลส่งออก: <%= file_field_tag 'output_file' %> + โปรแกรมคำตอบ: <%= file_field_tag 'source_file' %> + <%= submit_tag 'Submit' %> + <% end %> +
+
<% end %> + diff --git a/app/views/main/list.html.haml b/app/views/main/list.html.haml --- a/app/views/main/list.html.haml +++ b/app/views/main/list.html.haml @@ -10,9 +10,8 @@ = render :partial => 'announcement', :collection => @announcements - if GraderConfiguration.show_submitbox_to?(@user) - .submitbox - = error_messages_for 'submission' - = render :partial => 'submission_box' + = error_messages_for 'submission' + = render :partial => 'submission_box' %hr/ diff --git a/db/migrate/20150128163722_add_is_private_to_test_pairs.rb b/db/migrate/20150128163722_add_is_private_to_test_pairs.rb new file mode 100644 --- /dev/null +++ b/db/migrate/20150128163722_add_is_private_to_test_pairs.rb @@ -0,0 +1,5 @@ +class AddIsPrivateToTestPairs < ActiveRecord::Migration + def change + add_column :test_pairs, :is_private, :boolean + end +end diff --git a/db/migrate/20150128165518_create_test_pair_assignments.rb b/db/migrate/20150128165518_create_test_pair_assignments.rb new file mode 100644 --- /dev/null +++ b/db/migrate/20150128165518_create_test_pair_assignments.rb @@ -0,0 +1,16 @@ +class CreateTestPairAssignments < ActiveRecord::Migration + def up + create_table :test_pair_assignments do |t| + t.integer "user_id" + t.integer "problem_id" + t.integer "test_pair_id" + t.integer "request_number" + t.boolean "submitted" + t.timestamps + end + end + + def down + drop_table :test_pair_assignments + end +end diff --git a/db/schema.rb b/db/schema.rb --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20121001033508) do +ActiveRecord::Schema.define(:version => 20150128165518) do create_table "announcements", :force => true do |t| t.string "author" @@ -178,12 +178,23 @@ t.datetime "updated_at" end + create_table "test_pair_assignments", :force => true do |t| + t.integer "user_id" + t.integer "problem_id" + t.integer "test_pair_id" + t.integer "request_number" + t.boolean "submitted" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + create_table "test_pairs", :force => true do |t| t.integer "problem_id" t.text "input", :limit => 16777215 t.text "solution", :limit => 16777215 t.datetime "created_at", :null => false t.datetime "updated_at", :null => false + t.boolean "is_private" end create_table "test_requests", :force => true do |t|