Description:
fix error when problem.full_score is nil. More has to be done to prevent problem.full_score being nil
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r523:e5c66a78e3f9 - - 2 files changed: 13 inserted, 12 deleted

@@ -1,536 +1,536
1 require 'csv'
1 require 'csv'
2
2
3 class UserAdminController < ApplicationController
3 class UserAdminController < ApplicationController
4
4
5 include MailHelperMethods
5 include MailHelperMethods
6
6
7 before_filter :admin_authorization
7 before_filter :admin_authorization
8
8
9 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
9 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
10 verify :method => :post, :only => [ :destroy,
10 verify :method => :post, :only => [ :destroy,
11 :create, :create_from_list,
11 :create, :create_from_list,
12 :update,
12 :update,
13 :manage_contest,
13 :manage_contest,
14 :bulk_mail
14 :bulk_mail
15 ],
15 ],
16 :redirect_to => { :action => :list }
16 :redirect_to => { :action => :list }
17
17
18 def index
18 def index
19 list
19 list
20 render :action => 'list'
20 render :action => 'list'
21 end
21 end
22
22
23 def list
23 def list
24 @user_count = User.count
24 @user_count = User.count
25 if params[:page] == 'all'
25 if params[:page] == 'all'
26 @users = User.all
26 @users = User.all
27 @paginated = false
27 @paginated = false
28 else
28 else
29 @users = User.paginate :page => params[:page]
29 @users = User.paginate :page => params[:page]
30 @paginated = true
30 @paginated = true
31 end
31 end
32 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
32 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
33 @contests = Contest.enabled
33 @contests = Contest.enabled
34 end
34 end
35
35
36 def active
36 def active
37 sessions = ActiveRecord::SessionStore::Session.find(:all, :conditions => ["updated_at >= ?", 60.minutes.ago])
37 sessions = ActiveRecord::SessionStore::Session.find(:all, :conditions => ["updated_at >= ?", 60.minutes.ago])
38 @users = []
38 @users = []
39 sessions.each do |session|
39 sessions.each do |session|
40 if session.data[:user_id]
40 if session.data[:user_id]
41 @users << User.find(session.data[:user_id])
41 @users << User.find(session.data[:user_id])
42 end
42 end
43 end
43 end
44 end
44 end
45
45
46 def show
46 def show
47 @user = User.find(params[:id])
47 @user = User.find(params[:id])
48 end
48 end
49
49
50 def new
50 def new
51 @user = User.new
51 @user = User.new
52 end
52 end
53
53
54 def create
54 def create
55 @user = User.new(params[:user])
55 @user = User.new(params[:user])
56 @user.activated = true
56 @user.activated = true
57 if @user.save
57 if @user.save
58 flash[:notice] = 'User was successfully created.'
58 flash[:notice] = 'User was successfully created.'
59 redirect_to :action => 'list'
59 redirect_to :action => 'list'
60 else
60 else
61 render :action => 'new'
61 render :action => 'new'
62 end
62 end
63 end
63 end
64
64
65 def create_from_list
65 def create_from_list
66 lines = params[:user_list]
66 lines = params[:user_list]
67
67
68 note = []
68 note = []
69
69
70 lines.split("\n").each do |line|
70 lines.split("\n").each do |line|
71 items = line.chomp.split(',')
71 items = line.chomp.split(',')
72 if items.length>=2
72 if items.length>=2
73 login = items[0]
73 login = items[0]
74 full_name = items[1]
74 full_name = items[1]
75
75
76 added_random_password = false
76 added_random_password = false
77 if items.length>=3
77 if items.length>=3
78 password = items[2].chomp(" ")
78 password = items[2].chomp(" ")
79 user_alias = (items.length>=4) ? items[3] : login
79 user_alias = (items.length>=4) ? items[3] : login
80 else
80 else
81 password = random_password
81 password = random_password
82 user_alias = (items.length>=4) ? items[3] : login
82 user_alias = (items.length>=4) ? items[3] : login
83 added_random_password = true
83 added_random_password = true
84 end
84 end
85
85
86 user = User.find_by_login(login)
86 user = User.find_by_login(login)
87 if (user)
87 if (user)
88 user.full_name = full_name
88 user.full_name = full_name
89 user.password = password
89 user.password = password
90 else
90 else
91 user = User.new({:login => login,
91 user = User.new({:login => login,
92 :full_name => full_name,
92 :full_name => full_name,
93 :password => password,
93 :password => password,
94 :password_confirmation => password,
94 :password_confirmation => password,
95 :alias => user_alias})
95 :alias => user_alias})
96 end
96 end
97 user.activated = true
97 user.activated = true
98 user.save
98 user.save
99
99
100 if added_random_password
100 if added_random_password
101 note << "'#{login}' (+)"
101 note << "'#{login}' (+)"
102 else
102 else
103 note << login
103 note << login
104 end
104 end
105 end
105 end
106 end
106 end
107 flash[:notice] = 'User(s) ' + note.join(', ') +
107 flash[:notice] = 'User(s) ' + note.join(', ') +
108 ' were successfully created. ' +
108 ' were successfully created. ' +
109 '( (+) - created with random passwords.)'
109 '( (+) - created with random passwords.)'
110 redirect_to :action => 'list'
110 redirect_to :action => 'list'
111 end
111 end
112
112
113 def edit
113 def edit
114 @user = User.find(params[:id])
114 @user = User.find(params[:id])
115 end
115 end
116
116
117 def update
117 def update
118 @user = User.find(params[:id])
118 @user = User.find(params[:id])
119 if @user.update_attributes(params[:user])
119 if @user.update_attributes(params[:user])
120 flash[:notice] = 'User was successfully updated.'
120 flash[:notice] = 'User was successfully updated.'
121 redirect_to :action => 'show', :id => @user
121 redirect_to :action => 'show', :id => @user
122 else
122 else
123 render :action => 'edit'
123 render :action => 'edit'
124 end
124 end
125 end
125 end
126
126
127 def destroy
127 def destroy
128 User.find(params[:id]).destroy
128 User.find(params[:id]).destroy
129 redirect_to :action => 'list'
129 redirect_to :action => 'list'
130 end
130 end
131
131
132 def user_stat
132 def user_stat
133 if params[:commit] == 'download csv'
133 if params[:commit] == 'download csv'
134 @problems = Problem.all
134 @problems = Problem.all
135 else
135 else
136 @problems = Problem.find_available_problems
136 @problems = Problem.find_available_problems
137 end
137 end
138 @users = User.find(:all, :include => [:contests, :contest_stat])
138 @users = User.find(:all, :include => [:contests, :contest_stat])
139 @scorearray = Array.new
139 @scorearray = Array.new
140 @users.each do |u|
140 @users.each do |u|
141 ustat = Array.new
141 ustat = Array.new
142 ustat[0] = u
142 ustat[0] = u
143 @problems.each do |p|
143 @problems.each do |p|
144 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
144 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
145 - if (sub!=nil) and (sub.points!=nil)
145 + if (sub!=nil) and (sub.points!=nil) and p and p.full_score
146 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
146 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
147 else
147 else
148 ustat << [0,false]
148 ustat << [0,false]
149 end
149 end
150 end
150 end
151 @scorearray << ustat
151 @scorearray << ustat
152 end
152 end
153 if params[:commit] == 'download csv' then
153 if params[:commit] == 'download csv' then
154 csv = gen_csv_from_scorearray(@scorearray,@problems)
154 csv = gen_csv_from_scorearray(@scorearray,@problems)
155 send_data csv, filename: 'last_score.csv'
155 send_data csv, filename: 'last_score.csv'
156 else
156 else
157 render template: 'user_admin/user_stat'
157 render template: 'user_admin/user_stat'
158 end
158 end
159 end
159 end
160
160
161 def user_stat_max
161 def user_stat_max
162 if params[:commit] == 'download csv'
162 if params[:commit] == 'download csv'
163 @problems = Problem.all
163 @problems = Problem.all
164 else
164 else
165 @problems = Problem.find_available_problems
165 @problems = Problem.find_available_problems
166 end
166 end
167 @users = User.find(:all, :include => [:contests, :contest_stat])
167 @users = User.find(:all, :include => [:contests, :contest_stat])
168 @scorearray = Array.new
168 @scorearray = Array.new
169 #set up range from param
169 #set up range from param
170 since_id = params.fetch(:since_id, 0).to_i
170 since_id = params.fetch(:since_id, 0).to_i
171 until_id = params.fetch(:until_id, 0).to_i
171 until_id = params.fetch(:until_id, 0).to_i
172 @users.each do |u|
172 @users.each do |u|
173 ustat = Array.new
173 ustat = Array.new
174 ustat[0] = u
174 ustat[0] = u
175 @problems.each do |p|
175 @problems.each do |p|
176 max_points = 0
176 max_points = 0
177 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
177 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
178 max_points = sub.points if sub and sub.points and (sub.points > max_points)
178 max_points = sub.points if sub and sub.points and (sub.points > max_points)
179 end
179 end
180 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
180 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
181 end
181 end
182 @scorearray << ustat
182 @scorearray << ustat
183 end
183 end
184
184
185 if params[:commit] == 'download csv' then
185 if params[:commit] == 'download csv' then
186 csv = gen_csv_from_scorearray(@scorearray,@problems)
186 csv = gen_csv_from_scorearray(@scorearray,@problems)
187 send_data csv, filename: 'max_score.csv'
187 send_data csv, filename: 'max_score.csv'
188 else
188 else
189 render template: 'user_admin/user_stat'
189 render template: 'user_admin/user_stat'
190 end
190 end
191 end
191 end
192
192
193 def import
193 def import
194 if params[:file]==''
194 if params[:file]==''
195 flash[:notice] = 'Error importing no file'
195 flash[:notice] = 'Error importing no file'
196 redirect_to :action => 'list' and return
196 redirect_to :action => 'list' and return
197 end
197 end
198 import_from_file(params[:file])
198 import_from_file(params[:file])
199 end
199 end
200
200
201 def random_all_passwords
201 def random_all_passwords
202 users = User.find(:all)
202 users = User.find(:all)
203 @prefix = params[:prefix] || ''
203 @prefix = params[:prefix] || ''
204 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
204 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
205 @changed = false
205 @changed = false
206 if request.request_method == 'POST'
206 if request.request_method == 'POST'
207 @non_admin_users.each do |user|
207 @non_admin_users.each do |user|
208 password = random_password
208 password = random_password
209 user.password = password
209 user.password = password
210 user.password_confirmation = password
210 user.password_confirmation = password
211 user.save
211 user.save
212 end
212 end
213 @changed = true
213 @changed = true
214 end
214 end
215 end
215 end
216
216
217 # contest management
217 # contest management
218
218
219 def contests
219 def contests
220 @contest, @users = find_contest_and_user_from_contest_id(params[:id])
220 @contest, @users = find_contest_and_user_from_contest_id(params[:id])
221 @contests = Contest.enabled
221 @contests = Contest.enabled
222 end
222 end
223
223
224 def assign_from_list
224 def assign_from_list
225 contest_id = params[:users_contest_id]
225 contest_id = params[:users_contest_id]
226 org_contest, users = find_contest_and_user_from_contest_id(contest_id)
226 org_contest, users = find_contest_and_user_from_contest_id(contest_id)
227 contest = Contest.find(params[:new_contest][:id])
227 contest = Contest.find(params[:new_contest][:id])
228 if !contest
228 if !contest
229 flash[:notice] = 'Error: no contest'
229 flash[:notice] = 'Error: no contest'
230 redirect_to :action => 'contests', :id =>contest_id
230 redirect_to :action => 'contests', :id =>contest_id
231 end
231 end
232
232
233 note = []
233 note = []
234 users.each do |u|
234 users.each do |u|
235 u.contests = [contest]
235 u.contests = [contest]
236 note << u.login
236 note << u.login
237 end
237 end
238 flash[:notice] = 'User(s) ' + note.join(', ') +
238 flash[:notice] = 'User(s) ' + note.join(', ') +
239 " were successfully reassigned to #{contest.title}."
239 " were successfully reassigned to #{contest.title}."
240 redirect_to :action => 'contests', :id =>contest.id
240 redirect_to :action => 'contests', :id =>contest.id
241 end
241 end
242
242
243 def add_to_contest
243 def add_to_contest
244 user = User.find(params[:id])
244 user = User.find(params[:id])
245 contest = Contest.find(params[:contest_id])
245 contest = Contest.find(params[:contest_id])
246 if user and contest
246 if user and contest
247 user.contests << contest
247 user.contests << contest
248 end
248 end
249 redirect_to :action => 'list'
249 redirect_to :action => 'list'
250 end
250 end
251
251
252 def remove_from_contest
252 def remove_from_contest
253 user = User.find(params[:id])
253 user = User.find(params[:id])
254 contest = Contest.find(params[:contest_id])
254 contest = Contest.find(params[:contest_id])
255 if user and contest
255 if user and contest
256 user.contests.delete(contest)
256 user.contests.delete(contest)
257 end
257 end
258 redirect_to :action => 'list'
258 redirect_to :action => 'list'
259 end
259 end
260
260
261 def contest_management
261 def contest_management
262 end
262 end
263
263
264 def manage_contest
264 def manage_contest
265 contest = Contest.find(params[:contest][:id])
265 contest = Contest.find(params[:contest][:id])
266 if !contest
266 if !contest
267 flash[:notice] = 'You did not choose the contest.'
267 flash[:notice] = 'You did not choose the contest.'
268 redirect_to :action => 'contest_management' and return
268 redirect_to :action => 'contest_management' and return
269 end
269 end
270
270
271 operation = params[:operation]
271 operation = params[:operation]
272
272
273 if not ['add','remove','assign'].include? operation
273 if not ['add','remove','assign'].include? operation
274 flash[:notice] = 'You did not choose the operation to perform.'
274 flash[:notice] = 'You did not choose the operation to perform.'
275 redirect_to :action => 'contest_management' and return
275 redirect_to :action => 'contest_management' and return
276 end
276 end
277
277
278 lines = params[:login_list]
278 lines = params[:login_list]
279 if !lines or lines.blank?
279 if !lines or lines.blank?
280 flash[:notice] = 'You entered an empty list.'
280 flash[:notice] = 'You entered an empty list.'
281 redirect_to :action => 'contest_management' and return
281 redirect_to :action => 'contest_management' and return
282 end
282 end
283
283
284 note = []
284 note = []
285 users = []
285 users = []
286 lines.split("\n").each do |line|
286 lines.split("\n").each do |line|
287 user = User.find_by_login(line.chomp)
287 user = User.find_by_login(line.chomp)
288 if user
288 if user
289 if operation=='add'
289 if operation=='add'
290 if ! user.contests.include? contest
290 if ! user.contests.include? contest
291 user.contests << contest
291 user.contests << contest
292 end
292 end
293 elsif operation=='remove'
293 elsif operation=='remove'
294 user.contests.delete(contest)
294 user.contests.delete(contest)
295 else
295 else
296 user.contests = [contest]
296 user.contests = [contest]
297 end
297 end
298
298
299 if params[:reset_timer]
299 if params[:reset_timer]
300 user.contest_stat.forced_logout = true
300 user.contest_stat.forced_logout = true
301 user.contest_stat.reset_timer_and_save
301 user.contest_stat.reset_timer_and_save
302 end
302 end
303
303
304 if params[:notification_emails]
304 if params[:notification_emails]
305 send_contest_update_notification_email(user, contest)
305 send_contest_update_notification_email(user, contest)
306 end
306 end
307
307
308 note << user.login
308 note << user.login
309 users << user
309 users << user
310 end
310 end
311 end
311 end
312
312
313 if params[:reset_timer]
313 if params[:reset_timer]
314 logout_users(users)
314 logout_users(users)
315 end
315 end
316
316
317 flash[:notice] = 'User(s) ' + note.join(', ') +
317 flash[:notice] = 'User(s) ' + note.join(', ') +
318 ' were successfully modified. '
318 ' were successfully modified. '
319 redirect_to :action => 'contest_management'
319 redirect_to :action => 'contest_management'
320 end
320 end
321
321
322 # admin management
322 # admin management
323
323
324 def admin
324 def admin
325 @admins = User.find(:all).find_all {|user| user.admin? }
325 @admins = User.find(:all).find_all {|user| user.admin? }
326 end
326 end
327
327
328 def grant_admin
328 def grant_admin
329 login = params[:login]
329 login = params[:login]
330 user = User.find_by_login(login)
330 user = User.find_by_login(login)
331 if user!=nil
331 if user!=nil
332 admin_role = Role.find_by_name('admin')
332 admin_role = Role.find_by_name('admin')
333 user.roles << admin_role
333 user.roles << admin_role
334 else
334 else
335 flash[:notice] = 'Unknown user'
335 flash[:notice] = 'Unknown user'
336 end
336 end
337 flash[:notice] = 'User added as admins'
337 flash[:notice] = 'User added as admins'
338 redirect_to :action => 'admin'
338 redirect_to :action => 'admin'
339 end
339 end
340
340
341 def revoke_admin
341 def revoke_admin
342 user = User.find(params[:id])
342 user = User.find(params[:id])
343 if user==nil
343 if user==nil
344 flash[:notice] = 'Unknown user'
344 flash[:notice] = 'Unknown user'
345 redirect_to :action => 'admin' and return
345 redirect_to :action => 'admin' and return
346 elsif user.login == 'root'
346 elsif user.login == 'root'
347 flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
347 flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
348 redirect_to :action => 'admin' and return
348 redirect_to :action => 'admin' and return
349 end
349 end
350
350
351 admin_role = Role.find_by_name('admin')
351 admin_role = Role.find_by_name('admin')
352 user.roles.delete(admin_role)
352 user.roles.delete(admin_role)
353 flash[:notice] = 'User permission revoked'
353 flash[:notice] = 'User permission revoked'
354 redirect_to :action => 'admin'
354 redirect_to :action => 'admin'
355 end
355 end
356
356
357 # mass mailing
357 # mass mailing
358
358
359 def mass_mailing
359 def mass_mailing
360 end
360 end
361
361
362 def bulk_mail
362 def bulk_mail
363 lines = params[:login_list]
363 lines = params[:login_list]
364 if !lines or lines.blank?
364 if !lines or lines.blank?
365 flash[:notice] = 'You entered an empty list.'
365 flash[:notice] = 'You entered an empty list.'
366 redirect_to :action => 'mass_mailing' and return
366 redirect_to :action => 'mass_mailing' and return
367 end
367 end
368
368
369 mail_subject = params[:subject]
369 mail_subject = params[:subject]
370 if !mail_subject or mail_subject.blank?
370 if !mail_subject or mail_subject.blank?
371 flash[:notice] = 'You entered an empty mail subject.'
371 flash[:notice] = 'You entered an empty mail subject.'
372 redirect_to :action => 'mass_mailing' and return
372 redirect_to :action => 'mass_mailing' and return
373 end
373 end
374
374
375 mail_body = params[:email_body]
375 mail_body = params[:email_body]
376 if !mail_body or mail_body.blank?
376 if !mail_body or mail_body.blank?
377 flash[:notice] = 'You entered an empty mail body.'
377 flash[:notice] = 'You entered an empty mail body.'
378 redirect_to :action => 'mass_mailing' and return
378 redirect_to :action => 'mass_mailing' and return
379 end
379 end
380
380
381 note = []
381 note = []
382 users = []
382 users = []
383 lines.split("\n").each do |line|
383 lines.split("\n").each do |line|
384 user = User.find_by_login(line.chomp)
384 user = User.find_by_login(line.chomp)
385 if user
385 if user
386 send_mail(user.email, mail_subject, mail_body)
386 send_mail(user.email, mail_subject, mail_body)
387 note << user.login
387 note << user.login
388 end
388 end
389 end
389 end
390
390
391 flash[:notice] = 'User(s) ' + note.join(', ') +
391 flash[:notice] = 'User(s) ' + note.join(', ') +
392 ' were successfully modified. '
392 ' were successfully modified. '
393 redirect_to :action => 'mass_mailing'
393 redirect_to :action => 'mass_mailing'
394 end
394 end
395
395
396 protected
396 protected
397
397
398 def random_password(length=5)
398 def random_password(length=5)
399 chars = 'abcdefghijkmnopqrstuvwxyz23456789'
399 chars = 'abcdefghijkmnopqrstuvwxyz23456789'
400 newpass = ""
400 newpass = ""
401 length.times { newpass << chars[rand(chars.size-1)] }
401 length.times { newpass << chars[rand(chars.size-1)] }
402 return newpass
402 return newpass
403 end
403 end
404
404
405 def import_from_file(f)
405 def import_from_file(f)
406 data_hash = YAML.load(f)
406 data_hash = YAML.load(f)
407 @import_log = ""
407 @import_log = ""
408
408
409 country_data = data_hash[:countries]
409 country_data = data_hash[:countries]
410 site_data = data_hash[:sites]
410 site_data = data_hash[:sites]
411 user_data = data_hash[:users]
411 user_data = data_hash[:users]
412
412
413 # import country
413 # import country
414 countries = {}
414 countries = {}
415 country_data.each_pair do |id,country|
415 country_data.each_pair do |id,country|
416 c = Country.find_by_name(country[:name])
416 c = Country.find_by_name(country[:name])
417 if c!=nil
417 if c!=nil
418 countries[id] = c
418 countries[id] = c
419 @import_log << "Found #{country[:name]}\n"
419 @import_log << "Found #{country[:name]}\n"
420 else
420 else
421 countries[id] = Country.new(:name => country[:name])
421 countries[id] = Country.new(:name => country[:name])
422 countries[id].save
422 countries[id].save
423 @import_log << "Created #{country[:name]}\n"
423 @import_log << "Created #{country[:name]}\n"
424 end
424 end
425 end
425 end
426
426
427 # import sites
427 # import sites
428 sites = {}
428 sites = {}
429 site_data.each_pair do |id,site|
429 site_data.each_pair do |id,site|
430 s = Site.find_by_name(site[:name])
430 s = Site.find_by_name(site[:name])
431 if s!=nil
431 if s!=nil
432 @import_log << "Found #{site[:name]}\n"
432 @import_log << "Found #{site[:name]}\n"
433 else
433 else
434 s = Site.new(:name => site[:name])
434 s = Site.new(:name => site[:name])
435 @import_log << "Created #{site[:name]}\n"
435 @import_log << "Created #{site[:name]}\n"
436 end
436 end
437 s.password = site[:password]
437 s.password = site[:password]
438 s.country = countries[site[:country_id]]
438 s.country = countries[site[:country_id]]
439 s.save
439 s.save
440 sites[id] = s
440 sites[id] = s
441 end
441 end
442
442
443 # import users
443 # import users
444 user_data.each_pair do |id,user|
444 user_data.each_pair do |id,user|
445 u = User.find_by_login(user[:login])
445 u = User.find_by_login(user[:login])
446 if u!=nil
446 if u!=nil
447 @import_log << "Found #{user[:login]}\n"
447 @import_log << "Found #{user[:login]}\n"
448 else
448 else
449 u = User.new(:login => user[:login])
449 u = User.new(:login => user[:login])
450 @import_log << "Created #{user[:login]}\n"
450 @import_log << "Created #{user[:login]}\n"
451 end
451 end
452 u.full_name = user[:name]
452 u.full_name = user[:name]
453 u.password = user[:password]
453 u.password = user[:password]
454 u.country = countries[user[:country_id]]
454 u.country = countries[user[:country_id]]
455 u.site = sites[user[:site_id]]
455 u.site = sites[user[:site_id]]
456 u.activated = true
456 u.activated = true
457 u.email = "empty-#{u.login}@none.com"
457 u.email = "empty-#{u.login}@none.com"
458 if not u.save
458 if not u.save
459 @import_log << "Errors\n"
459 @import_log << "Errors\n"
460 u.errors.each { |attr,msg| @import_log << "#{attr} - #{msg}\n" }
460 u.errors.each { |attr,msg| @import_log << "#{attr} - #{msg}\n" }
461 end
461 end
462 end
462 end
463
463
464 end
464 end
465
465
466 def logout_users(users)
466 def logout_users(users)
467 users.each do |user|
467 users.each do |user|
468 contest_stat = user.contest_stat(true)
468 contest_stat = user.contest_stat(true)
469 if contest_stat and !contest_stat.forced_logout
469 if contest_stat and !contest_stat.forced_logout
470 contest_stat.forced_logout = true
470 contest_stat.forced_logout = true
471 contest_stat.save
471 contest_stat.save
472 end
472 end
473 end
473 end
474 end
474 end
475
475
476 def send_contest_update_notification_email(user, contest)
476 def send_contest_update_notification_email(user, contest)
477 contest_title_name = GraderConfiguration['contest.name']
477 contest_title_name = GraderConfiguration['contest.name']
478 contest_name = contest.name
478 contest_name = contest.name
479 mail_subject = t('contest.notification.email_subject', {
479 mail_subject = t('contest.notification.email_subject', {
480 :contest_title_name => contest_title_name,
480 :contest_title_name => contest_title_name,
481 :contest_name => contest_name })
481 :contest_name => contest_name })
482 mail_body = t('contest.notification.email_body', {
482 mail_body = t('contest.notification.email_body', {
483 :full_name => user.full_name,
483 :full_name => user.full_name,
484 :contest_title_name => contest_title_name,
484 :contest_title_name => contest_title_name,
485 :contest_name => contest.name,
485 :contest_name => contest.name,
486 })
486 })
487
487
488 logger.info mail_body
488 logger.info mail_body
489 send_mail(user.email, mail_subject, mail_body)
489 send_mail(user.email, mail_subject, mail_body)
490 end
490 end
491
491
492 def find_contest_and_user_from_contest_id(id)
492 def find_contest_and_user_from_contest_id(id)
493 if id!='none'
493 if id!='none'
494 @contest = Contest.find(id)
494 @contest = Contest.find(id)
495 else
495 else
496 @contest = nil
496 @contest = nil
497 end
497 end
498 if @contest
498 if @contest
499 @users = @contest.users
499 @users = @contest.users
500 else
500 else
501 @users = User.find_users_with_no_contest
501 @users = User.find_users_with_no_contest
502 end
502 end
503 return [@contest, @users]
503 return [@contest, @users]
504 end
504 end
505
505
506 def gen_csv_from_scorearray(scorearray,problem)
506 def gen_csv_from_scorearray(scorearray,problem)
507 CSV.generate do |csv|
507 CSV.generate do |csv|
508 #add header
508 #add header
509 header = ['User','Name', 'Activated?', 'Logged in', 'Contest']
509 header = ['User','Name', 'Activated?', 'Logged in', 'Contest']
510 problem.each { |p| header << p.name }
510 problem.each { |p| header << p.name }
511 header += ['Total','Passed']
511 header += ['Total','Passed']
512 csv << header
512 csv << header
513 #add data
513 #add data
514 scorearray.each do |sc|
514 scorearray.each do |sc|
515 total = num_passed = 0
515 total = num_passed = 0
516 row = Array.new
516 row = Array.new
517 sc.each_index do |i|
517 sc.each_index do |i|
518 if i == 0
518 if i == 0
519 row << sc[i].login
519 row << sc[i].login
520 row << sc[i].full_name
520 row << sc[i].full_name
521 row << sc[i].activated
521 row << sc[i].activated
522 row << (sc[i].try(:contest_stat).try(:started_at)!=nil ? 'yes' : 'no')
522 row << (sc[i].try(:contest_stat).try(:started_at)!=nil ? 'yes' : 'no')
523 row << sc[i].contests.collect {|c| c.name}.join(', ')
523 row << sc[i].contests.collect {|c| c.name}.join(', ')
524 else
524 else
525 row << sc[i][0]
525 row << sc[i][0]
526 total += sc[i][0]
526 total += sc[i][0]
527 num_passed += 1 if sc[i][1]
527 num_passed += 1 if sc[i][1]
528 end
528 end
529 end
529 end
530 row << total
530 row << total
531 row << num_passed
531 row << num_passed
532 csv << row
532 csv << row
533 end
533 end
534 end
534 end
535 end
535 end
536 end
536 end
@@ -1,248 +1,249
1 # encoding: UTF-8
1 # encoding: UTF-8
2 # This file is auto-generated from the current state of the database. Instead
2 # This file is auto-generated from the current state of the database. Instead
3 # of editing this file, please use the migrations feature of Active Record to
3 # of editing this file, please use the migrations feature of Active Record to
4 # incrementally modify your database, and then regenerate this schema definition.
4 # incrementally modify your database, and then regenerate this schema definition.
5 #
5 #
6 # Note that this schema.rb definition is the authoritative source for your
6 # Note that this schema.rb definition is the authoritative source for your
7 # database schema. If you need to create the application database on another
7 # database schema. If you need to create the application database on another
8 # system, you should be using db:schema:load, not running all the migrations
8 # system, you should be using db:schema:load, not running all the migrations
9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10 # you'll amass, the slower it'll run and the greater likelihood for issues).
10 # you'll amass, the slower it'll run and the greater likelihood for issues).
11 #
11 #
12 # It's strongly recommended to check this file into your version control system.
12 # It's strongly recommended to check this file into your version control system.
13
13
14 ActiveRecord::Schema.define(:version => 20150203153534) do
14 ActiveRecord::Schema.define(:version => 20150203153534) do
15
15
16 create_table "announcements", :force => true do |t|
16 create_table "announcements", :force => true do |t|
17 t.string "author"
17 t.string "author"
18 - t.text "body"
18 + t.text "body", :limit => 16777215
19 t.boolean "published"
19 t.boolean "published"
20 t.datetime "created_at", :null => false
20 t.datetime "created_at", :null => false
21 t.datetime "updated_at", :null => false
21 t.datetime "updated_at", :null => false
22 t.boolean "frontpage", :default => false
22 t.boolean "frontpage", :default => false
23 t.boolean "contest_only", :default => false
23 t.boolean "contest_only", :default => false
24 t.string "title"
24 t.string "title"
25 t.string "notes"
25 t.string "notes"
26 end
26 end
27
27
28 create_table "contests", :force => true do |t|
28 create_table "contests", :force => true do |t|
29 t.string "title"
29 t.string "title"
30 t.boolean "enabled"
30 t.boolean "enabled"
31 t.datetime "created_at", :null => false
31 t.datetime "created_at", :null => false
32 t.datetime "updated_at", :null => false
32 t.datetime "updated_at", :null => false
33 t.string "name"
33 t.string "name"
34 end
34 end
35
35
36 create_table "contests_problems", :id => false, :force => true do |t|
36 create_table "contests_problems", :id => false, :force => true do |t|
37 t.integer "contest_id"
37 t.integer "contest_id"
38 t.integer "problem_id"
38 t.integer "problem_id"
39 end
39 end
40
40
41 create_table "contests_users", :id => false, :force => true do |t|
41 create_table "contests_users", :id => false, :force => true do |t|
42 t.integer "contest_id"
42 t.integer "contest_id"
43 t.integer "user_id"
43 t.integer "user_id"
44 end
44 end
45
45
46 create_table "countries", :force => true do |t|
46 create_table "countries", :force => true do |t|
47 t.string "name"
47 t.string "name"
48 t.datetime "created_at", :null => false
48 t.datetime "created_at", :null => false
49 t.datetime "updated_at", :null => false
49 t.datetime "updated_at", :null => false
50 end
50 end
51
51
52 create_table "descriptions", :force => true do |t|
52 create_table "descriptions", :force => true do |t|
53 - t.text "body"
53 + t.text "body", :limit => 16777215
54 t.boolean "markdowned"
54 t.boolean "markdowned"
55 t.datetime "created_at", :null => false
55 t.datetime "created_at", :null => false
56 t.datetime "updated_at", :null => false
56 t.datetime "updated_at", :null => false
57 end
57 end
58
58
59 create_table "grader_configurations", :force => true do |t|
59 create_table "grader_configurations", :force => true do |t|
60 t.string "key"
60 t.string "key"
61 t.string "value_type"
61 t.string "value_type"
62 t.string "value"
62 t.string "value"
63 t.datetime "created_at", :null => false
63 t.datetime "created_at", :null => false
64 t.datetime "updated_at", :null => false
64 t.datetime "updated_at", :null => false
65 - t.text "description"
65 + t.text "description", :limit => 16777215
66 end
66 end
67
67
68 create_table "grader_processes", :force => true do |t|
68 create_table "grader_processes", :force => true do |t|
69 t.string "host", :limit => 20
69 t.string "host", :limit => 20
70 t.integer "pid"
70 t.integer "pid"
71 t.string "mode"
71 t.string "mode"
72 t.boolean "active"
72 t.boolean "active"
73 t.datetime "created_at", :null => false
73 t.datetime "created_at", :null => false
74 t.datetime "updated_at", :null => false
74 t.datetime "updated_at", :null => false
75 t.integer "task_id"
75 t.integer "task_id"
76 t.string "task_type"
76 t.string "task_type"
77 t.boolean "terminated"
77 t.boolean "terminated"
78 end
78 end
79
79
80 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
80 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
81
81
82 create_table "languages", :force => true do |t|
82 create_table "languages", :force => true do |t|
83 t.string "name", :limit => 10
83 t.string "name", :limit => 10
84 t.string "pretty_name"
84 t.string "pretty_name"
85 t.string "ext", :limit => 10
85 t.string "ext", :limit => 10
86 t.string "common_ext"
86 t.string "common_ext"
87 end
87 end
88
88
89 create_table "logins", :force => true do |t|
89 create_table "logins", :force => true do |t|
90 t.string "user_id"
90 t.string "user_id"
91 t.string "ip_address"
91 t.string "ip_address"
92 t.datetime "created_at", :null => false
92 t.datetime "created_at", :null => false
93 t.datetime "updated_at", :null => false
93 t.datetime "updated_at", :null => false
94 end
94 end
95
95
96 create_table "messages", :force => true do |t|
96 create_table "messages", :force => true do |t|
97 t.integer "sender_id"
97 t.integer "sender_id"
98 t.integer "receiver_id"
98 t.integer "receiver_id"
99 t.integer "replying_message_id"
99 t.integer "replying_message_id"
100 - t.text "body"
100 + t.text "body", :limit => 16777215
101 t.boolean "replied"
101 t.boolean "replied"
102 t.datetime "created_at", :null => false
102 t.datetime "created_at", :null => false
103 t.datetime "updated_at", :null => false
103 t.datetime "updated_at", :null => false
104 end
104 end
105
105
106 create_table "problems", :force => true do |t|
106 create_table "problems", :force => true do |t|
107 t.string "name", :limit => 30
107 t.string "name", :limit => 30
108 t.string "full_name"
108 t.string "full_name"
109 t.integer "full_score"
109 t.integer "full_score"
110 t.date "date_added"
110 t.date "date_added"
111 t.boolean "available"
111 t.boolean "available"
112 t.string "url"
112 t.string "url"
113 t.integer "description_id"
113 t.integer "description_id"
114 t.boolean "test_allowed"
114 t.boolean "test_allowed"
115 t.boolean "output_only"
115 t.boolean "output_only"
116 t.string "description_filename"
116 t.string "description_filename"
117 end
117 end
118
118
119 create_table "rights", :force => true do |t|
119 create_table "rights", :force => true do |t|
120 t.string "name"
120 t.string "name"
121 t.string "controller"
121 t.string "controller"
122 t.string "action"
122 t.string "action"
123 end
123 end
124
124
125 create_table "rights_roles", :id => false, :force => true do |t|
125 create_table "rights_roles", :id => false, :force => true do |t|
126 t.integer "right_id"
126 t.integer "right_id"
127 t.integer "role_id"
127 t.integer "role_id"
128 end
128 end
129
129
130 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
130 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
131
131
132 create_table "roles", :force => true do |t|
132 create_table "roles", :force => true do |t|
133 t.string "name"
133 t.string "name"
134 end
134 end
135
135
136 create_table "roles_users", :id => false, :force => true do |t|
136 create_table "roles_users", :id => false, :force => true do |t|
137 t.integer "role_id"
137 t.integer "role_id"
138 t.integer "user_id"
138 t.integer "user_id"
139 end
139 end
140
140
141 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
141 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
142
142
143 create_table "sessions", :force => true do |t|
143 create_table "sessions", :force => true do |t|
144 t.string "session_id"
144 t.string "session_id"
145 - t.text "data"
145 + t.text "data", :limit => 16777215
146 t.datetime "updated_at"
146 t.datetime "updated_at"
147 end
147 end
148
148
149 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
149 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
150 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
150 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
151
151
152 create_table "sites", :force => true do |t|
152 create_table "sites", :force => true do |t|
153 t.string "name"
153 t.string "name"
154 t.boolean "started"
154 t.boolean "started"
155 t.datetime "start_time"
155 t.datetime "start_time"
156 t.datetime "created_at", :null => false
156 t.datetime "created_at", :null => false
157 t.datetime "updated_at", :null => false
157 t.datetime "updated_at", :null => false
158 t.integer "country_id"
158 t.integer "country_id"
159 t.string "password"
159 t.string "password"
160 end
160 end
161
161
162 create_table "submissions", :force => true do |t|
162 create_table "submissions", :force => true do |t|
163 t.integer "user_id"
163 t.integer "user_id"
164 t.integer "problem_id"
164 t.integer "problem_id"
165 t.integer "language_id"
165 t.integer "language_id"
166 - t.text "source"
166 + t.text "source", :limit => 16777215
167 t.binary "binary"
167 t.binary "binary"
168 t.datetime "submitted_at"
168 t.datetime "submitted_at"
169 t.datetime "compiled_at"
169 t.datetime "compiled_at"
170 - t.text "compiler_message"
170 + t.text "compiler_message", :limit => 16777215
171 t.datetime "graded_at"
171 t.datetime "graded_at"
172 t.integer "points"
172 t.integer "points"
173 - t.text "grader_comment"
173 + t.text "grader_comment", :limit => 16777215
174 t.integer "number"
174 t.integer "number"
175 t.string "source_filename"
175 t.string "source_filename"
176 t.float "max_runtime"
176 t.float "max_runtime"
177 t.integer "peak_memory"
177 t.integer "peak_memory"
178 t.integer "effective_code_length"
178 t.integer "effective_code_length"
179 t.string "ip_address"
179 t.string "ip_address"
180 end
180 end
181
181
182 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
182 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
183 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
183 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
184
184
185 create_table "tasks", :force => true do |t|
185 create_table "tasks", :force => true do |t|
186 t.integer "submission_id"
186 t.integer "submission_id"
187 t.datetime "created_at"
187 t.datetime "created_at"
188 t.integer "status"
188 t.integer "status"
189 t.datetime "updated_at"
189 t.datetime "updated_at"
190 end
190 end
191
191
192 create_table "test_pairs", :force => true do |t|
192 create_table "test_pairs", :force => true do |t|
193 t.integer "problem_id"
193 t.integer "problem_id"
194 - t.text "input", :limit => 16777215
194 + t.text "input", :limit => 2147483647
195 - t.text "solution", :limit => 16777215
195 + t.text "solution", :limit => 2147483647
196 t.datetime "created_at", :null => false
196 t.datetime "created_at", :null => false
197 t.datetime "updated_at", :null => false
197 t.datetime "updated_at", :null => false
198 end
198 end
199
199
200 create_table "test_requests", :force => true do |t|
200 create_table "test_requests", :force => true do |t|
201 t.integer "user_id"
201 t.integer "user_id"
202 t.integer "problem_id"
202 t.integer "problem_id"
203 t.integer "submission_id"
203 t.integer "submission_id"
204 t.string "input_file_name"
204 t.string "input_file_name"
205 t.string "output_file_name"
205 t.string "output_file_name"
206 t.string "running_stat"
206 t.string "running_stat"
207 t.integer "status"
207 t.integer "status"
208 t.datetime "updated_at", :null => false
208 t.datetime "updated_at", :null => false
209 t.datetime "submitted_at"
209 t.datetime "submitted_at"
210 t.datetime "compiled_at"
210 t.datetime "compiled_at"
211 - t.text "compiler_message"
211 + t.text "compiler_message", :limit => 16777215
212 t.datetime "graded_at"
212 t.datetime "graded_at"
213 t.string "grader_comment"
213 t.string "grader_comment"
214 t.datetime "created_at", :null => false
214 t.datetime "created_at", :null => false
215 t.float "running_time"
215 t.float "running_time"
216 t.string "exit_status"
216 t.string "exit_status"
217 t.integer "memory_usage"
217 t.integer "memory_usage"
218 end
218 end
219
219
220 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
220 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
221
221
222 create_table "user_contest_stats", :force => true do |t|
222 create_table "user_contest_stats", :force => true do |t|
223 t.integer "user_id"
223 t.integer "user_id"
224 t.datetime "started_at"
224 t.datetime "started_at"
225 t.datetime "created_at", :null => false
225 t.datetime "created_at", :null => false
226 t.datetime "updated_at", :null => false
226 t.datetime "updated_at", :null => false
227 t.boolean "forced_logout"
227 t.boolean "forced_logout"
228 end
228 end
229
229
230 create_table "users", :force => true do |t|
230 create_table "users", :force => true do |t|
231 t.string "login", :limit => 50
231 t.string "login", :limit => 50
232 t.string "full_name"
232 t.string "full_name"
233 t.string "hashed_password"
233 t.string "hashed_password"
234 t.string "salt", :limit => 5
234 t.string "salt", :limit => 5
235 t.string "alias"
235 t.string "alias"
236 t.string "email"
236 t.string "email"
237 t.integer "site_id"
237 t.integer "site_id"
238 t.integer "country_id"
238 t.integer "country_id"
239 t.boolean "activated", :default => false
239 t.boolean "activated", :default => false
240 t.datetime "created_at"
240 t.datetime "created_at"
241 t.datetime "updated_at"
241 t.datetime "updated_at"
242 + t.string "section"
242 t.boolean "enabled", :default => true
243 t.boolean "enabled", :default => true
243 t.string "remark"
244 t.string "remark"
244 end
245 end
245
246
246 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
247 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
247
248
248 end
249 end
You need to be logged in to leave comments. Login now