Description:
modify user list creation into user list update
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r469:b28cd479ede6 - - 1 file changed: 11 inserted, 5 deleted

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