Description:
added submission_status to store grading results, first page shows only unpassed problems.
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r216:fa11dca6b078 - - 10 files changed: 131 inserted, 56 deleted

@@ -0,0 +1,6
1 + class SubmissionStatus < ActiveRecord::Base
2 +
3 + belongs_to :user
4 + belongs_to :problem
5 +
6 + end
@@ -0,0 +1,18
1 + .problem-panel{:id => "problem-panel-#{problem.id}", :style => "display:none"}
2 + .problem-form{:id => "problem-form-#{problem.id}"}
3 + - form_tag({ :action => 'download_input', :id => problem.id }, :method => :post) do
4 + %b Input:
5 + %input{:type => "submit", :value => "Download input"}
6 + - form_tag({ :action => 'submit_solution', :id => problem.id }, :method => :post, :multipart => true) do
7 + %b Submit output:
8 + %input{:type => "file", :name => "file"}
9 + %input{:type => "submit", :value => "Submit solution"}
10 +
11 + .problem-description
12 + - if problem.description!=nil
13 + - if problem.description.markdowned
14 + = markdown(problem.description.body)
15 + - else
16 + = problem.description.body
17 + - else
18 + (not available)
@@ -0,0 +1,16
1 + class CreateSubmissionStatuses < ActiveRecord::Migration
2 + def self.up
3 + create_table :submission_statuses do |t|
4 + t.integer :user_id
5 + t.integer :problem_id
6 + t.boolean :passed
7 + t.integer :submission_count
8 +
9 + t.timestamps
10 + end
11 + end
12 +
13 + def self.down
14 + drop_table :submission_statuses
15 + end
16 + end
@@ -0,0 +1,13
1 + # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 +
3 + one:
4 + user_id: 1
5 + problem_id: 1
6 + passed: false
7 + submission_count: 1
8 +
9 + two:
10 + user_id: 1
11 + problem_id: 1
12 + passed: false
13 + submission_count: 1
@@ -0,0 +1,8
1 + require 'test_helper'
2 +
3 + class SubmissionStatusTest < ActiveSupport::TestCase
4 + # Replace this with your real tests.
5 + test "the truth" do
6 + assert true
7 + end
8 + end
@@ -1,23 +1,23
1 1 class MainController < ApplicationController
2 2
3 3 SYSTEM_MODE_CONF_KEY = 'system.mode'
4 4
5 5 before_filter :authenticate, :except => [:index, :login]
6 6 before_filter :check_viewability, :except => [:index, :login]
7 7
8 8 # COMMENTED OUT: filter in each action instead
9 9 # before_filter :verify_time_limit, :only => [:submit]
10 10
11 - verify :method => :post, :only => [:submit, :new_input, :download_input, :submit_solution],
11 + verify :method => :post, :only => [:submit, :download_input, :submit_solution],
12 12 :redirect_to => { :action => :index }
13 13
14 14 # COMMENT OUT: only need when having high load
15 15 # caches_action :index, :login
16 16
17 17 # NOTE: This method is not actually needed, 'config/routes.rb' has
18 18 # assigned action login as a default action.
19 19 def index
20 20 redirect_to :action => 'login'
21 21 end
22 22
23 23 def login
@@ -167,111 +167,133
167 167
168 168 def announcements
169 169 if params.has_key? 'recent'
170 170 prepare_announcements(params[:recent])
171 171 else
172 172 prepare_announcements
173 173 end
174 174 render(:partial => 'announcement',
175 175 :collection => @announcements,
176 176 :locals => {:announcement_effect => true})
177 177 end
178 178
179 + #
179 180 # actions for Code Jom
180 - def new_input
181 + #
182 + def download_input
181 183 problem = Problem.find(params[:id])
182 184 user = User.find(session[:user_id])
183 185 if user.can_request_new_test_pair_for? problem
184 186 assignment = user.get_new_test_pair_assignment_for problem
185 187 assignment.save
186 188
187 189 send_data(assignment.test_pair.input,
188 190 { :filename => "#{problem.name}-#{assignment.request_number}.in",
189 191 :type => 'text/plain' })
190 192 else
191 - flash[:notice] = 'You cannot request new input now.'
192 - redirect_to :action => 'list'
193 - end
194 - end
195 -
196 - def download_input
197 - problem = Problem.find(params[:id])
198 - user = User.find(session[:user_id])
199 193 recent_assignment = user.get_recent_test_pair_assignment_for problem
200 - if recent_assignment != nil
201 194 send_data(recent_assignment.test_pair.input,
202 195 { :filename => "#{problem.name}-#{recent_assignment.request_number}.in",
203 196 :type => 'text/plain' })
204 - else
205 - flash[:notice] = 'You have not requested for any input data for this problem.'
206 - redirect_to :action => 'list'
207 197 end
208 198 end
209 199
210 200 def submit_solution
211 201 problem = Problem.find(params[:id])
212 202 user = User.find(session[:user_id])
213 203 recent_assignment = user.get_recent_test_pair_assignment_for problem
214 - if recent_assignment != nil
204 + if recent_assignment == nil
205 + flash[:notice] = 'You have not requested for any input data for this problem. Please download an input first.'
206 + redirect_to :action => 'list' and return
207 + end
208 +
209 + if recent_assignment.submitted
210 + flash[:notice] = 'You have already submitted an incorrect solution for this input. Please download a new input data.'
211 + redirect_to :action => 'list' and return
212 + end
213 +
214 + if params[:file] == nil
215 + flash[:notice] = 'You have not submitted any output.'
216 + redirect_to :action => 'list' and return
217 + end
218 +
215 219 submitted_solution = params[:file].read
216 220 test_pair = recent_assignment.test_pair
217 221 passed = test_pair.grade(submitted_solution)
218 222 points = passed ? 100 : 0
219 223 submission = Submission.new(:user => user,
220 224 :problem => problem,
221 - :source => params[:file].read,
225 + :source => submitted_solution,
222 226 :source_filename => params['file'].original_filename,
223 227 :language_id => 0,
224 228 :submitted_at => Time.new.gmtime,
225 229 :graded_at => Time.new.gmtime,
226 230 :points => points)
227 231 submission.save
228 232 recent_assignment.submitted = true
229 233 recent_assignment.save
234 +
235 + status = user.get_submission_status_for(problem)
236 + if status == nil
237 + status = SubmissionStatus.new :user => user, :problem => problem, :submission_count => 0
238 + end
239 +
240 + status.submission_count += 1
241 + status.passed = passed
242 + status.save
243 +
230 244 if passed
231 - flash[:notice] = 'Correct solution'
245 + flash[:notice] = 'Correct solution.'
232 246 else
233 - flash[:notice] = 'Incorrect solution'
247 + flash[:notice] = 'Incorrect solution.'
234 248 end
235 249 redirect_to :action => 'list'
236 - else
237 - flash[:notice] = 'You have not requested for any input data for this problem.'
238 - redirect_to :action => 'list'
239 - end
240 250 end
241 251
242 252 protected
243 253
244 254 def prepare_announcements(recent=nil)
245 255 if Configuration.show_tasks_to?(@user)
246 256 @announcements = Announcement.find_published(true)
247 257 else
248 258 @announcements = Announcement.find_published
249 259 end
250 260 if recent!=nil
251 261 recent_id = recent.to_i
252 262 @announcements = @announcements.find_all { |a| a.id > recent_id }
253 263 end
254 264 end
255 265
256 266 def prepare_list_information
257 - @problems = Problem.find_available_problems
267 + @user = User.find(session[:user_id])
268 +
269 + all_problems = Problem.find_available_problems
270 +
271 + passed = {}
272 + sub_count = {}
273 + @user.submission_statuses.each do |status|
274 + if status.passed
275 + passed[status.problem_id] = true
276 + end
277 + sub_count[status.problem_id] = status.submission_count
278 + end
279 +
280 + @problems = all_problems.reject { |problem| passed.has_key? problem.id }
281 +
258 282 @prob_submissions = Array.new
259 - @user = User.find(session[:user_id])
260 283 @problems.each do |p|
261 - sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
262 - if sub!=nil
263 - @prob_submissions << { :count => sub.number, :submission => sub }
284 + if sub_count.has_key? p.id
285 + @prob_submissions << { :count => sub_count[p.id] }
264 286 else
265 - @prob_submissions << { :count => 0, :submission => nil }
287 + @prob_submissions << { :count => 0 }
266 288 end
267 289 end
268 290 prepare_announcements
269 291 end
270 292
271 293 def check_viewability
272 294 @user = User.find(session[:user_id])
273 295 if (!Configuration.show_tasks_to?(@user)) and
274 296 ((action_name=='submission') or (action_name=='submit'))
275 297 redirect_to :action => 'list' and return
276 298 end
277 299 end
@@ -2,25 +2,25
2 2
3 3 belongs_to :language
4 4 belongs_to :problem
5 5 belongs_to :user
6 6
7 7 before_validation :assign_problem
8 8 before_validation :assign_language
9 9
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 13 validate :must_have_valid_problem
14 - validate :must_specify_language
14 + #validate :must_specify_language
15 15
16 16 before_save :assign_latest_number_if_new_recond
17 17
18 18 def self.find_last_by_user_and_problem(user_id, problem_id)
19 19 last_sub = find(:first,
20 20 :conditions => {:user_id => user_id,
21 21 :problem_id => problem_id},
22 22 :order => 'number DESC')
23 23 return last_sub
24 24 end
25 25
26 26 def self.find_all_last_by_problem(problem_id)
@@ -8,24 +8,25
8 8
9 9 has_many :messages,
10 10 :class_name => "Message",
11 11 :foreign_key => "sender_id",
12 12 :order => 'created_at DESC'
13 13
14 14 has_many :replied_messages,
15 15 :class_name => "Message",
16 16 :foreign_key => "receiver_id",
17 17 :order => 'created_at DESC'
18 18
19 19 has_many :test_pair_assignments, :dependent => :delete_all
20 + has_many :submission_statuses
20 21
21 22 belongs_to :site
22 23 belongs_to :country
23 24
24 25 named_scope :activated_users, :conditions => {:activated => true}
25 26
26 27 validates_presence_of :login
27 28 validates_uniqueness_of :login
28 29 validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
29 30 validates_length_of :login, :within => 3..30
30 31
31 32 validates_presence_of :full_name
@@ -102,24 +103,32
102 103 :problem => problem,
103 104 :test_pair => test_pair,
104 105 :test_pair_number => test_pair.number,
105 106 :request_number =>
106 107 previous_assignment_numbers.length + 1,
107 108 :submitted => false)
108 109 return assignment
109 110 else
110 111 return nil
111 112 end
112 113 end
113 114
115 + def get_submission_status_for(problem)
116 + SubmissionStatus.find(:first,
117 + :conditions => {
118 + :user_id => id,
119 + :problem_id => problem.id
120 + })
121 + end
122 +
114 123 def email_for_editing
115 124 if self.email==nil
116 125 "(unknown)"
117 126 elsif self.email==''
118 127 "(blank)"
119 128 else
120 129 self.email
121 130 end
122 131 end
123 132
124 133 def email_for_editing=(e)
125 134 self.email=e
@@ -1,24 +1,24
1 1 # This file is auto-generated from the current state of the database. Instead of editing this file,
2 2 # please use the migrations feature of Active Record to incrementally modify your database, and
3 3 # then regenerate this schema definition.
4 4 #
5 5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
6 6 # to create the application database on another system, you should be using db:schema:load, not running
7 7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
8 8 # you'll amass, the slower it'll run and the greater likelihood for issues).
9 9 #
10 10 # It's strongly recommended to check this file into your version control system.
11 11
12 - ActiveRecord::Schema.define(:version => 20100118174404) do
12 + ActiveRecord::Schema.define(:version => 20100123154326) do
13 13
14 14 create_table "announcements", :force => true do |t|
15 15 t.string "author"
16 16 t.text "body"
17 17 t.boolean "published"
18 18 t.datetime "created_at"
19 19 t.datetime "updated_at"
20 20 t.boolean "frontpage", :default => false
21 21 t.boolean "contest_only", :default => false
22 22 t.string "title"
23 23 end
24 24
@@ -120,24 +120,33
120 120 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
121 121
122 122 create_table "sites", :force => true do |t|
123 123 t.string "name"
124 124 t.boolean "started"
125 125 t.datetime "start_time"
126 126 t.datetime "created_at"
127 127 t.datetime "updated_at"
128 128 t.integer "country_id"
129 129 t.string "password"
130 130 end
131 131
132 + create_table "submission_statuses", :force => true do |t|
133 + t.integer "user_id"
134 + t.integer "problem_id"
135 + t.boolean "passed"
136 + t.integer "submission_count"
137 + t.datetime "created_at"
138 + t.datetime "updated_at"
139 + end
140 +
132 141 create_table "submissions", :force => true do |t|
133 142 t.integer "user_id"
134 143 t.integer "problem_id"
135 144 t.integer "language_id"
136 145 t.text "source"
137 146 t.binary "binary"
138 147 t.datetime "submitted_at"
139 148 t.datetime "compiled_at"
140 149 t.text "compiler_message"
141 150 t.datetime "graded_at"
142 151 t.integer "points"
143 152 t.text "grader_comment"
deleted file
You need to be logged in to leave comments. Login now