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 @@ -8,7 +8,7 @@ # COMMENTED OUT: filter in each action instead # before_filter :verify_time_limit, :only => [:submit] - verify :method => :post, :only => [:submit, :new_input, :download_input, :submit_solution], + verify :method => :post, :only => [:submit, :download_input, :submit_solution], :redirect_to => { :action => :index } # COMMENT OUT: only need when having high load @@ -176,8 +176,10 @@ :locals => {:announcement_effect => true}) end + # # actions for Code Jom - def new_input + # + def download_input problem = Problem.find(params[:id]) user = User.find(session[:user_id]) if user.can_request_new_test_pair_for? problem @@ -187,23 +189,11 @@ send_data(assignment.test_pair.input, { :filename => "#{problem.name}-#{assignment.request_number}.in", :type => 'text/plain' }) - else - flash[:notice] = 'You cannot request new input now.' - redirect_to :action => 'list' - end - end - - def download_input - problem = Problem.find(params[:id]) - user = User.find(session[:user_id]) - recent_assignment = user.get_recent_test_pair_assignment_for problem - if recent_assignment != nil + else + recent_assignment = user.get_recent_test_pair_assignment_for problem send_data(recent_assignment.test_pair.input, { :filename => "#{problem.name}-#{recent_assignment.request_number}.in", :type => 'text/plain' }) - else - flash[:notice] = 'You have not requested for any input data for this problem.' - redirect_to :action => 'list' end end @@ -211,32 +201,52 @@ problem = Problem.find(params[:id]) user = User.find(session[:user_id]) recent_assignment = user.get_recent_test_pair_assignment_for problem - if recent_assignment != nil - submitted_solution = params[:file].read - test_pair = recent_assignment.test_pair - passed = test_pair.grade(submitted_solution) - points = passed ? 100 : 0 - submission = Submission.new(:user => user, - :problem => problem, - :source => params[:file].read, - :source_filename => params['file'].original_filename, - :language_id => 0, - :submitted_at => Time.new.gmtime, - :graded_at => Time.new.gmtime, - :points => points) - submission.save - recent_assignment.submitted = true - recent_assignment.save - if passed - flash[:notice] = 'Correct solution' - else - flash[:notice] = 'Incorrect solution' - end - redirect_to :action => 'list' + if recent_assignment == nil + flash[:notice] = 'You have not requested for any input data for this problem. Please download an input first.' + redirect_to :action => 'list' and return + end + + if recent_assignment.submitted + flash[:notice] = 'You have already submitted an incorrect solution for this input. Please download a new input data.' + redirect_to :action => 'list' and return + end + + if params[:file] == nil + flash[:notice] = 'You have not submitted any output.' + redirect_to :action => 'list' and return + end + + submitted_solution = params[:file].read + test_pair = recent_assignment.test_pair + passed = test_pair.grade(submitted_solution) + points = passed ? 100 : 0 + submission = Submission.new(:user => user, + :problem => problem, + :source => submitted_solution, + :source_filename => params['file'].original_filename, + :language_id => 0, + :submitted_at => Time.new.gmtime, + :graded_at => Time.new.gmtime, + :points => points) + submission.save + recent_assignment.submitted = true + recent_assignment.save + + status = user.get_submission_status_for(problem) + if status == nil + status = SubmissionStatus.new :user => user, :problem => problem, :submission_count => 0 + end + + status.submission_count += 1 + status.passed = passed + status.save + + if passed + flash[:notice] = 'Correct solution.' else - flash[:notice] = 'You have not requested for any input data for this problem.' - redirect_to :action => 'list' + flash[:notice] = 'Incorrect solution.' end + redirect_to :action => 'list' end protected @@ -254,15 +264,27 @@ end def prepare_list_information - @problems = Problem.find_available_problems + @user = User.find(session[:user_id]) + + all_problems = Problem.find_available_problems + + passed = {} + sub_count = {} + @user.submission_statuses.each do |status| + if status.passed + passed[status.problem_id] = true + end + sub_count[status.problem_id] = status.submission_count + end + + @problems = all_problems.reject { |problem| passed.has_key? problem.id } + @prob_submissions = Array.new - @user = User.find(session[:user_id]) @problems.each do |p| - sub = Submission.find_last_by_user_and_problem(@user.id,p.id) - if sub!=nil - @prob_submissions << { :count => sub.number, :submission => sub } + if sub_count.has_key? p.id + @prob_submissions << { :count => sub_count[p.id] } else - @prob_submissions << { :count => 0, :submission => nil } + @prob_submissions << { :count => 0 } end end prepare_announcements diff --git a/app/models/submission.rb b/app/models/submission.rb --- a/app/models/submission.rb +++ b/app/models/submission.rb @@ -11,7 +11,7 @@ validates_length_of :source, :maximum => 100_000, :allow_blank => true, :message => 'too long' validates_length_of :source, :minimum => 1, :allow_blank => true, :message => 'too short' validate :must_have_valid_problem - validate :must_specify_language + #validate :must_specify_language before_save :assign_latest_number_if_new_recond diff --git a/app/models/submission_status.rb b/app/models/submission_status.rb new file mode 100644 --- /dev/null +++ b/app/models/submission_status.rb @@ -0,0 +1,6 @@ +class SubmissionStatus < ActiveRecord::Base + + belongs_to :user + belongs_to :problem + +end diff --git a/app/models/user.rb b/app/models/user.rb --- a/app/models/user.rb +++ b/app/models/user.rb @@ -17,6 +17,7 @@ :order => 'created_at DESC' has_many :test_pair_assignments, :dependent => :delete_all + has_many :submission_statuses belongs_to :site belongs_to :country @@ -111,6 +112,14 @@ end end + def get_submission_status_for(problem) + SubmissionStatus.find(:first, + :conditions => { + :user_id => id, + :problem_id => problem.id + }) + end + def email_for_editing if self.email==nil "(unknown)" diff --git a/app/views/main/_problem.html.erb b/app/views/main/_problem.html.erb deleted file mode 100644 --- a/app/views/main/_problem.html.erb +++ /dev/null @@ -1,26 +0,0 @@ - diff --git a/app/views/main/_problem.html.haml b/app/views/main/_problem.html.haml new file mode 100644 --- /dev/null +++ b/app/views/main/_problem.html.haml @@ -0,0 +1,18 @@ +.problem-panel{:id => "problem-panel-#{problem.id}", :style => "display:none"} + .problem-form{:id => "problem-form-#{problem.id}"} + - form_tag({ :action => 'download_input', :id => problem.id }, :method => :post) do + %b Input: + %input{:type => "submit", :value => "Download input"} + - form_tag({ :action => 'submit_solution', :id => problem.id }, :method => :post, :multipart => true) do + %b Submit output: + %input{:type => "file", :name => "file"} + %input{:type => "submit", :value => "Submit solution"} + + .problem-description + - if problem.description!=nil + - if problem.description.markdowned + = markdown(problem.description.body) + - else + = problem.description.body + - else + (not available) diff --git a/db/migrate/20100123154326_create_submission_statuses.rb b/db/migrate/20100123154326_create_submission_statuses.rb new file mode 100644 --- /dev/null +++ b/db/migrate/20100123154326_create_submission_statuses.rb @@ -0,0 +1,16 @@ +class CreateSubmissionStatuses < ActiveRecord::Migration + def self.up + create_table :submission_statuses do |t| + t.integer :user_id + t.integer :problem_id + t.boolean :passed + t.integer :submission_count + + t.timestamps + end + end + + def self.down + drop_table :submission_statuses + end +end diff --git a/db/schema.rb b/db/schema.rb --- a/db/schema.rb +++ b/db/schema.rb @@ -9,7 +9,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20100118174404) do +ActiveRecord::Schema.define(:version => 20100123154326) do create_table "announcements", :force => true do |t| t.string "author" @@ -129,6 +129,15 @@ t.string "password" end + create_table "submission_statuses", :force => true do |t| + t.integer "user_id" + t.integer "problem_id" + t.boolean "passed" + t.integer "submission_count" + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "submissions", :force => true do |t| t.integer "user_id" t.integer "problem_id" diff --git a/test/fixtures/submission_statuses.yml b/test/fixtures/submission_statuses.yml new file mode 100644 --- /dev/null +++ b/test/fixtures/submission_statuses.yml @@ -0,0 +1,13 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html + +one: + user_id: 1 + problem_id: 1 + passed: false + submission_count: 1 + +two: + user_id: 1 + problem_id: 1 + passed: false + submission_count: 1 diff --git a/test/unit/submission_status_test.rb b/test/unit/submission_status_test.rb new file mode 100644 --- /dev/null +++ b/test/unit/submission_status_test.rb @@ -0,0 +1,8 @@ +require 'test_helper' + +class SubmissionStatusTest < ActiveSupport::TestCase + # Replace this with your real tests. + test "the truth" do + assert true + end +end