Description:
add more error message to user list upgrade. Fix #9
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r785:2cf37c58fc60 - - 2 files changed: 13 inserted, 7 deleted

@@ -1,617 +1,621
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_action :admin_authorization
7 before_action :admin_authorization
8
8
9 def index
9 def index
10 @user_count = User.count
10 @user_count = User.count
11 if params[:page] == 'all'
11 if params[:page] == 'all'
12 @users = User.all
12 @users = User.all
13 @paginated = false
13 @paginated = false
14 else
14 else
15 @users = User.paginate :page => params[:page]
15 @users = User.paginate :page => params[:page]
16 @paginated = true
16 @paginated = true
17 end
17 end
18 @users = User.all
18 @users = User.all
19 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
19 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
20 @contests = Contest.enabled
20 @contests = Contest.enabled
21 end
21 end
22
22
23 def active
23 def active
24 sessions = ActiveRecord::SessionStore::Session.where("updated_at >= ?", 60.minutes.ago)
24 sessions = ActiveRecord::SessionStore::Session.where("updated_at >= ?", 60.minutes.ago)
25 @users = []
25 @users = []
26 sessions.each do |session|
26 sessions.each do |session|
27 if session.data[:user_id]
27 if session.data[:user_id]
28 @users << User.find(session.data[:user_id])
28 @users << User.find(session.data[:user_id])
29 end
29 end
30 end
30 end
31 end
31 end
32
32
33 def show
33 def show
34 @user = User.find(params[:id])
34 @user = User.find(params[:id])
35 end
35 end
36
36
37 def new
37 def new
38 @user = User.new
38 @user = User.new
39 end
39 end
40
40
41 def create
41 def create
42 @user = User.new(user_params)
42 @user = User.new(user_params)
43 @user.activated = true
43 @user.activated = true
44 if @user.save
44 if @user.save
45 flash[:notice] = 'User was successfully created.'
45 flash[:notice] = 'User was successfully created.'
46 redirect_to :action => 'index'
46 redirect_to :action => 'index'
47 else
47 else
48 render :action => 'new'
48 render :action => 'new'
49 end
49 end
50 end
50 end
51
51
52 def clear_last_ip
52 def clear_last_ip
53 @user = User.find(params[:id])
53 @user = User.find(params[:id])
54 @user.last_ip = nil
54 @user.last_ip = nil
55 @user.save
55 @user.save
56 redirect_to action: 'index', page: params[:page]
56 redirect_to action: 'index', page: params[:page]
57 end
57 end
58
58
59 def create_from_list
59 def create_from_list
60 lines = params[:user_list]
60 lines = params[:user_list]
61
61
62 note = []
62 note = []
63 error_note = []
63 error_note = []
64 + error_msg = nil
64 ok_user = []
65 ok_user = []
65
66
66 lines.split("\n").each do |line|
67 lines.split("\n").each do |line|
67 items = line.chomp.split(',')
68 items = line.chomp.split(',')
68 if items.length>=2
69 if items.length>=2
69 login = items[0]
70 login = items[0]
70 full_name = items[1]
71 full_name = items[1]
71 remark =''
72 remark =''
72 user_alias = ''
73 user_alias = ''
73
74
74 added_random_password = false
75 added_random_password = false
75 if items.length >= 3 and items[2].chomp(" ").length > 0;
76 if items.length >= 3 and items[2].chomp(" ").length > 0;
76 password = items[2].chomp(" ")
77 password = items[2].chomp(" ")
77 else
78 else
78 password = random_password
79 password = random_password
79 - add_random_password=true;
80 + added_random_password=true;
80 end
81 end
81
82
82 if items.length>= 4 and items[3].chomp(" ").length > 0;
83 if items.length>= 4 and items[3].chomp(" ").length > 0;
83 user_alias = items[3].chomp(" ")
84 user_alias = items[3].chomp(" ")
84 else
85 else
85 user_alias = login
86 user_alias = login
86 end
87 end
87
88
88 if items.length>=5
89 if items.length>=5
89 remark = items[4].strip;
90 remark = items[4].strip;
90 end
91 end
91
92
92 user = User.find_by_login(login)
93 user = User.find_by_login(login)
93 if (user)
94 if (user)
94 user.full_name = full_name
95 user.full_name = full_name
95 user.password = password
96 user.password = password
96 user.remark = remark
97 user.remark = remark
97 else
98 else
98 user = User.new({:login => login,
99 user = User.new({:login => login,
99 :full_name => full_name,
100 :full_name => full_name,
100 :password => password,
101 :password => password,
101 :password_confirmation => password,
102 :password_confirmation => password,
102 :alias => user_alias,
103 :alias => user_alias,
103 :remark => remark})
104 :remark => remark})
104 end
105 end
105 user.activated = true
106 user.activated = true
106
107
107 if user.save
108 if user.save
108 if added_random_password
109 if added_random_password
109 note << "'#{login}' (+)"
110 note << "'#{login}' (+)"
110 else
111 else
111 note << login
112 note << login
112 end
113 end
113 ok_user << user
114 ok_user << user
114 else
115 else
115 - error_note << "#{login}"
116 + error_note << "'#{login}'"
117 + error_msg = user.errors.full_messages.to_sentence unless error_msg
116 end
118 end
117
119
118 end
120 end
119 end
121 end
120
122
121 #add to group
123 #add to group
122 if params[:add_to_group]
124 if params[:add_to_group]
123 group = Group.where(id: params[:group_id]).first
125 group = Group.where(id: params[:group_id]).first
124 if group
126 if group
125 group.users << ok_user
127 group.users << ok_user
126 end
128 end
127 end
129 end
128
130
129 # show flash
131 # show flash
132 + if note.size > 0
130 flash[:success] = 'User(s) ' + note.join(', ') +
133 flash[:success] = 'User(s) ' + note.join(', ') +
131 ' were successfully created. ' +
134 ' were successfully created. ' +
132 '( (+) - created with random passwords.)'
135 '( (+) - created with random passwords.)'
136 + end
133 if error_note.size > 0
137 if error_note.size > 0
134 - flash[:error] = "Following user(s) failed to be created: " + error_note.join(', ')
138 + flash[:error] = "Following user(s) failed to be created: " + error_note.join(', ') + ". The error of the first failed one are: " + error_msg;
135 end
139 end
136 redirect_to :action => 'index'
140 redirect_to :action => 'index'
137 end
141 end
138
142
139 def edit
143 def edit
140 @user = User.find(params[:id])
144 @user = User.find(params[:id])
141 end
145 end
142
146
143 def update
147 def update
144 @user = User.find(params[:id])
148 @user = User.find(params[:id])
145 if @user.update_attributes(user_params)
149 if @user.update_attributes(user_params)
146 flash[:notice] = 'User was successfully updated.'
150 flash[:notice] = 'User was successfully updated.'
147 redirect_to :action => 'show', :id => @user
151 redirect_to :action => 'show', :id => @user
148 else
152 else
149 render :action => 'edit'
153 render :action => 'edit'
150 end
154 end
151 end
155 end
152
156
153 def destroy
157 def destroy
154 User.find(params[:id]).destroy
158 User.find(params[:id]).destroy
155 redirect_to :action => 'index'
159 redirect_to :action => 'index'
156 end
160 end
157
161
158 def user_stat
162 def user_stat
159 if params[:commit] == 'download csv'
163 if params[:commit] == 'download csv'
160 @problems = Problem.all
164 @problems = Problem.all
161 else
165 else
162 @problems = Problem.available_problems
166 @problems = Problem.available_problems
163 end
167 end
164 @users = User.includes(:contests, :contest_stat).where(enabled: true)
168 @users = User.includes(:contests, :contest_stat).where(enabled: true)
165 @scorearray = Array.new
169 @scorearray = Array.new
166 @users.each do |u|
170 @users.each do |u|
167 ustat = Array.new
171 ustat = Array.new
168 ustat[0] = u
172 ustat[0] = u
169 @problems.each do |p|
173 @problems.each do |p|
170 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
174 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
171 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
175 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
172 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
176 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
173 else
177 else
174 ustat << [0,false]
178 ustat << [0,false]
175 end
179 end
176 end
180 end
177 @scorearray << ustat
181 @scorearray << ustat
178 end
182 end
179 if params[:commit] == 'download csv' then
183 if params[:commit] == 'download csv' then
180 csv = gen_csv_from_scorearray(@scorearray,@problems)
184 csv = gen_csv_from_scorearray(@scorearray,@problems)
181 send_data csv, filename: 'last_score.csv'
185 send_data csv, filename: 'last_score.csv'
182 else
186 else
183 render template: 'user_admin/user_stat'
187 render template: 'user_admin/user_stat'
184 end
188 end
185 end
189 end
186
190
187 def user_stat_max
191 def user_stat_max
188 if params[:commit] == 'download csv'
192 if params[:commit] == 'download csv'
189 @problems = Problem.all
193 @problems = Problem.all
190 else
194 else
191 @problems = Problem.available_problems
195 @problems = Problem.available_problems
192 end
196 end
193 @users = User.includes(:contests).includes(:contest_stat).all
197 @users = User.includes(:contests).includes(:contest_stat).all
194 @scorearray = Array.new
198 @scorearray = Array.new
195 #set up range from param
199 #set up range from param
196 since_id = params.fetch(:since_id, 0).to_i
200 since_id = params.fetch(:since_id, 0).to_i
197 until_id = params.fetch(:until_id, 0).to_i
201 until_id = params.fetch(:until_id, 0).to_i
198 @users.each do |u|
202 @users.each do |u|
199 ustat = Array.new
203 ustat = Array.new
200 ustat[0] = u
204 ustat[0] = u
201 @problems.each do |p|
205 @problems.each do |p|
202 max_points = 0
206 max_points = 0
203 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
207 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
204 max_points = sub.points if sub and sub.points and (sub.points > max_points)
208 max_points = sub.points if sub and sub.points and (sub.points > max_points)
205 end
209 end
206 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
210 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
207 end
211 end
208 @scorearray << ustat
212 @scorearray << ustat
209 end
213 end
210
214
211 if params[:commit] == 'download csv' then
215 if params[:commit] == 'download csv' then
212 csv = gen_csv_from_scorearray(@scorearray,@problems)
216 csv = gen_csv_from_scorearray(@scorearray,@problems)
213 send_data csv, filename: 'max_score.csv'
217 send_data csv, filename: 'max_score.csv'
214 else
218 else
215 render template: 'user_admin/user_stat'
219 render template: 'user_admin/user_stat'
216 end
220 end
217 end
221 end
218
222
219 def import
223 def import
220 if params[:file]==''
224 if params[:file]==''
221 flash[:notice] = 'Error importing no file'
225 flash[:notice] = 'Error importing no file'
222 redirect_to :action => 'index' and return
226 redirect_to :action => 'index' and return
223 end
227 end
224 import_from_file(params[:file])
228 import_from_file(params[:file])
225 end
229 end
226
230
227 def random_all_passwords
231 def random_all_passwords
228 users = User.all
232 users = User.all
229 @prefix = params[:prefix] || ''
233 @prefix = params[:prefix] || ''
230 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
234 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
231 @changed = false
235 @changed = false
232 if params[:commit] == 'Go ahead'
236 if params[:commit] == 'Go ahead'
233 @non_admin_users.each do |user|
237 @non_admin_users.each do |user|
234 password = random_password
238 password = random_password
235 user.password = password
239 user.password = password
236 user.password_confirmation = password
240 user.password_confirmation = password
237 user.save
241 user.save
238 end
242 end
239 @changed = true
243 @changed = true
240 end
244 end
241 end
245 end
242
246
243 # contest management
247 # contest management
244
248
245 def contests
249 def contests
246 @contest, @users = find_contest_and_user_from_contest_id(params[:id])
250 @contest, @users = find_contest_and_user_from_contest_id(params[:id])
247 @contests = Contest.enabled
251 @contests = Contest.enabled
248 end
252 end
249
253
250 def assign_from_list
254 def assign_from_list
251 contest_id = params[:users_contest_id]
255 contest_id = params[:users_contest_id]
252 org_contest, users = find_contest_and_user_from_contest_id(contest_id)
256 org_contest, users = find_contest_and_user_from_contest_id(contest_id)
253 contest = Contest.find(params[:new_contest][:id])
257 contest = Contest.find(params[:new_contest][:id])
254 if !contest
258 if !contest
255 flash[:notice] = 'Error: no contest'
259 flash[:notice] = 'Error: no contest'
256 redirect_to :action => 'contests', :id =>contest_id
260 redirect_to :action => 'contests', :id =>contest_id
257 end
261 end
258
262
259 note = []
263 note = []
260 users.each do |u|
264 users.each do |u|
261 u.contests = [contest]
265 u.contests = [contest]
262 note << u.login
266 note << u.login
263 end
267 end
264 flash[:notice] = 'User(s) ' + note.join(', ') +
268 flash[:notice] = 'User(s) ' + note.join(', ') +
265 " were successfully reassigned to #{contest.title}."
269 " were successfully reassigned to #{contest.title}."
266 redirect_to :action => 'contests', :id =>contest.id
270 redirect_to :action => 'contests', :id =>contest.id
267 end
271 end
268
272
269 def add_to_contest
273 def add_to_contest
270 user = User.find(params[:id])
274 user = User.find(params[:id])
271 contest = Contest.find(params[:contest_id])
275 contest = Contest.find(params[:contest_id])
272 if user and contest
276 if user and contest
273 user.contests << contest
277 user.contests << contest
274 end
278 end
275 redirect_to :action => 'index'
279 redirect_to :action => 'index'
276 end
280 end
277
281
278 def remove_from_contest
282 def remove_from_contest
279 user = User.find(params[:id])
283 user = User.find(params[:id])
280 contest = Contest.find(params[:contest_id])
284 contest = Contest.find(params[:contest_id])
281 if user and contest
285 if user and contest
282 user.contests.delete(contest)
286 user.contests.delete(contest)
283 end
287 end
284 redirect_to :action => 'index'
288 redirect_to :action => 'index'
285 end
289 end
286
290
287 def contest_management
291 def contest_management
288 end
292 end
289
293
290 def manage_contest
294 def manage_contest
291 contest = Contest.find(params[:contest][:id])
295 contest = Contest.find(params[:contest][:id])
292 if !contest
296 if !contest
293 flash[:notice] = 'You did not choose the contest.'
297 flash[:notice] = 'You did not choose the contest.'
294 redirect_to :action => 'contest_management' and return
298 redirect_to :action => 'contest_management' and return
295 end
299 end
296
300
297 operation = params[:operation]
301 operation = params[:operation]
298
302
299 if not ['add','remove','assign'].include? operation
303 if not ['add','remove','assign'].include? operation
300 flash[:notice] = 'You did not choose the operation to perform.'
304 flash[:notice] = 'You did not choose the operation to perform.'
301 redirect_to :action => 'contest_management' and return
305 redirect_to :action => 'contest_management' and return
302 end
306 end
303
307
304 lines = params[:login_list]
308 lines = params[:login_list]
305 if !lines or lines.blank?
309 if !lines or lines.blank?
306 flash[:notice] = 'You entered an empty list.'
310 flash[:notice] = 'You entered an empty list.'
307 redirect_to :action => 'contest_management' and return
311 redirect_to :action => 'contest_management' and return
308 end
312 end
309
313
310 note = []
314 note = []
311 users = []
315 users = []
312 lines.split("\n").each do |line|
316 lines.split("\n").each do |line|
313 user = User.find_by_login(line.chomp)
317 user = User.find_by_login(line.chomp)
314 if user
318 if user
315 if operation=='add'
319 if operation=='add'
316 if ! user.contests.include? contest
320 if ! user.contests.include? contest
317 user.contests << contest
321 user.contests << contest
318 end
322 end
319 elsif operation=='remove'
323 elsif operation=='remove'
320 user.contests.delete(contest)
324 user.contests.delete(contest)
321 else
325 else
322 user.contests = [contest]
326 user.contests = [contest]
323 end
327 end
324
328
325 if params[:reset_timer]
329 if params[:reset_timer]
326 user.contest_stat.forced_logout = true
330 user.contest_stat.forced_logout = true
327 user.contest_stat.reset_timer_and_save
331 user.contest_stat.reset_timer_and_save
328 end
332 end
329
333
330 if params[:notification_emails]
334 if params[:notification_emails]
331 send_contest_update_notification_email(user, contest)
335 send_contest_update_notification_email(user, contest)
332 end
336 end
333
337
334 note << user.login
338 note << user.login
335 users << user
339 users << user
336 end
340 end
337 end
341 end
338
342
339 if params[:reset_timer]
343 if params[:reset_timer]
340 logout_users(users)
344 logout_users(users)
341 end
345 end
342
346
343 flash[:notice] = 'User(s) ' + note.join(', ') +
347 flash[:notice] = 'User(s) ' + note.join(', ') +
344 ' were successfully modified. '
348 ' were successfully modified. '
345 redirect_to :action => 'contest_management'
349 redirect_to :action => 'contest_management'
346 end
350 end
347
351
348 # admin management
352 # admin management
349
353
350 def admin
354 def admin
351 @admins = User.all.find_all {|user| user.admin? }
355 @admins = User.all.find_all {|user| user.admin? }
352 end
356 end
353
357
354 def grant_admin
358 def grant_admin
355 login = params[:login]
359 login = params[:login]
356 user = User.find_by_login(login)
360 user = User.find_by_login(login)
357 if user!=nil
361 if user!=nil
358 admin_role = Role.find_by_name('admin')
362 admin_role = Role.find_by_name('admin')
359 user.roles << admin_role
363 user.roles << admin_role
360 else
364 else
361 flash[:notice] = 'Unknown user'
365 flash[:notice] = 'Unknown user'
362 end
366 end
363 flash[:notice] = 'User added as admins'
367 flash[:notice] = 'User added as admins'
364 redirect_to :action => 'admin'
368 redirect_to :action => 'admin'
365 end
369 end
366
370
367 def revoke_admin
371 def revoke_admin
368 user = User.find(params[:id])
372 user = User.find(params[:id])
369 if user==nil
373 if user==nil
370 flash[:notice] = 'Unknown user'
374 flash[:notice] = 'Unknown user'
371 redirect_to :action => 'admin' and return
375 redirect_to :action => 'admin' and return
372 elsif user.login == 'root'
376 elsif user.login == 'root'
373 flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
377 flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
374 redirect_to :action => 'admin' and return
378 redirect_to :action => 'admin' and return
375 end
379 end
376
380
377 admin_role = Role.find_by_name('admin')
381 admin_role = Role.find_by_name('admin')
378 user.roles.delete(admin_role)
382 user.roles.delete(admin_role)
379 flash[:notice] = 'User permission revoked'
383 flash[:notice] = 'User permission revoked'
380 redirect_to :action => 'admin'
384 redirect_to :action => 'admin'
381 end
385 end
382
386
383 # mass mailing
387 # mass mailing
384
388
385 def mass_mailing
389 def mass_mailing
386 end
390 end
387
391
388 def bulk_mail
392 def bulk_mail
389 lines = params[:login_list]
393 lines = params[:login_list]
390 if !lines or lines.blank?
394 if !lines or lines.blank?
391 flash[:notice] = 'You entered an empty list.'
395 flash[:notice] = 'You entered an empty list.'
392 redirect_to :action => 'mass_mailing' and return
396 redirect_to :action => 'mass_mailing' and return
393 end
397 end
394
398
395 mail_subject = params[:subject]
399 mail_subject = params[:subject]
396 if !mail_subject or mail_subject.blank?
400 if !mail_subject or mail_subject.blank?
397 flash[:notice] = 'You entered an empty mail subject.'
401 flash[:notice] = 'You entered an empty mail subject.'
398 redirect_to :action => 'mass_mailing' and return
402 redirect_to :action => 'mass_mailing' and return
399 end
403 end
400
404
401 mail_body = params[:email_body]
405 mail_body = params[:email_body]
402 if !mail_body or mail_body.blank?
406 if !mail_body or mail_body.blank?
403 flash[:notice] = 'You entered an empty mail body.'
407 flash[:notice] = 'You entered an empty mail body.'
404 redirect_to :action => 'mass_mailing' and return
408 redirect_to :action => 'mass_mailing' and return
405 end
409 end
406
410
407 note = []
411 note = []
408 users = []
412 users = []
409 lines.split("\n").each do |line|
413 lines.split("\n").each do |line|
410 user = User.find_by_login(line.chomp)
414 user = User.find_by_login(line.chomp)
411 if user
415 if user
412 send_mail(user.email, mail_subject, mail_body)
416 send_mail(user.email, mail_subject, mail_body)
413 note << user.login
417 note << user.login
414 end
418 end
415 end
419 end
416
420
417 flash[:notice] = 'User(s) ' + note.join(', ') +
421 flash[:notice] = 'User(s) ' + note.join(', ') +
418 ' were successfully modified. '
422 ' were successfully modified. '
419 redirect_to :action => 'mass_mailing'
423 redirect_to :action => 'mass_mailing'
420 end
424 end
421
425
422 #bulk manage
426 #bulk manage
423 def bulk_manage
427 def bulk_manage
424
428
425 begin
429 begin
426 @users = User.where('(login REGEXP ?) OR (remark REGEXP ?)',params[:regex],params[:regex]) if params[:regex]
430 @users = User.where('(login REGEXP ?) OR (remark REGEXP ?)',params[:regex],params[:regex]) if params[:regex]
427 @users.count if @users #i don't know why I have to call count, but if I won't exception is not raised
431 @users.count if @users #i don't know why I have to call count, but if I won't exception is not raised
428 rescue Exception
432 rescue Exception
429 flash[:error] = 'Regular Expression is malformed'
433 flash[:error] = 'Regular Expression is malformed'
430 @users = nil
434 @users = nil
431 end
435 end
432
436
433 if params[:commit]
437 if params[:commit]
434 @action = {}
438 @action = {}
435 @action[:set_enable] = params[:enabled]
439 @action[:set_enable] = params[:enabled]
436 @action[:enabled] = params[:enable] == "1"
440 @action[:enabled] = params[:enable] == "1"
437 @action[:gen_password] = params[:gen_password]
441 @action[:gen_password] = params[:gen_password]
438 @action[:add_group] = params[:add_group]
442 @action[:add_group] = params[:add_group]
439 @action[:group_name] = params[:group_name]
443 @action[:group_name] = params[:group_name]
440 end
444 end
441
445
442 if params[:commit] == "Perform"
446 if params[:commit] == "Perform"
443 if @action[:set_enable]
447 if @action[:set_enable]
444 @users.update_all(enabled: @action[:enabled])
448 @users.update_all(enabled: @action[:enabled])
445 end
449 end
446 if @action[:gen_password]
450 if @action[:gen_password]
447 @users.each do |u|
451 @users.each do |u|
448 password = random_password
452 password = random_password
449 u.password = password
453 u.password = password
450 u.password_confirmation = password
454 u.password_confirmation = password
451 u.save
455 u.save
452 end
456 end
453 end
457 end
454 if @action[:add_group] and @action[:group_name]
458 if @action[:add_group] and @action[:group_name]
455 @group = Group.find(@action[:group_name])
459 @group = Group.find(@action[:group_name])
456 ok = []
460 ok = []
457 failed = []
461 failed = []
458 @users.each do |user|
462 @users.each do |user|
459 begin
463 begin
460 @group.users << user
464 @group.users << user
461 ok << user.login
465 ok << user.login
462 rescue => e
466 rescue => e
463 failed << user.login
467 failed << user.login
464 end
468 end
465 end
469 end
466 flash[:success] = "The following users are added to the 'group #{@group.name}': " + ok.join(', ') if ok.count > 0
470 flash[:success] = "The following users are added to the 'group #{@group.name}': " + ok.join(', ') if ok.count > 0
467 flash[:alert] = "The following users are already in the 'group #{@group.name}': " + failed.join(', ') if failed.count > 0
471 flash[:alert] = "The following users are already in the 'group #{@group.name}': " + failed.join(', ') if failed.count > 0
468 end
472 end
469 end
473 end
470 end
474 end
471
475
472 protected
476 protected
473
477
474 def random_password(length=5)
478 def random_password(length=5)
475 chars = 'abcdefghijkmnopqrstuvwxyz23456789'
479 chars = 'abcdefghijkmnopqrstuvwxyz23456789'
476 newpass = ""
480 newpass = ""
477 length.times { newpass << chars[rand(chars.size-1)] }
481 length.times { newpass << chars[rand(chars.size-1)] }
478 return newpass
482 return newpass
479 end
483 end
480
484
481 def import_from_file(f)
485 def import_from_file(f)
482 data_hash = YAML.load(f)
486 data_hash = YAML.load(f)
483 @import_log = ""
487 @import_log = ""
484
488
485 country_data = data_hash[:countries]
489 country_data = data_hash[:countries]
486 site_data = data_hash[:sites]
490 site_data = data_hash[:sites]
487 user_data = data_hash[:users]
491 user_data = data_hash[:users]
488
492
489 # import country
493 # import country
490 countries = {}
494 countries = {}
491 country_data.each_pair do |id,country|
495 country_data.each_pair do |id,country|
492 c = Country.find_by_name(country[:name])
496 c = Country.find_by_name(country[:name])
493 if c!=nil
497 if c!=nil
494 countries[id] = c
498 countries[id] = c
495 @import_log << "Found #{country[:name]}\n"
499 @import_log << "Found #{country[:name]}\n"
496 else
500 else
497 countries[id] = Country.new(:name => country[:name])
501 countries[id] = Country.new(:name => country[:name])
498 countries[id].save
502 countries[id].save
499 @import_log << "Created #{country[:name]}\n"
503 @import_log << "Created #{country[:name]}\n"
500 end
504 end
501 end
505 end
502
506
503 # import sites
507 # import sites
504 sites = {}
508 sites = {}
505 site_data.each_pair do |id,site|
509 site_data.each_pair do |id,site|
506 s = Site.find_by_name(site[:name])
510 s = Site.find_by_name(site[:name])
507 if s!=nil
511 if s!=nil
508 @import_log << "Found #{site[:name]}\n"
512 @import_log << "Found #{site[:name]}\n"
509 else
513 else
510 s = Site.new(:name => site[:name])
514 s = Site.new(:name => site[:name])
511 @import_log << "Created #{site[:name]}\n"
515 @import_log << "Created #{site[:name]}\n"
512 end
516 end
513 s.password = site[:password]
517 s.password = site[:password]
514 s.country = countries[site[:country_id]]
518 s.country = countries[site[:country_id]]
515 s.save
519 s.save
516 sites[id] = s
520 sites[id] = s
517 end
521 end
518
522
519 # import users
523 # import users
520 user_data.each_pair do |id,user|
524 user_data.each_pair do |id,user|
521 u = User.find_by_login(user[:login])
525 u = User.find_by_login(user[:login])
522 if u!=nil
526 if u!=nil
523 @import_log << "Found #{user[:login]}\n"
527 @import_log << "Found #{user[:login]}\n"
524 else
528 else
525 u = User.new(:login => user[:login])
529 u = User.new(:login => user[:login])
526 @import_log << "Created #{user[:login]}\n"
530 @import_log << "Created #{user[:login]}\n"
527 end
531 end
528 u.full_name = user[:name]
532 u.full_name = user[:name]
529 u.password = user[:password]
533 u.password = user[:password]
530 u.country = countries[user[:country_id]]
534 u.country = countries[user[:country_id]]
531 u.site = sites[user[:site_id]]
535 u.site = sites[user[:site_id]]
532 u.activated = true
536 u.activated = true
533 u.email = "empty-#{u.login}@none.com"
537 u.email = "empty-#{u.login}@none.com"
534 if not u.save
538 if not u.save
535 @import_log << "Errors\n"
539 @import_log << "Errors\n"
536 u.errors.each { |attr,msg| @import_log << "#{attr} - #{msg}\n" }
540 u.errors.each { |attr,msg| @import_log << "#{attr} - #{msg}\n" }
537 end
541 end
538 end
542 end
539
543
540 end
544 end
541
545
542 def logout_users(users)
546 def logout_users(users)
543 users.each do |user|
547 users.each do |user|
544 contest_stat = user.contest_stat(true)
548 contest_stat = user.contest_stat(true)
545 if contest_stat and !contest_stat.forced_logout
549 if contest_stat and !contest_stat.forced_logout
546 contest_stat.forced_logout = true
550 contest_stat.forced_logout = true
547 contest_stat.save
551 contest_stat.save
548 end
552 end
549 end
553 end
550 end
554 end
551
555
552 def send_contest_update_notification_email(user, contest)
556 def send_contest_update_notification_email(user, contest)
553 contest_title_name = GraderConfiguration['contest.name']
557 contest_title_name = GraderConfiguration['contest.name']
554 contest_name = contest.name
558 contest_name = contest.name
555 mail_subject = t('contest.notification.email_subject', {
559 mail_subject = t('contest.notification.email_subject', {
556 :contest_title_name => contest_title_name,
560 :contest_title_name => contest_title_name,
557 :contest_name => contest_name })
561 :contest_name => contest_name })
558 mail_body = t('contest.notification.email_body', {
562 mail_body = t('contest.notification.email_body', {
559 :full_name => user.full_name,
563 :full_name => user.full_name,
560 :contest_title_name => contest_title_name,
564 :contest_title_name => contest_title_name,
561 :contest_name => contest.name,
565 :contest_name => contest.name,
562 })
566 })
563
567
564 logger.info mail_body
568 logger.info mail_body
565 send_mail(user.email, mail_subject, mail_body)
569 send_mail(user.email, mail_subject, mail_body)
566 end
570 end
567
571
568 def find_contest_and_user_from_contest_id(id)
572 def find_contest_and_user_from_contest_id(id)
569 if id!='none'
573 if id!='none'
570 @contest = Contest.find(id)
574 @contest = Contest.find(id)
571 else
575 else
572 @contest = nil
576 @contest = nil
573 end
577 end
574 if @contest
578 if @contest
575 @users = @contest.users
579 @users = @contest.users
576 else
580 else
577 @users = User.find_users_with_no_contest
581 @users = User.find_users_with_no_contest
578 end
582 end
579 return [@contest, @users]
583 return [@contest, @users]
580 end
584 end
581
585
582 def gen_csv_from_scorearray(scorearray,problem)
586 def gen_csv_from_scorearray(scorearray,problem)
583 CSV.generate do |csv|
587 CSV.generate do |csv|
584 #add header
588 #add header
585 header = ['User','Name', 'Activated?', 'Logged in', 'Contest']
589 header = ['User','Name', 'Activated?', 'Logged in', 'Contest']
586 problem.each { |p| header << p.name }
590 problem.each { |p| header << p.name }
587 header += ['Total','Passed']
591 header += ['Total','Passed']
588 csv << header
592 csv << header
589 #add data
593 #add data
590 scorearray.each do |sc|
594 scorearray.each do |sc|
591 total = num_passed = 0
595 total = num_passed = 0
592 row = Array.new
596 row = Array.new
593 sc.each_index do |i|
597 sc.each_index do |i|
594 if i == 0
598 if i == 0
595 row << sc[i].login
599 row << sc[i].login
596 row << sc[i].full_name
600 row << sc[i].full_name
597 row << sc[i].activated
601 row << sc[i].activated
598 row << (sc[i].try(:contest_stat).try(:started_at).nil? ? 'no' : 'yes')
602 row << (sc[i].try(:contest_stat).try(:started_at).nil? ? 'no' : 'yes')
599 row << sc[i].contests.collect {|c| c.name}.join(', ')
603 row << sc[i].contests.collect {|c| c.name}.join(', ')
600 else
604 else
601 row << sc[i][0]
605 row << sc[i][0]
602 total += sc[i][0]
606 total += sc[i][0]
603 num_passed += 1 if sc[i][1]
607 num_passed += 1 if sc[i][1]
604 end
608 end
605 end
609 end
606 row << total
610 row << total
607 row << num_passed
611 row << num_passed
608 csv << row
612 csv << row
609 end
613 end
610 end
614 end
611 end
615 end
612
616
613 private
617 private
614 def user_params
618 def user_params
615 params.require(:user).permit(:login,:password,:password_confirmation,:email, :alias, :full_name,:remark)
619 params.require(:user).permit(:login,:password,:password_confirmation,:email, :alias, :full_name,:remark)
616 end
620 end
617 end
621 end
@@ -1,80 +1,82
1 .container-fluid
1 .container-fluid
2 .row
2 .row
3 .col-md-6
3 .col-md-6
4 %h1 Group #{@group.name}
4 %h1 Group #{@group.name}
5 .row
5 .row
6 .col-md-6
6 .col-md-6
7 %b Description:
7 %b Description:
8 = @group.description
8 = @group.description
9 %br
9 %br
10 = link_to 'Edit', edit_group_path(@group), class: 'btn btn-primary'
10 = link_to 'Edit', edit_group_path(@group), class: 'btn btn-primary'
11 .row
11 .row
12 .col-md-12
12 .col-md-12
13 %h1 Group details
13 %h1 Group details
14 .row
14 .row
15 .col-md-6
15 .col-md-6
16 .panel.panel-default
16 .panel.panel-default
17 .panel-heading
17 .panel-heading
18 .panel-title Users in this group
18 .panel-title Users in this group
19 .panel-body
19 .panel-body
20 %ul
20 %ul
21 %li
21 %li
22 If you want to add several users to a group, it may be easier to just re-import those users in
22 If you want to add several users to a group, it may be easier to just re-import those users in
23 = link_to 'New list of users', new_list_user_admin_index_path
23 = link_to 'New list of users', new_list_user_admin_index_path
24 - page
24 + page. You can also use
25 + = link_to 'Bulk Manage User', bulk_manage_user_admin_index_path
26 + page.
25 =form_tag add_user_group_path(@group), class: 'form-inline' do
27 =form_tag add_user_group_path(@group), class: 'form-inline' do
26 .form-group
28 .form-group
27 =label_tag :user_id, "User"
29 =label_tag :user_id, "User"
28 - =select_tag :user_id, options_from_collection_for_select(User.all,'id','full_name'), class: 'select2'
30 + =select_tag :user_id, options_from_collection_for_select(User.all,'id','full_name'), class: 'select2', style: 'width: 10em';
29 =submit_tag "Add",class: 'btn btn-primary'
31 =submit_tag "Add",class: 'btn btn-primary'
30
32
31
33
32 %table.table.table-hover
34 %table.table.table-hover
33 %thead
35 %thead
34 %tr
36 %tr
35 %th Login
37 %th Login
36 %th Full name
38 %th Full name
37 %th Remark
39 %th Remark
38 %th= link_to 'Remove All', remove_all_user_group_path(@group), method: :delete, :data => { :confirm => "Remove ALL USERS from group?" }, class: 'btn btn-danger btn-sm'
40 %th= link_to 'Remove All', remove_all_user_group_path(@group), method: :delete, :data => { :confirm => "Remove ALL USERS from group?" }, class: 'btn btn-danger btn-sm'
39
41
40 %tbody
42 %tbody
41 - @group.users.each do |user|
43 - @group.users.each do |user|
42 %tr
44 %tr
43 %td= user.login
45 %td= user.login
44 %td= user.full_name
46 %td= user.full_name
45 %td= user.remark
47 %td= user.remark
46 %td= link_to 'Remove', remove_user_group_path(@group,user), :method => :delete, :data => { :confirm => "Remove #{user.full_name}?" }, class: 'btn btn-danger btn-sm'
48 %td= link_to 'Remove', remove_user_group_path(@group,user), :method => :delete, :data => { :confirm => "Remove #{user.full_name}?" }, class: 'btn btn-danger btn-sm'
47 .col-md-6
49 .col-md-6
48 .panel.panel-default
50 .panel.panel-default
49 .panel-heading
51 .panel-heading
50 .panel-title Problems
52 .panel-title Problems
51 .panel-body
53 .panel-body
52 %ul
54 %ul
53 %li
55 %li
54 If you want to add several problem to a group, it may be easier to bulk manage them in the
56 If you want to add several problem to a group, it may be easier to bulk manage them in the
55 - = link_to 'Bulk Manage', manage_problems_path
57 + = link_to 'Bulk Manage Problems', manage_problems_path
56 page
58 page
57 =form_tag add_problem_group_path(@group), class: 'form-inline' do
59 =form_tag add_problem_group_path(@group), class: 'form-inline' do
58 .form-group
60 .form-group
59 =label_tag :problem_id, "Problem"
61 =label_tag :problem_id, "Problem"
60 - =select_tag :problem_id, options_from_collection_for_select(Problem.all,'id','full_name'), class: 'select2'
62 + =select_tag :problem_id, options_from_collection_for_select(Problem.all,'id','full_name'), class: 'select2', style: 'width: 10em';
61 =submit_tag "Add",class: 'btn btn-primary'
63 =submit_tag "Add",class: 'btn btn-primary'
62
64
63
65
64 %table.table.table-hover
66 %table.table.table-hover
65 %thead
67 %thead
66 %tr
68 %tr
67 %th name
69 %th name
68 %th Full name
70 %th Full name
69 %th Full score
71 %th Full score
70 %th= link_to 'Remove All', remove_all_problem_group_path(@group), method: :delete, :data => { :confirm => "Remove ALL PROBLEMS from group?" }, class: 'btn btn-danger btn-sm'
72 %th= link_to 'Remove All', remove_all_problem_group_path(@group), method: :delete, :data => { :confirm => "Remove ALL PROBLEMS from group?" }, class: 'btn btn-danger btn-sm'
71
73
72 %tbody
74 %tbody
73 - @group.problems.each do |problem|
75 - @group.problems.each do |problem|
74 %tr
76 %tr
75 %td= problem.name
77 %td= problem.name
76 %td= problem.full_name
78 %td= problem.full_name
77 %td= problem.full_score
79 %td= problem.full_score
78 %td= link_to 'Remove', remove_problem_group_path(@group,problem), :method => :delete, :data => { :confirm => "Remove #{problem.full_name}?" }, class: 'btn btn-danger btn-sm'
80 %td= link_to 'Remove', remove_problem_group_path(@group,problem), :method => :delete, :data => { :confirm => "Remove #{problem.full_name}?" }, class: 'btn btn-danger btn-sm'
79
81
80
82
You need to be logged in to leave comments. Login now