Description:
added codejom_status model for computing level with basic user update
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r219:95cc49d72ca8 - - 9 files changed: 79 inserted, 1 deleted

@@ -0,0 +1,5
1 + class CodejomStatus < ActiveRecord::Base
2 +
3 + belongs_to :user
4 +
5 + end
@@ -0,0 +1,15
1 + class CreateCodejomStatuses < ActiveRecord::Migration
2 + def self.up
3 + create_table :codejom_statuses do |t|
4 + t.integer :user_id
5 + t.boolean :alive
6 + t.integer :num_problems_passed
7 +
8 + t.timestamps
9 + end
10 + end
11 +
12 + def self.down
13 + drop_table :codejom_statuses
14 + end
15 + end
@@ -0,0 +1,11
1 + # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 +
3 + one:
4 + user_id: 1
5 + alive: false
6 + num_problems_passed: 1
7 +
8 + two:
9 + user_id: 1
10 + alive: false
11 + num_problems_passed: 1
@@ -0,0 +1,8
1 + require 'test_helper'
2 +
3 + class CodejomStatusTest < ActiveSupport::TestCase
4 + # Replace this with your real tests.
5 + test "the truth" do
6 + assert true
7 + end
8 + end
@@ -219,48 +219,49
219 points = passed ? 100 : 0
219 points = passed ? 100 : 0
220 submission = Submission.new(:user => user,
220 submission = Submission.new(:user => user,
221 :problem => problem,
221 :problem => problem,
222 :source => submitted_solution,
222 :source => submitted_solution,
223 :source_filename => params['file'].original_filename,
223 :source_filename => params['file'].original_filename,
224 :language_id => 0,
224 :language_id => 0,
225 :submitted_at => Time.new.gmtime,
225 :submitted_at => Time.new.gmtime,
226 :graded_at => Time.new.gmtime,
226 :graded_at => Time.new.gmtime,
227 :points => points)
227 :points => points)
228 submission.save
228 submission.save
229 recent_assignment.submitted = true
229 recent_assignment.submitted = true
230 recent_assignment.save
230 recent_assignment.save
231
231
232 status = user.get_submission_status_for(problem)
232 status = user.get_submission_status_for(problem)
233 if status == nil
233 if status == nil
234 status = SubmissionStatus.new :user => user, :problem => problem, :submission_count => 0
234 status = SubmissionStatus.new :user => user, :problem => problem, :submission_count => 0
235 end
235 end
236
236
237 status.submission_count += 1
237 status.submission_count += 1
238 status.passed = passed
238 status.passed = passed
239 status.save
239 status.save
240
240
241 if passed
241 if passed
242 flash[:notice] = 'Correct solution.'
242 flash[:notice] = 'Correct solution.'
243 + user.update_codejom_status
243 else
244 else
244 flash[:notice] = 'Incorrect solution.'
245 flash[:notice] = 'Incorrect solution.'
245 end
246 end
246 redirect_to :action => 'list'
247 redirect_to :action => 'list'
247 end
248 end
248
249
249 protected
250 protected
250
251
251 def prepare_announcements(recent=nil)
252 def prepare_announcements(recent=nil)
252 if Configuration.show_tasks_to?(@user)
253 if Configuration.show_tasks_to?(@user)
253 @announcements = Announcement.find_published(true)
254 @announcements = Announcement.find_published(true)
254 else
255 else
255 @announcements = Announcement.find_published
256 @announcements = Announcement.find_published
256 end
257 end
257 if recent!=nil
258 if recent!=nil
258 recent_id = recent.to_i
259 recent_id = recent.to_i
259 @announcements = @announcements.find_all { |a| a.id > recent_id }
260 @announcements = @announcements.find_all { |a| a.id > recent_id }
260 end
261 end
261 end
262 end
262
263
263 def prepare_list_information
264 def prepare_list_information
264 @user = User.find(session[:user_id])
265 @user = User.find(session[:user_id])
265
266
266 all_problems = Problem.find_available_problems
267 all_problems = Problem.find_available_problems
@@ -8,48 +8,53
8 validates_presence_of :full_name
8 validates_presence_of :full_name
9
9
10 DEFAULT_TIME_LIMIT = 1
10 DEFAULT_TIME_LIMIT = 1
11 DEFAULT_MEMORY_LIMIT = 32
11 DEFAULT_MEMORY_LIMIT = 32
12
12
13 def test_pair_count
13 def test_pair_count
14 @test_pair_count ||= test_pairs.size
14 @test_pair_count ||= test_pairs.size
15 end
15 end
16
16
17 def uses_random_test_pair?
17 def uses_random_test_pair?
18 test_pair_count != 0
18 test_pair_count != 0
19 end
19 end
20
20
21 def random_test_pair(forbidden_numbers=nil)
21 def random_test_pair(forbidden_numbers=nil)
22 begin
22 begin
23 test_num = 1 + rand(test_pair_count)
23 test_num = 1 + rand(test_pair_count)
24 end while forbidden_numbers!=nil and forbidden_numbers.include? test_num
24 end while forbidden_numbers!=nil and forbidden_numbers.include? test_num
25 test_pairs.find_by_number test_num
25 test_pairs.find_by_number test_num
26 end
26 end
27
27
28 def self.find_available_problems
28 def self.find_available_problems
29 find(:all, :conditions => {:available => true}, :order => "date_added DESC")
29 find(:all, :conditions => {:available => true}, :order => "date_added DESC")
30 end
30 end
31
31
32 + # TODO: may try to optimize this using cache
33 + def self.available_problem_count
34 + return Problem.find_available_problems.length
35 + end
36 +
32 def self.create_from_import_form_params(params, old_problem=nil)
37 def self.create_from_import_form_params(params, old_problem=nil)
33 problem = old_problem || Problem.new
38 problem = old_problem || Problem.new
34 import_params = Problem.extract_params_and_check(params, problem)
39 import_params = Problem.extract_params_and_check(params, problem)
35
40
36 if not problem.valid?
41 if not problem.valid?
37 return problem, 'Error importing'
42 return problem, 'Error importing'
38 end
43 end
39
44
40 problem.full_score = 100
45 problem.full_score = 100
41 problem.date_added = Time.new
46 problem.date_added = Time.new
42 problem.test_allowed = true
47 problem.test_allowed = true
43 problem.output_only = false
48 problem.output_only = false
44 problem.available = false
49 problem.available = false
45
50
46 if not problem.save
51 if not problem.save
47 return problem, 'Error importing'
52 return problem, 'Error importing'
48 end
53 end
49
54
50 import_to_db = params.has_key? :import_to_db
55 import_to_db = params.has_key? :import_to_db
51
56
52 importer = TestdataImporter.new(problem)
57 importer = TestdataImporter.new(problem)
53
58
54 if not importer.import_from_file(import_params[:file],
59 if not importer.import_from_file(import_params[:file],
55 import_params[:time_limit],
60 import_params[:time_limit],
@@ -3,48 +3,51
3 class User < ActiveRecord::Base
3 class User < ActiveRecord::Base
4
4
5 has_and_belongs_to_many :roles
5 has_and_belongs_to_many :roles
6
6
7 has_many :test_requests, :order => "submitted_at DESC"
7 has_many :test_requests, :order => "submitted_at DESC"
8
8
9 has_many :messages,
9 has_many :messages,
10 :class_name => "Message",
10 :class_name => "Message",
11 :foreign_key => "sender_id",
11 :foreign_key => "sender_id",
12 :order => 'created_at DESC'
12 :order => 'created_at DESC'
13
13
14 has_many :replied_messages,
14 has_many :replied_messages,
15 :class_name => "Message",
15 :class_name => "Message",
16 :foreign_key => "receiver_id",
16 :foreign_key => "receiver_id",
17 :order => 'created_at DESC'
17 :order => 'created_at DESC'
18
18
19 has_many :test_pair_assignments, :dependent => :delete_all
19 has_many :test_pair_assignments, :dependent => :delete_all
20 has_many :submission_statuses
20 has_many :submission_statuses
21
21
22 has_one :contest_stat, :class_name => "UserContestStat"
22 has_one :contest_stat, :class_name => "UserContestStat"
23
23
24 belongs_to :site
24 belongs_to :site
25 belongs_to :country
25 belongs_to :country
26
26
27 + # For Code Jom
28 + has_one :codejom_status
29 +
27 named_scope :activated_users, :conditions => {:activated => true}
30 named_scope :activated_users, :conditions => {:activated => true}
28
31
29 validates_presence_of :login
32 validates_presence_of :login
30 validates_uniqueness_of :login
33 validates_uniqueness_of :login
31 validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
34 validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
32 validates_length_of :login, :within => 3..30
35 validates_length_of :login, :within => 3..30
33
36
34 validates_presence_of :full_name
37 validates_presence_of :full_name
35 validates_length_of :full_name, :minimum => 1
38 validates_length_of :full_name, :minimum => 1
36
39
37 validates_presence_of :password, :if => :password_required?
40 validates_presence_of :password, :if => :password_required?
38 validates_length_of :password, :within => 4..20, :if => :password_required?
41 validates_length_of :password, :within => 4..20, :if => :password_required?
39 validates_confirmation_of :password, :if => :password_required?
42 validates_confirmation_of :password, :if => :password_required?
40
43
41 validates_format_of :email,
44 validates_format_of :email,
42 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
45 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
43 :if => :email_validation?
46 :if => :email_validation?
44 validate :uniqueness_of_email_from_activated_users,
47 validate :uniqueness_of_email_from_activated_users,
45 :if => :email_validation?
48 :if => :email_validation?
46 validate :enough_time_interval_between_same_email_registrations,
49 validate :enough_time_interval_between_same_email_registrations,
47 :if => :email_validation?
50 :if => :email_validation?
48
51
49 # these are for ytopc
52 # these are for ytopc
50 # disable for now
53 # disable for now
@@ -200,48 +203,66
200 def contest_finished?
203 def contest_finished?
201 if Configuration.contest_mode?
204 if Configuration.contest_mode?
202 return false if site==nil
205 return false if site==nil
203 return site.finished?
206 return site.finished?
204 elsif Configuration.indv_contest_mode?
207 elsif Configuration.indv_contest_mode?
205 time_limit = Configuration.contest_time_limit
208 time_limit = Configuration.contest_time_limit
206
209
207 return false if contest_stat==nil
210 return false if contest_stat==nil
208
211
209 return contest_time_left == 0
212 return contest_time_left == 0
210 else
213 else
211 return false
214 return false
212 end
215 end
213 end
216 end
214
217
215 def contest_started?
218 def contest_started?
216 if Configuration.contest_mode?
219 if Configuration.contest_mode?
217 return true if site==nil
220 return true if site==nil
218 return site.started
221 return site.started
219 else
222 else
220 return true
223 return true
221 end
224 end
222 end
225 end
223
226
227 + # For Code Jom
228 + def update_codejom_status
229 + status = codejom_status || CodejomStatus.new(:user => self)
230 + problem_count = Problem.available_problem_count
231 + status.num_problems_passed = (self.submission_statuses.find_all {|s| s.passed}).length
232 + status.alive = (problem_count - (status.num_problems_passed)) <= CODEJOM_MAX_ALIVE_LEVEL
233 + status.save
234 + end
235 +
236 + def codejom_level
237 + problem_count = Problem.available_problem_count
238 + if codejom_status!=nil
239 + return problem_count - codejom_status.num_problems_passed
240 + else
241 + return problem_count
242 + end
243 + end
244 +
224 protected
245 protected
225 def encrypt_new_password
246 def encrypt_new_password
226 return if password.blank?
247 return if password.blank?
227 self.salt = (10+rand(90)).to_s
248 self.salt = (10+rand(90)).to_s
228 self.hashed_password = User.encrypt(self.password,self.salt)
249 self.hashed_password = User.encrypt(self.password,self.salt)
229 end
250 end
230
251
231 def assign_default_site
252 def assign_default_site
232 # have to catch error when migrating (because self.site is not available).
253 # have to catch error when migrating (because self.site is not available).
233 begin
254 begin
234 if self.site==nil
255 if self.site==nil
235 self.site = Site.find_by_name('default')
256 self.site = Site.find_by_name('default')
236 if self.site==nil
257 if self.site==nil
237 self.site = Site.find(1) # when 'default has be renamed'
258 self.site = Site.find(1) # when 'default has be renamed'
238 end
259 end
239 end
260 end
240 rescue
261 rescue
241 end
262 end
242 end
263 end
243
264
244 def password_required?
265 def password_required?
245 self.hashed_password.blank? || !self.password.blank?
266 self.hashed_password.blank? || !self.password.blank?
246 end
267 end
247
268
@@ -82,24 +82,28
82 # These are where inputs and outputs of test requests are stored
82 # These are where inputs and outputs of test requests are stored
83 TEST_REQUEST_INPUT_FILE_DIR = RAILS_ROOT + '/data/test_request/input'
83 TEST_REQUEST_INPUT_FILE_DIR = RAILS_ROOT + '/data/test_request/input'
84 TEST_REQUEST_OUTPUT_FILE_DIR = RAILS_ROOT + '/data/test_request/output'
84 TEST_REQUEST_OUTPUT_FILE_DIR = RAILS_ROOT + '/data/test_request/output'
85
85
86 # To use ANALYSIS MODE, provide the testcases/testruns breakdown,
86 # To use ANALYSIS MODE, provide the testcases/testruns breakdown,
87 # and the directory of the grading result (usually in judge's dir).
87 # and the directory of the grading result (usually in judge's dir).
88 TASK_GRADING_INFO_FILENAME = RAILS_ROOT + '/config/tasks.yml'
88 TASK_GRADING_INFO_FILENAME = RAILS_ROOT + '/config/tasks.yml'
89
89
90 # TODO: change this to where results are kept.
90 # TODO: change this to where results are kept.
91 GRADING_RESULT_DIR = 'RESULT-DIR'
91 GRADING_RESULT_DIR = 'RESULT-DIR'
92
92
93 # Change this to allow importing testdata into database as test-pairs.
93 # Change this to allow importing testdata into database as test-pairs.
94 # This is mainly for Code Jom contest.
94 # This is mainly for Code Jom contest.
95 ALLOW_TEST_PAIR_IMPORT = false
95 ALLOW_TEST_PAIR_IMPORT = false
96
96
97 # Uncomment so that the system validates user e-mails
97 # Uncomment so that the system validates user e-mails
98 # VALIDATE_USER_EMAILS = true
98 # VALIDATE_USER_EMAILS = true
99
99
100 # Uncomment so that Apache X-Sendfile is used when delivering files
100 # Uncomment so that Apache X-Sendfile is used when delivering files
101 # (e.g., in /tasks/view).
101 # (e.g., in /tasks/view).
102 # USE_APACHE_XSENDFILE = true
102 # USE_APACHE_XSENDFILE = true
103
103
104 # Uncomment so that configuration is read only once when the server is loaded
104 # Uncomment so that configuration is read only once when the server is loaded
105 # Configuration.enable_caching
105 # Configuration.enable_caching
106 +
107 + # OPTIONS FOR CODE JOM
108 + # --------------------
109 + CODEJOM_MAX_ALIVE_LEVEL = 10
@@ -1,48 +1,56
1 # This file is auto-generated from the current state of the database. Instead of editing this file,
1 # This file is auto-generated from the current state of the database. Instead of editing this file,
2 # please use the migrations feature of Active Record to incrementally modify your database, and
2 # please use the migrations feature of Active Record to incrementally modify your database, and
3 # then regenerate this schema definition.
3 # then regenerate this schema definition.
4 #
4 #
5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
6 # to create the application database on another system, you should be using db:schema:load, not running
6 # to create the application database on another system, you should be using db:schema:load, not running
7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
8 # you'll amass, the slower it'll run and the greater likelihood for issues).
8 # you'll amass, the slower it'll run and the greater likelihood for issues).
9 #
9 #
10 # It's strongly recommended to check this file into your version control system.
10 # It's strongly recommended to check this file into your version control system.
11
11
12 - ActiveRecord::Schema.define(:version => 20100124054458) do
12 + ActiveRecord::Schema.define(:version => 20100124191250) do
13
13
14 create_table "announcements", :force => true do |t|
14 create_table "announcements", :force => true do |t|
15 t.string "author"
15 t.string "author"
16 t.text "body"
16 t.text "body"
17 t.boolean "published"
17 t.boolean "published"
18 t.datetime "created_at"
18 t.datetime "created_at"
19 t.datetime "updated_at"
19 t.datetime "updated_at"
20 t.boolean "frontpage", :default => false
20 t.boolean "frontpage", :default => false
21 t.boolean "contest_only", :default => false
21 t.boolean "contest_only", :default => false
22 t.string "title"
22 t.string "title"
23 end
23 end
24
24
25 + create_table "codejom_statuses", :force => true do |t|
26 + t.integer "user_id"
27 + t.boolean "alive"
28 + t.integer "num_problems_passed"
29 + t.datetime "created_at"
30 + t.datetime "updated_at"
31 + end
32 +
25 create_table "configurations", :force => true do |t|
33 create_table "configurations", :force => true do |t|
26 t.string "key"
34 t.string "key"
27 t.string "value_type"
35 t.string "value_type"
28 t.string "value"
36 t.string "value"
29 t.datetime "created_at"
37 t.datetime "created_at"
30 t.datetime "updated_at"
38 t.datetime "updated_at"
31 t.text "description"
39 t.text "description"
32 end
40 end
33
41
34 create_table "countries", :force => true do |t|
42 create_table "countries", :force => true do |t|
35 t.string "name"
43 t.string "name"
36 t.datetime "created_at"
44 t.datetime "created_at"
37 t.datetime "updated_at"
45 t.datetime "updated_at"
38 end
46 end
39
47
40 create_table "descriptions", :force => true do |t|
48 create_table "descriptions", :force => true do |t|
41 t.text "body"
49 t.text "body"
42 t.boolean "markdowned"
50 t.boolean "markdowned"
43 t.datetime "created_at"
51 t.datetime "created_at"
44 t.datetime "updated_at"
52 t.datetime "updated_at"
45 end
53 end
46
54
47 create_table "grader_processes", :force => true do |t|
55 create_table "grader_processes", :force => true do |t|
48 t.string "host", :limit => 20
56 t.string "host", :limit => 20
You need to be logged in to leave comments. Login now