Description:
lists users in each contest. individual user contest management moved to each contest user list page
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r297:2abed488d02c - - 4 files changed: 92 inserted, 19 deleted

@@ -0,0 +1,65
1 + <h1>
2 + List users in <% if @contest %><%= @contest.title %>
3 + <% else %>Users not in any contests<% end %>
4 + </h1>
5 +
6 + <div class="submitbox">
7 + <%= link_to '[View all users]', :action => 'list' %>
8 + <% if Configuration.multicontests? %>
9 + <%= link_to '[Manage bulk users in contests]', :action => 'contest_management' %>
10 + <br/>
11 + View users in:
12 + <% @contests.each do |contest| %>
13 + <%= link_to "[#{contest.name}]", :action => 'contests', :id => contest.id %>
14 + <% end %>
15 + <%= link_to "[no contest]", :action => 'contests', :id => 'none' %>
16 + <% end %>
17 + </div>
18 +
19 + <table class="info">
20 + <tr class="info-head">
21 + <th>Login</th>
22 + <th>Full name</th>
23 + <th>Email</th>
24 + <th>Activated?</th>
25 + <th></th>
26 + <th></th>
27 + <th></th>
28 + <% if Configuration.multicontests? %>
29 + <th>Contests</th>
30 + <th>Other enabled contests</th>
31 + <% end %>
32 + </tr>
33 +
34 + <% for user in @users %>
35 + <tr class="info-<%= cycle("odd","even") %>">
36 + <td><%=h user.login %></td>
37 + <td><%=h user.full_name %></td>
38 + <td><%=h user.email %></td>
39 + <td><%=h user.activated %></td>
40 + <td><%= link_to 'Show', :action => 'show', :id => user %></td>
41 + <td><%= link_to 'Edit', :action => 'edit', :id => user %></td>
42 + <td><%= link_to 'Destroy', { :action => 'destroy', :id => user }, :confirm => 'Are you sure?', :method => :post %></td>
43 + <% if Configuration.multicontests? %>
44 + <td>
45 + <% user.contests.each do |contest| %>
46 + <%= contest.name %> [<%= link_to 'x', :action => 'remove_from_contest', :id => user.id, :contest_id => contest.id %>]
47 + <% end %>
48 + </td>
49 + <td>
50 + <% @contests.each do |contest| %>
51 + <% if not user.contests.all.find {|c| c.id==contest.id } %>
52 + <%= contest.name %> [<%= link_to '+', :action => 'add_to_contest', :id => user.id, :contest_id => contest.id %>]
53 + <% end %>
54 + <% end %>
55 + </td>
56 + <% end %>
57 + </tr>
58 + <% end %>
59 + </table>
60 +
61 +
62 + <br />
63 +
64 + <%= link_to 'New user', :action => 'new' %>
65 + <%= link_to 'New list of users', :action => 'new_list' %>
@@ -1,368 +1,382
1 1 class UserAdminController < ApplicationController
2 2
3 3 include MailHelperMethods
4 4
5 5 before_filter :admin_authorization
6 6
7 7 def index
8 8 list
9 9 render :action => 'list'
10 10 end
11 11
12 12 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
13 13 verify :method => :post, :only => [ :destroy,
14 14 :create, :create_from_list,
15 15 :update ],
16 16 :redirect_to => { :action => :list }
17 17
18 18 def list
19 19 @users = User.find(:all)
20 20 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
21 - @contests = Contest.all(:conditions => {:enabled => true})
21 + @contests = Contest.enabled
22 22 end
23 23
24 24 def active
25 25 sessions = ActiveRecord::SessionStore::Session.find(:all, :conditions => ["updated_at >= ?", 60.minutes.ago])
26 26 @users = []
27 27 sessions.each do |session|
28 28 if session.data[:user_id]
29 29 @users << User.find(session.data[:user_id])
30 30 end
31 31 end
32 32 end
33 33
34 34 def show
35 35 @user = User.find(params[:id])
36 36 end
37 37
38 38 def new
39 39 @user = User.new
40 40 end
41 41
42 42 def create
43 43 @user = User.new(params[:user])
44 44 @user.activated = true
45 45 if @user.save
46 46 flash[:notice] = 'User was successfully created.'
47 47 redirect_to :action => 'list'
48 48 else
49 49 render :action => 'new'
50 50 end
51 51 end
52 52
53 53 def create_from_list
54 54 lines = params[:user_list]
55 55
56 56 note = []
57 57
58 58 lines.split("\n").each do |line|
59 59 items = line.chomp.split(',')
60 60 if items.length>=2
61 61 login = items[0]
62 62 full_name = items[1]
63 63
64 64 added_random_password = false
65 65 if items.length>=3
66 66 password = items[2]
67 67 user_alias = (items.length>=4) ? items[3] : login
68 68 else
69 69 password = random_password
70 70 user_alias = (items.length>=4) ? items[3] : login
71 71 added_random_password = true
72 72 end
73 73
74 74 user = User.new({:login => login,
75 75 :full_name => full_name,
76 76 :password => password,
77 77 :password_confirmation => password,
78 78 :alias => user_alias})
79 79 user.activated = true
80 80 user.save
81 81
82 82 if added_random_password
83 83 note << "'#{login}' (+)"
84 84 else
85 85 note << login
86 86 end
87 87 end
88 88 end
89 89 flash[:notice] = 'User(s) ' + note.join(', ') +
90 90 ' were successfully created. ' +
91 91 '( (+) - created with random passwords.)'
92 92 redirect_to :action => 'list'
93 93 end
94 94
95 95 def edit
96 96 @user = User.find(params[:id])
97 97 end
98 98
99 99 def update
100 100 @user = User.find(params[:id])
101 101 if @user.update_attributes(params[:user])
102 102 flash[:notice] = 'User was successfully updated.'
103 103 redirect_to :action => 'show', :id => @user
104 104 else
105 105 render :action => 'edit'
106 106 end
107 107 end
108 108
109 109 def destroy
110 110 User.find(params[:id]).destroy
111 111 redirect_to :action => 'list'
112 112 end
113 113
114 114 def user_stat
115 115 @problems = Problem.find_available_problems
116 116 @users = User.find(:all)
117 117 @scorearray = Array.new
118 118 @users.each do |u|
119 119 ustat = Array.new
120 120 ustat[0] = u
121 121 @problems.each do |p|
122 122 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
123 123 if (sub!=nil) and (sub.points!=nil)
124 124 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
125 125 else
126 126 ustat << [0,false]
127 127 end
128 128 end
129 129 @scorearray << ustat
130 130 end
131 131 end
132 132
133 133 def import
134 134 if params[:file]==''
135 135 flash[:notice] = 'Error importing no file'
136 136 redirect_to :action => 'list' and return
137 137 end
138 138 import_from_file(params[:file])
139 139 end
140 140
141 141 def random_all_passwords
142 142 users = User.find(:all)
143 143 @prefix = params[:prefix] || ''
144 144 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
145 145 @changed = false
146 146 if request.request_method == :post
147 147 @non_admin_users.each do |user|
148 148 password = random_password
149 149 user.password = password
150 150 user.password_confirmation = password
151 151 user.save
152 152 end
153 153 @changed = true
154 154 end
155 155 end
156 156
157 157 # contest management
158 158
159 + def contests
160 + if params[:id]!='none'
161 + @contest = Contest.find(params[:id])
162 + else
163 + @contest = nil
164 + end
165 + if @contest
166 + @users = @contest.users
167 + else
168 + @users = User.find_users_with_no_contest
169 + end
170 + @contests = Contest.enabled
171 + end
172 +
159 173 def add_to_contest
160 174 user = User.find(params[:id])
161 175 contest = Contest.find(params[:contest_id])
162 176 if user and contest
163 177 user.contests << contest
164 178 end
165 179 redirect_to :action => 'list'
166 180 end
167 181
168 182 def remove_from_contest
169 183 user = User.find(params[:id])
170 184 contest = Contest.find(params[:contest_id])
171 185 if user and contest
172 186 user.contests.delete(contest)
173 187 end
174 188 redirect_to :action => 'list'
175 189 end
176 190
177 191 def contest_management
178 192 end
179 193
180 194 def manage_contest
181 195 contest = Contest.find(params[:contest][:id])
182 196 if !contest
183 197 flash[:notice] = 'You did not choose the contest.'
184 198 redirect_to :action => 'contest_management' and return
185 199 end
186 200
187 201 operation = params[:operation]
188 202
189 203 if not ['add','remove','assign'].include? operation
190 204 flash[:notice] = 'You did not choose the operation to perform.'
191 205 redirect_to :action => 'contest_management' and return
192 206 end
193 207
194 208 lines = params[:login_list]
195 209 if !lines or lines.blank?
196 210 flash[:notice] = 'You entered an empty list.'
197 211 redirect_to :action => 'contest_management' and return
198 212 end
199 213
200 214 note = []
201 215 users = []
202 216 lines.split("\n").each do |line|
203 217 user = User.find_by_login(line.chomp)
204 218 if user
205 219 if operation=='add'
206 220 if ! user.contests.include? contest
207 221 user.contests << contest
208 222 end
209 223 elsif operation=='remove'
210 224 user.contests.delete(contest)
211 225 else
212 226 user.contests = [contest]
213 227 end
214 228
215 229 if params[:reset_timer]
216 230 user.contest_stat.forced_logout = true
217 231 user.contest_stat.reset_timer_and_save
218 232 end
219 233
220 234 if params[:notification_emails]
221 235 send_contest_update_notification_email(user, contest)
222 236 end
223 237
224 238 note << user.login
225 239 users << user
226 240 end
227 241 end
228 242
229 243 if params[:reset_timer]
230 244 logout_users(users)
231 245 end
232 246
233 247 flash[:notice] = 'User(s) ' + note.join(', ') +
234 248 ' were successfully modified. '
235 249 redirect_to :action => 'contest_management'
236 250 end
237 251
238 252 # admin management
239 253
240 254 def admin
241 255 @admins = User.find(:all).find_all {|user| user.admin? }
242 256 end
243 257
244 258 def grant_admin
245 259 login = params[:login]
246 260 user = User.find_by_login(login)
247 261 if user!=nil
248 262 admin_role = Role.find_by_name('admin')
249 263 user.roles << admin_role
250 264 else
251 265 flash[:notice] = 'Unknown user'
252 266 end
253 267 flash[:notice] = 'User added as admins'
254 268 redirect_to :action => 'admin'
255 269 end
256 270
257 271 def revoke_admin
258 272 user = User.find(params[:id])
259 273 if user==nil
260 274 flash[:notice] = 'Unknown user'
261 275 redirect_to :action => 'admin' and return
262 276 elsif user.login == 'root'
263 277 flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
264 278 redirect_to :action => 'admin' and return
265 279 end
266 280
267 281 admin_role = Role.find_by_name('admin')
268 282 user.roles.delete(admin_role)
269 283 flash[:notice] = 'User permission revoked'
270 284 redirect_to :action => 'admin'
271 285 end
272 286
273 287 protected
274 288
275 289 def random_password(length=5)
276 290 chars = 'abcdefghijkmnopqrstuvwxyz23456789'
277 291 newpass = ""
278 292 length.times { newpass << chars[rand(chars.size-1)] }
279 293 return newpass
280 294 end
281 295
282 296 def import_from_file(f)
283 297 data_hash = YAML.load(f)
284 298 @import_log = ""
285 299
286 300 country_data = data_hash[:countries]
287 301 site_data = data_hash[:sites]
288 302 user_data = data_hash[:users]
289 303
290 304 # import country
291 305 countries = {}
292 306 country_data.each_pair do |id,country|
293 307 c = Country.find_by_name(country[:name])
294 308 if c!=nil
295 309 countries[id] = c
296 310 @import_log << "Found #{country[:name]}\n"
297 311 else
298 312 countries[id] = Country.new(:name => country[:name])
299 313 countries[id].save
300 314 @import_log << "Created #{country[:name]}\n"
301 315 end
302 316 end
303 317
304 318 # import sites
305 319 sites = {}
306 320 site_data.each_pair do |id,site|
307 321 s = Site.find_by_name(site[:name])
308 322 if s!=nil
309 323 @import_log << "Found #{site[:name]}\n"
310 324 else
311 325 s = Site.new(:name => site[:name])
312 326 @import_log << "Created #{site[:name]}\n"
313 327 end
314 328 s.password = site[:password]
315 329 s.country = countries[site[:country_id]]
316 330 s.save
317 331 sites[id] = s
318 332 end
319 333
320 334 # import users
321 335 user_data.each_pair do |id,user|
322 336 u = User.find_by_login(user[:login])
323 337 if u!=nil
324 338 @import_log << "Found #{user[:login]}\n"
325 339 else
326 340 u = User.new(:login => user[:login])
327 341 @import_log << "Created #{user[:login]}\n"
328 342 end
329 343 u.full_name = user[:name]
330 344 u.password = user[:password]
331 345 u.country = countries[user[:country_id]]
332 346 u.site = sites[user[:site_id]]
333 347 u.activated = true
334 348 u.email = "empty-#{u.login}@none.com"
335 349 if not u.save
336 350 @import_log << "Errors\n"
337 351 u.errors.each { |attr,msg| @import_log << "#{attr} - #{msg}\n" }
338 352 end
339 353 end
340 354
341 355 end
342 356
343 357 def logout_users(users)
344 358 users.each do |user|
345 359 contest_stat = user.contest_stat(true)
346 360 if contest_stat and !contest_stat.forced_logout
347 361 contest_stat.forced_logout = true
348 362 contest_stat.save
349 363 end
350 364 end
351 365 end
352 366
353 367 def send_contest_update_notification_email(user, contest)
354 368 contest_title_name = Configuration['contest.name']
355 369 contest_name = contest.name
356 370 subject = t('contest.notification.email_subject', {
357 371 :contest_title_name => contest_title_name,
358 372 :contest_name => contest_name })
359 373 body = t('contest.notification.email_body', {
360 374 :full_name => user.full_name,
361 375 :contest_title_name => contest_title_name,
362 376 :contest_name => contest.name,
363 377 })
364 378
365 379 logger.info body
366 380 send_mail(user.email, subject, body)
367 381 end
368 382 end
@@ -1,296 +1,302
1 1 require 'digest/sha1'
2 2
3 3 class User < ActiveRecord::Base
4 4
5 5 has_and_belongs_to_many :roles
6 6
7 7 has_many :test_requests, :order => "submitted_at DESC"
8 8
9 9 has_many :messages,
10 10 :class_name => "Message",
11 11 :foreign_key => "sender_id",
12 12 :order => 'created_at DESC'
13 13
14 14 has_many :replied_messages,
15 15 :class_name => "Message",
16 16 :foreign_key => "receiver_id",
17 17 :order => 'created_at DESC'
18 18
19 19 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
20 20
21 21 belongs_to :site
22 22 belongs_to :country
23 23
24 24 has_and_belongs_to_many :contests, :uniq => true, :order => 'name'
25 25
26 26 named_scope :activated_users, :conditions => {:activated => true}
27 27
28 28 validates_presence_of :login
29 29 validates_uniqueness_of :login
30 30 validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
31 31 validates_length_of :login, :within => 3..30
32 32
33 33 validates_presence_of :full_name
34 34 validates_length_of :full_name, :minimum => 1
35 35
36 36 validates_presence_of :password, :if => :password_required?
37 37 validates_length_of :password, :within => 4..20, :if => :password_required?
38 38 validates_confirmation_of :password, :if => :password_required?
39 39
40 40 validates_format_of :email,
41 41 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
42 42 :if => :email_validation?
43 43 validate :uniqueness_of_email_from_activated_users,
44 44 :if => :email_validation?
45 45 validate :enough_time_interval_between_same_email_registrations,
46 46 :if => :email_validation?
47 47
48 48 # these are for ytopc
49 49 # disable for now
50 50 #validates_presence_of :province
51 51
52 52 attr_accessor :password
53 53
54 54 before_save :encrypt_new_password
55 55 before_save :assign_default_site
56 56
57 57 def self.authenticate(login, password)
58 58 user = find_by_login(login)
59 59 return user if user && user.authenticated?(password)
60 60 end
61 61
62 62 def authenticated?(password)
63 63 if self.activated
64 64 hashed_password == User.encrypt(password,self.salt)
65 65 else
66 66 false
67 67 end
68 68 end
69 69
70 70 def admin?
71 71 self.roles.detect {|r| r.name == 'admin' }
72 72 end
73 73
74 74 def email_for_editing
75 75 if self.email==nil
76 76 "(unknown)"
77 77 elsif self.email==''
78 78 "(blank)"
79 79 else
80 80 self.email
81 81 end
82 82 end
83 83
84 84 def email_for_editing=(e)
85 85 self.email=e
86 86 end
87 87
88 88 def alias_for_editing
89 89 if self.alias==nil
90 90 "(unknown)"
91 91 elsif self.alias==''
92 92 "(blank)"
93 93 else
94 94 self.alias
95 95 end
96 96 end
97 97
98 98 def alias_for_editing=(e)
99 99 self.alias=e
100 100 end
101 101
102 102 def activation_key
103 103 if self.hashed_password==nil
104 104 encrypt_new_password
105 105 end
106 106 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
107 107 end
108 108
109 109 def verify_activation_key(key)
110 110 key == activation_key
111 111 end
112 112
113 113 def self.random_password(length=5)
114 114 chars = 'abcdefghjkmnopqrstuvwxyz'
115 115 password = ''
116 116 length.times { password << chars[rand(chars.length - 1)] }
117 117 password
118 118 end
119 119
120 120 def self.find_non_admin_with_prefix(prefix='')
121 121 users = User.find(:all)
122 122 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
123 123 end
124 124
125 125 # Contest information
126 126
127 + def self.find_users_with_no_contest()
128 + users = User.find(:all)
129 + return users.find_all { |u| u.contests.length == 0 }
130 + end
131 +
132 +
127 133 def contest_time_left
128 134 if Configuration.contest_mode?
129 135 return nil if site==nil
130 136 return site.time_left
131 137 elsif Configuration.indv_contest_mode?
132 138 time_limit = Configuration.contest_time_limit
133 139 if time_limit == nil
134 140 return nil
135 141 end
136 142 if contest_stat==nil or contest_stat.started_at==nil
137 143 return (Time.now.gmtime + time_limit) - Time.now.gmtime
138 144 else
139 145 finish_time = contest_stat.started_at + time_limit
140 146 current_time = Time.now.gmtime
141 147 if current_time > finish_time
142 148 return 0
143 149 else
144 150 return finish_time - current_time
145 151 end
146 152 end
147 153 else
148 154 return nil
149 155 end
150 156 end
151 157
152 158 def contest_finished?
153 159 if Configuration.contest_mode?
154 160 return false if site==nil
155 161 return site.finished?
156 162 elsif Configuration.indv_contest_mode?
157 163 return false if self.contest_stat(true)==nil
158 164 return contest_time_left == 0
159 165 else
160 166 return false
161 167 end
162 168 end
163 169
164 170 def contest_started?
165 171 if Configuration.contest_mode?
166 172 return true if site==nil
167 173 return site.started
168 174 else
169 175 return true
170 176 end
171 177 end
172 178
173 179 def update_start_time
174 180 stat = self.contest_stat
175 181 if stat == nil or stat.started_at == nil
176 182 stat ||= UserContestStat.new(:user => self)
177 183 stat.started_at = Time.now.gmtime
178 184 stat.save
179 185 end
180 186 end
181 187
182 188 def problem_in_user_contests?(problem)
183 189 problem_contests = problem.contests.all
184 190
185 191 if problem_contests.length == 0 # this is public contest
186 192 return true
187 193 end
188 194
189 195 contests.each do |contest|
190 196 if problem_contests.find {|c| c.id == contest.id }
191 197 return true
192 198 end
193 199 end
194 200 return false
195 201 end
196 202
197 203 def available_problems_group_by_contests
198 204 contest_problems = []
199 205 pin = {}
200 206 contests.enabled.each do |contest|
201 207 available_problems = contest.problems.available
202 208 contest_problems << {
203 209 :contest => contest,
204 210 :problems => available_problems
205 211 }
206 212 available_problems.each {|p| pin[p.id] = true}
207 213 end
208 214 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
209 215 contest_problems << {
210 216 :contest => nil,
211 217 :problems => other_avaiable_problems
212 218 }
213 219 return contest_problems
214 220 end
215 221
216 222 def available_problems
217 223 if not Configuration.multicontests?
218 224 return Problem.find_available_problems
219 225 else
220 226 contest_problems = []
221 227 pin = {}
222 228 contests.enabled.each do |contest|
223 229 contest.problems.available.each do |problem|
224 230 if not pin.has_key? problem.id
225 231 contest_problems << problem
226 232 end
227 233 pin[problem.id] = true
228 234 end
229 235 end
230 236 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
231 237 return contest_problems + other_avaiable_problems
232 238 end
233 239 end
234 240
235 241 def can_view_problem?(problem)
236 242 if not Configuration.multicontests?
237 243 return problem.available
238 244 else
239 245 return problem_in_user_contests? problem
240 246 end
241 247 end
242 248
243 249 protected
244 250 def encrypt_new_password
245 251 return if password.blank?
246 252 self.salt = (10+rand(90)).to_s
247 253 self.hashed_password = User.encrypt(self.password,self.salt)
248 254 end
249 255
250 256 def assign_default_site
251 257 # have to catch error when migrating (because self.site is not available).
252 258 begin
253 259 if self.site==nil
254 260 self.site = Site.find_by_name('default')
255 261 if self.site==nil
256 262 self.site = Site.find(1) # when 'default has be renamed'
257 263 end
258 264 end
259 265 rescue
260 266 end
261 267 end
262 268
263 269 def password_required?
264 270 self.hashed_password.blank? || !self.password.blank?
265 271 end
266 272
267 273 def self.encrypt(string,salt)
268 274 Digest::SHA1.hexdigest(salt + string)
269 275 end
270 276
271 277 def uniqueness_of_email_from_activated_users
272 278 user = User.activated_users.find_by_email(self.email)
273 279 if user and (user.login != self.login)
274 280 self.errors.add_to_base("Email has already been taken")
275 281 end
276 282 end
277 283
278 284 def enough_time_interval_between_same_email_registrations
279 285 return if !self.new_record?
280 286 return if self.activated
281 287 open_user = User.find_by_email(self.email,
282 288 :order => 'created_at DESC')
283 289 if open_user and open_user.created_at and
284 290 (open_user.created_at > Time.now.gmtime - 5.minutes)
285 291 self.errors.add_to_base("There are already unactivated registrations with this e-mail address (please wait for 5 minutes)")
286 292 end
287 293 end
288 294
289 295 def email_validation?
290 296 begin
291 297 return VALIDATE_USER_EMAILS
292 298 rescue
293 299 return false
294 300 end
295 301 end
296 302 end
@@ -1,89 +1,77
1 1 <h1>Listing users</h1>
2 2
3 3 <div class="submitbox">
4 4 <b>Quick add</b>
5 5 <% form_tag :action => 'create' do %>
6 6 <table border="0">
7 7 <tr>
8 8 <td><label for="user_login">Login</label></td>
9 9 <td><label for="user_full_name">Full name</label></td>
10 10 <td><label for="user_password">Password</label></td>
11 11 <td><label for="user_password_confirmation">Confirm</label></td>
12 12 <td><label for="user_email">Email</label></td>
13 13 </tr>
14 14 <tr>
15 15 <td><%= text_field 'user', 'login', :size => 10 %></td>
16 16 <td><%= text_field 'user', 'full_name', :size => 30 %></td>
17 17 <td><%= password_field 'user', 'password', :size => 10 %></td>
18 18 <td><%= password_field 'user', 'password_confirmation', :size => 10 %></td>
19 19 <td><%= text_field 'user', 'email', :size => 15 %></td>
20 20 <td><%= submit_tag "Create" %></td>
21 21 </tr>
22 22 </table>
23 23 <% end %>
24 24 <br/>
25 25 <b>Import from site management</b>
26 26 <% form_tag({:action => 'import'}, :multipart => true) do %>
27 27 File: <%= file_field_tag 'file' %> <%= submit_tag 'Import' %>
28 28 <% end %>
29 29 <br/>
30 30 <b>What else: </b>
31 31 <%= link_to '[New user]', :action => 'new' %>
32 32 <%= link_to '[New list of users]', :action => 'new_list' %>
33 33 <%= link_to '[View administrators]', :action => 'admin' %>
34 34 <%= link_to '[Random passwords]', :action => 'random_all_passwords' %>
35 35 <%= link_to '[View active users]', :action => 'active' %>
36 36 <% if Configuration.multicontests? %>
37 + <br/><b>Multi-contest:</b>
37 38 <%= link_to '[Manage bulk users in contests]', :action => 'contest_management' %>
39 + View users in:
40 + <% @contests.each do |contest| %>
41 + <%= link_to "[#{contest.name}]", :action => 'contests', :id => contest.id %>
42 + <% end %>
43 + <%= link_to "[no contest]", :action => 'contests', :id => 'none' %>
38 44 <% end %>
39 45 </div>
40 46
41 47 <table class="info">
42 48 <tr class="info-head">
43 49 <% for column in User.content_columns %>
44 50 <% if !@hidden_columns.index(column.name) %>
45 51 <th><%= column.human_name %></th>
46 52 <% end %>
47 53 <% end %>
48 54 <th></th>
49 55 <th></th>
50 56 <th></th>
51 - <% if Configuration.multicontests? %>
52 - <th>Contests</th>
53 - <th>Other enabled contests</th>
54 - <% end %>
55 57 </tr>
56 58
57 59 <% for user in @users %>
58 60 <tr class="info-<%= cycle("odd","even") %>">
59 61 <% for column in User.content_columns %>
60 62 <% if !@hidden_columns.index(column.name) %>
61 63 <td><%=h user.send(column.name) %></td>
62 64 <% end %>
63 65 <% end %>
64 66 <td><%= link_to 'Show', :action => 'show', :id => user %></td>
65 67 <td><%= link_to 'Edit', :action => 'edit', :id => user %></td>
66 68 <td><%= link_to 'Destroy', { :action => 'destroy', :id => user }, :confirm => 'Are you sure?', :method => :post %></td>
67 - <% if Configuration.multicontests? %>
68 - <td>
69 - <% user.contests.each do |contest| %>
70 - <%= contest.name %> [<%= link_to 'x', :action => 'remove_from_contest', :id => user.id, :contest_id => contest.id %>]
71 - <% end %>
72 - </td>
73 - <td>
74 - <% @contests.each do |contest| %>
75 - <% if not user.contests.all.find {|c| c.id==contest.id } %>
76 - <%= contest.name %> [<%= link_to '+', :action => 'add_to_contest', :id => user.id, :contest_id => contest.id %>]
77 - <% end %>
78 - <% end %>
79 - </td>
80 - <% end %>
81 69 </tr>
82 70 <% end %>
83 71 </table>
84 72
85 73
86 74 <br />
87 75
88 76 <%= link_to 'New user', :action => 'new' %>
89 77 <%= link_to 'New list of users', :action => 'new_list' %>
You need to be logged in to leave comments. Login now