Description:
created join tables for contests and users and problems
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r268:5fffb74cc182 - - 6 files changed: 42 inserted, 1 deleted

@@ -0,0 +1,12
1 + class CreateContestsUsersJoinTable < ActiveRecord::Migration
2 + def self.up
3 + create_table :contests_users, :id => false do |t|
4 + t.integer :contest_id
5 + t.integer :user_id
6 + end
7 + end
8 +
9 + def self.down
10 + drop_table :contests_users
11 + end
12 + end
@@ -0,0 +1,12
1 + class CreateContestsProblemsJoinTable < ActiveRecord::Migration
2 + def self.up
3 + create_table :contests_problems, :id => false do |t|
4 + t.integer :contest_id
5 + t.integer :problem_id
6 + end
7 + end
8 +
9 + def self.down
10 + drop_table :contests_problems
11 + end
12 + end
@@ -1,2 +1,6
1 1 class Contest < ActiveRecord::Base
2 +
3 + has_and_belongs_to_many :users
4 + has_and_belongs_to_many :problems
5 +
2 6 end
@@ -1,101 +1,102
1 1 class Problem < ActiveRecord::Base
2 2
3 3 belongs_to :description
4 + has_and_belongs_to_many :contests
4 5 has_many :test_pairs, :dependent => :delete_all
5 6
6 7 validates_presence_of :name
7 8 validates_format_of :name, :with => /^\w+$/
8 9 validates_presence_of :full_name
9 10
10 11 DEFAULT_TIME_LIMIT = 1
11 12 DEFAULT_MEMORY_LIMIT = 32
12 13
13 14 def self.find_available_problems
14 15 find(:all, :conditions => {:available => true}, :order => "date_added DESC")
15 16 end
16 17
17 18 def self.create_from_import_form_params(params, old_problem=nil)
18 19 problem = old_problem || Problem.new
19 20 import_params = Problem.extract_params_and_check(params, problem)
20 21
21 22 if not problem.valid?
22 23 return problem, 'Error importing'
23 24 end
24 25
25 26 problem.full_score = 100
26 27 problem.date_added = Time.new
27 28 problem.test_allowed = true
28 29 problem.output_only = false
29 30 problem.available = false
30 31
31 32 if not problem.save
32 33 return problem, 'Error importing'
33 34 end
34 35
35 36 import_to_db = params.has_key? :import_to_db
36 37
37 38 importer = TestdataImporter.new(problem)
38 39
39 40 if not importer.import_from_file(import_params[:file],
40 41 import_params[:time_limit],
41 42 import_params[:memory_limit],
42 43 import_to_db)
43 44 problem.errors.add_to_base('Import error.')
44 45 end
45 46
46 47 return problem, importer.log_msg
47 48 end
48 49
49 50 protected
50 51
51 52 def self.to_i_or_default(st, default)
52 53 if st!=''
53 54 st.to_i
54 55 else
55 56 default
56 57 end
57 58 end
58 59
59 60 def self.extract_params_and_check(params, problem)
60 61 time_limit = Problem.to_i_or_default(params[:time_limit],
61 62 DEFAULT_TIME_LIMIT)
62 63 memory_limit = Problem.to_i_or_default(params[:memory_limit],
63 64 DEFAULT_MEMORY_LIMIT)
64 65
65 66 if time_limit==0 and time_limit_s!='0'
66 67 problem.errors.add_to_base('Time limit format errors.')
67 68 elsif time_limit<=0 or time_limit >60
68 69 problem.errors.add_to_base('Time limit out of range.')
69 70 end
70 71
71 72 if memory_limit==0 and memory_limit_s!='0'
72 73 problem.errors.add_to_base('Memory limit format errors.')
73 74 elsif memory_limit<=0 or memory_limit >512
74 75 problem.errors.add_to_base('Memory limit out of range.')
75 76 end
76 77
77 78 if params[:file]==nil or params[:file]==''
78 79 problem.errors.add_to_base('No testdata file.')
79 80 end
80 81
81 82 file = params[:file]
82 83
83 84 if problem.errors.length!=0
84 85 return problem
85 86 end
86 87
87 88 problem.name = params[:name]
88 89 if params[:full_name]!=''
89 90 problem.full_name = params[:full_name]
90 91 else
91 92 problem.full_name = params[:name]
92 93 end
93 94
94 95 return {
95 96 :time_limit => time_limit,
96 97 :memory_limit => memory_limit,
97 98 :file => file
98 99 }
99 100 end
100 101
101 102 end
@@ -1,224 +1,226
1 1 require 'digest/sha1'
2 2
3 3 class User < ActiveRecord::Base
4 4
5 5 has_and_belongs_to_many :roles
6 6
7 7 has_many :test_requests, :order => "submitted_at DESC"
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_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
20 20
21 21 belongs_to :site
22 22 belongs_to :country
23 23
24 + has_and_belongs_to_many :contests
25 +
24 26 named_scope :activated_users, :conditions => {:activated => true}
25 27
26 28 validates_presence_of :login
27 29 validates_uniqueness_of :login
28 30 validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
29 31 validates_length_of :login, :within => 3..30
30 32
31 33 validates_presence_of :full_name
32 34 validates_length_of :full_name, :minimum => 1
33 35
34 36 validates_presence_of :password, :if => :password_required?
35 37 validates_length_of :password, :within => 4..20, :if => :password_required?
36 38 validates_confirmation_of :password, :if => :password_required?
37 39
38 40 validates_format_of :email,
39 41 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
40 42 :if => :email_validation?
41 43 validate :uniqueness_of_email_from_activated_users,
42 44 :if => :email_validation?
43 45 validate :enough_time_interval_between_same_email_registrations,
44 46 :if => :email_validation?
45 47
46 48 # these are for ytopc
47 49 # disable for now
48 50 #validates_presence_of :province
49 51
50 52 attr_accessor :password
51 53
52 54 before_save :encrypt_new_password
53 55 before_save :assign_default_site
54 56
55 57 def self.authenticate(login, password)
56 58 user = find_by_login(login)
57 59 return user if user && user.authenticated?(password)
58 60 end
59 61
60 62 def authenticated?(password)
61 63 if self.activated
62 64 hashed_password == User.encrypt(password,self.salt)
63 65 else
64 66 false
65 67 end
66 68 end
67 69
68 70 def admin?
69 71 self.roles.detect {|r| r.name == 'admin' }
70 72 end
71 73
72 74 def email_for_editing
73 75 if self.email==nil
74 76 "(unknown)"
75 77 elsif self.email==''
76 78 "(blank)"
77 79 else
78 80 self.email
79 81 end
80 82 end
81 83
82 84 def email_for_editing=(e)
83 85 self.email=e
84 86 end
85 87
86 88 def alias_for_editing
87 89 if self.alias==nil
88 90 "(unknown)"
89 91 elsif self.alias==''
90 92 "(blank)"
91 93 else
92 94 self.alias
93 95 end
94 96 end
95 97
96 98 def alias_for_editing=(e)
97 99 self.alias=e
98 100 end
99 101
100 102 def activation_key
101 103 if self.hashed_password==nil
102 104 encrypt_new_password
103 105 end
104 106 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
105 107 end
106 108
107 109 def verify_activation_key(key)
108 110 key == activation_key
109 111 end
110 112
111 113 def self.random_password(length=5)
112 114 chars = 'abcdefghjkmnopqrstuvwxyz'
113 115 password = ''
114 116 length.times { password << chars[rand(chars.length - 1)] }
115 117 password
116 118 end
117 119
118 120 def self.find_non_admin_with_prefix(prefix='')
119 121 users = User.find(:all)
120 122 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
121 123 end
122 124
123 125 # Contest information
124 126
125 127 def contest_time_left
126 128 if Configuration.contest_mode?
127 129 return nil if site==nil
128 130 return site.time_left
129 131 elsif Configuration.indv_contest_mode?
130 132 time_limit = Configuration.contest_time_limit
131 133 if contest_stat==nil
132 134 return (Time.now.gmtime + time_limit) - Time.now.gmtime
133 135 else
134 136 finish_time = contest_stat.started_at + time_limit
135 137 current_time = Time.now.gmtime
136 138 if current_time > finish_time
137 139 return 0
138 140 else
139 141 return finish_time - current_time
140 142 end
141 143 end
142 144 else
143 145 return nil
144 146 end
145 147 end
146 148
147 149 def contest_finished?
148 150 if Configuration.contest_mode?
149 151 return false if site==nil
150 152 return site.finished?
151 153 elsif Configuration.indv_contest_mode?
152 154 time_limit = Configuration.contest_time_limit
153 155
154 156 return false if contest_stat==nil
155 157
156 158 return contest_time_left == 0
157 159 else
158 160 return false
159 161 end
160 162 end
161 163
162 164 def contest_started?
163 165 if Configuration.contest_mode?
164 166 return true if site==nil
165 167 return site.started
166 168 else
167 169 return true
168 170 end
169 171 end
170 172
171 173 protected
172 174 def encrypt_new_password
173 175 return if password.blank?
174 176 self.salt = (10+rand(90)).to_s
175 177 self.hashed_password = User.encrypt(self.password,self.salt)
176 178 end
177 179
178 180 def assign_default_site
179 181 # have to catch error when migrating (because self.site is not available).
180 182 begin
181 183 if self.site==nil
182 184 self.site = Site.find_by_name('default')
183 185 if self.site==nil
184 186 self.site = Site.find(1) # when 'default has be renamed'
185 187 end
186 188 end
187 189 rescue
188 190 end
189 191 end
190 192
191 193 def password_required?
192 194 self.hashed_password.blank? || !self.password.blank?
193 195 end
194 196
195 197 def self.encrypt(string,salt)
196 198 Digest::SHA1.hexdigest(salt + string)
197 199 end
198 200
199 201 def uniqueness_of_email_from_activated_users
200 202 user = User.activated_users.find_by_email(self.email)
201 203 if user and (user.login != self.login)
202 204 self.errors.add_to_base("Email has already been taken")
203 205 end
204 206 end
205 207
206 208 def enough_time_interval_between_same_email_registrations
207 209 return if !self.new_record?
208 210 return if self.activated
209 211 open_user = User.find_by_email(self.email,
210 212 :order => 'created_at DESC')
211 213 if open_user and open_user.created_at and
212 214 (open_user.created_at > Time.now.gmtime - 5.minutes)
213 215 self.errors.add_to_base("There are already unactivated registrations with this e-mail address (please wait for 5 minutes)")
214 216 end
215 217 end
216 218
217 219 def email_validation?
218 220 begin
219 221 return VALIDATE_USER_EMAILS
220 222 rescue
221 223 return false
222 224 end
223 225 end
224 226 end
@@ -1,260 +1,270
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 => 20100216105730) do
12 + ActiveRecord::Schema.define(:version => 20100216162940) 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
25 25 create_table "codejom_statuses", :force => true do |t|
26 26 t.integer "user_id"
27 27 t.boolean "alive"
28 28 t.integer "num_problems_passed"
29 29 t.datetime "created_at"
30 30 t.datetime "updated_at"
31 31 end
32 32
33 33 create_table "configurations", :force => true do |t|
34 34 t.string "key"
35 35 t.string "value_type"
36 36 t.string "value"
37 37 t.datetime "created_at"
38 38 t.datetime "updated_at"
39 39 t.text "description"
40 40 end
41 41
42 42 create_table "contests", :force => true do |t|
43 43 t.string "title"
44 44 t.boolean "enabled"
45 45 t.datetime "created_at"
46 46 t.datetime "updated_at"
47 47 end
48 48
49 + create_table "contests_problems", :id => false, :force => true do |t|
50 + t.integer "contest_id"
51 + t.integer "problem_id"
52 + end
53 +
54 + create_table "contests_users", :id => false, :force => true do |t|
55 + t.integer "contest_id"
56 + t.integer "user_id"
57 + end
58 +
49 59 create_table "countries", :force => true do |t|
50 60 t.string "name"
51 61 t.datetime "created_at"
52 62 t.datetime "updated_at"
53 63 end
54 64
55 65 create_table "descriptions", :force => true do |t|
56 66 t.text "body"
57 67 t.boolean "markdowned"
58 68 t.datetime "created_at"
59 69 t.datetime "updated_at"
60 70 end
61 71
62 72 create_table "grader_processes", :force => true do |t|
63 73 t.string "host", :limit => 20
64 74 t.integer "pid"
65 75 t.string "mode"
66 76 t.boolean "active"
67 77 t.datetime "created_at"
68 78 t.datetime "updated_at"
69 79 t.integer "task_id"
70 80 t.string "task_type"
71 81 t.boolean "terminated"
72 82 end
73 83
74 84 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
75 85
76 86 create_table "languages", :force => true do |t|
77 87 t.string "name", :limit => 10
78 88 t.string "pretty_name"
79 89 t.string "ext", :limit => 10
80 90 t.string "common_ext"
81 91 end
82 92
83 93 create_table "messages", :force => true do |t|
84 94 t.integer "sender_id"
85 95 t.integer "receiver_id"
86 96 t.integer "replying_message_id"
87 97 t.text "body"
88 98 t.boolean "replied"
89 99 t.datetime "created_at"
90 100 t.datetime "updated_at"
91 101 end
92 102
93 103 create_table "problems", :force => true do |t|
94 104 t.string "name", :limit => 30
95 105 t.string "full_name"
96 106 t.integer "full_score"
97 107 t.date "date_added"
98 108 t.boolean "available"
99 109 t.string "url"
100 110 t.integer "description_id"
101 111 t.boolean "test_allowed"
102 112 t.boolean "output_only"
103 113 t.integer "level", :default => 0
104 114 t.datetime "updated_at"
105 115 end
106 116
107 117 create_table "rights", :force => true do |t|
108 118 t.string "name"
109 119 t.string "controller"
110 120 t.string "action"
111 121 end
112 122
113 123 create_table "rights_roles", :id => false, :force => true do |t|
114 124 t.integer "right_id"
115 125 t.integer "role_id"
116 126 end
117 127
118 128 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
119 129
120 130 create_table "roles", :force => true do |t|
121 131 t.string "name"
122 132 end
123 133
124 134 create_table "roles_users", :id => false, :force => true do |t|
125 135 t.integer "role_id"
126 136 t.integer "user_id"
127 137 end
128 138
129 139 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
130 140
131 141 create_table "sessions", :force => true do |t|
132 142 t.string "session_id"
133 143 t.text "data"
134 144 t.datetime "updated_at"
135 145 end
136 146
137 147 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
138 148 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
139 149
140 150 create_table "sites", :force => true do |t|
141 151 t.string "name"
142 152 t.boolean "started"
143 153 t.datetime "start_time"
144 154 t.datetime "created_at"
145 155 t.datetime "updated_at"
146 156 t.integer "country_id"
147 157 t.string "password"
148 158 end
149 159
150 160 create_table "submission_statuses", :force => true do |t|
151 161 t.integer "user_id"
152 162 t.integer "problem_id"
153 163 t.boolean "passed"
154 164 t.integer "submission_count"
155 165 t.datetime "created_at"
156 166 t.datetime "updated_at"
157 167 end
158 168
159 169 create_table "submissions", :force => true do |t|
160 170 t.integer "user_id"
161 171 t.integer "problem_id"
162 172 t.integer "language_id"
163 173 t.text "source"
164 174 t.binary "binary"
165 175 t.datetime "submitted_at"
166 176 t.datetime "compiled_at"
167 177 t.text "compiler_message"
168 178 t.datetime "graded_at"
169 179 t.integer "points"
170 180 t.text "grader_comment"
171 181 t.integer "number"
172 182 t.string "source_filename"
173 183 end
174 184
175 185 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
176 186 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
177 187
178 188 create_table "tasks", :force => true do |t|
179 189 t.integer "submission_id"
180 190 t.datetime "created_at"
181 191 t.integer "status"
182 192 t.datetime "updated_at"
183 193 end
184 194
185 195 create_table "test_pair_assignments", :force => true do |t|
186 196 t.integer "user_id"
187 197 t.integer "problem_id"
188 198 t.integer "test_pair_id"
189 199 t.integer "test_pair_number"
190 200 t.integer "request_number"
191 201 t.datetime "created_at"
192 202 t.datetime "updated_at"
193 203 t.boolean "submitted"
194 204 end
195 205
196 206 create_table "test_pairs", :force => true do |t|
197 207 t.integer "problem_id"
198 208 t.text "input", :limit => 16777215
199 209 t.text "solution", :limit => 16777215
200 210 t.datetime "created_at"
201 211 t.datetime "updated_at"
202 212 t.integer "number"
203 213 end
204 214
205 215 create_table "test_requests", :force => true do |t|
206 216 t.integer "user_id"
207 217 t.integer "problem_id"
208 218 t.integer "submission_id"
209 219 t.string "input_file_name"
210 220 t.string "output_file_name"
211 221 t.string "running_stat"
212 222 t.integer "status"
213 223 t.datetime "updated_at"
214 224 t.datetime "submitted_at"
215 225 t.datetime "compiled_at"
216 226 t.text "compiler_message"
217 227 t.datetime "graded_at"
218 228 t.string "grader_comment"
219 229 t.datetime "created_at"
220 230 t.float "running_time"
221 231 t.string "exit_status"
222 232 t.integer "memory_usage"
223 233 end
224 234
225 235 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
226 236
227 237 create_table "user_contest_stats", :force => true do |t|
228 238 t.integer "user_id"
229 239 t.datetime "started_at"
230 240 t.datetime "created_at"
231 241 t.datetime "updated_at"
232 242 end
233 243
234 244 create_table "users", :force => true do |t|
235 245 t.string "login", :limit => 50
236 246 t.string "full_name"
237 247 t.string "hashed_password"
238 248 t.string "salt", :limit => 5
239 249 t.string "alias"
240 250 t.string "email"
241 251 t.integer "site_id"
242 252 t.integer "country_id"
243 253 t.boolean "activated", :default => false
244 254 t.datetime "created_at"
245 255 t.datetime "updated_at"
246 256 t.string "member1_full_name"
247 257 t.string "member2_full_name"
248 258 t.string "member3_full_name"
249 259 t.boolean "high_school"
250 260 t.string "member1_school_name"
251 261 t.string "member2_school_name"
252 262 t.string "member3_school_name"
253 263 t.string "school_name"
254 264 t.string "province"
255 265 t.integer "year"
256 266 end
257 267
258 268 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
259 269
260 270 end
You need to be logged in to leave comments. Login now