Description:
manages users in contests
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r280:f8e3b2e72e4a - - 7 files changed: 111 inserted, 7 deleted

@@ -0,0 +1,16
1 + %h1 Bulk edit users in contests
2 +
3 + - form_tag :action => 'manage_contest' do
4 + List users' login below; one per line.
5 + %br/
6 + = text_area_tag 'login_list', nil, :rows => 25, :cols => 80
7 + %br/
8 + You want to
9 + = select(nil,"operation",[['add users to','add'],['remove users from','remove']])
10 + contest
11 + = select("contest","id",Contest.all.collect {|c| [c.title, c.id]})
12 +     
13 + = submit_tag "Perform action", :confirm => 'Are you sure?'
14 +
15 + %hr/
16 + = link_to '[go back to index]', :action => 'index'
@@ -1,66 +1,67
1 class UserAdminController < ApplicationController
1 class UserAdminController < ApplicationController
2
2
3 before_filter :admin_authorization
3 before_filter :admin_authorization
4
4
5 def index
5 def index
6 list
6 list
7 render :action => 'list'
7 render :action => 'list'
8 end
8 end
9
9
10 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
10 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
11 verify :method => :post, :only => [ :destroy,
11 verify :method => :post, :only => [ :destroy,
12 :create, :create_from_list,
12 :create, :create_from_list,
13 :update ],
13 :update ],
14 :redirect_to => { :action => :list }
14 :redirect_to => { :action => :list }
15
15
16 def list
16 def list
17 @users = User.find(:all)
17 @users = User.find(:all)
18 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
18 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
19 + @contests = Contest.all(:conditions => {:enabled => true})
19 end
20 end
20
21
21 def active
22 def active
22 sessions = ActiveRecord::SessionStore::Session.find(:all, :conditions => ["updated_at >= ?", 60.minutes.ago])
23 sessions = ActiveRecord::SessionStore::Session.find(:all, :conditions => ["updated_at >= ?", 60.minutes.ago])
23 @users = []
24 @users = []
24 sessions.each do |session|
25 sessions.each do |session|
25 if session.data[:user_id]
26 if session.data[:user_id]
26 @users << User.find(session.data[:user_id])
27 @users << User.find(session.data[:user_id])
27 end
28 end
28 end
29 end
29 end
30 end
30
31
31 def show
32 def show
32 @user = User.find(params[:id])
33 @user = User.find(params[:id])
33 end
34 end
34
35
35 def new
36 def new
36 @user = User.new
37 @user = User.new
37 end
38 end
38
39
39 def create
40 def create
40 @user = User.new(params[:user])
41 @user = User.new(params[:user])
41 @user.activated = true
42 @user.activated = true
42 if @user.save
43 if @user.save
43 flash[:notice] = 'User was successfully created.'
44 flash[:notice] = 'User was successfully created.'
44 redirect_to :action => 'list'
45 redirect_to :action => 'list'
45 else
46 else
46 render :action => 'new'
47 render :action => 'new'
47 end
48 end
48 end
49 end
49
50
50 def create_from_list
51 def create_from_list
51 lines = params[:user_list]
52 lines = params[:user_list]
52
53
53 note = []
54 note = []
54
55
55 lines.split("\n").each do |line|
56 lines.split("\n").each do |line|
56 items = line.chomp.split(',')
57 items = line.chomp.split(',')
57 if items.length>=2
58 if items.length>=2
58 login = items[0]
59 login = items[0]
59 full_name = items[1]
60 full_name = items[1]
60
61
61 added_random_password = false
62 added_random_password = false
62 if items.length>=3
63 if items.length>=3
63 password = items[2]
64 password = items[2]
64 user_alias = (items.length>=4) ? items[3] : login
65 user_alias = (items.length>=4) ? items[3] : login
65 else
66 else
66 password = random_password
67 password = random_password
@@ -106,96 +107,158
106 def destroy
107 def destroy
107 User.find(params[:id]).destroy
108 User.find(params[:id]).destroy
108 redirect_to :action => 'list'
109 redirect_to :action => 'list'
109 end
110 end
110
111
111 def user_stat
112 def user_stat
112 @problems = Problem.find_available_problems
113 @problems = Problem.find_available_problems
113 @users = User.find(:all)
114 @users = User.find(:all)
114 @scorearray = Array.new
115 @scorearray = Array.new
115 @users.each do |u|
116 @users.each do |u|
116 ustat = Array.new
117 ustat = Array.new
117 ustat[0] = u
118 ustat[0] = u
118 @problems.each do |p|
119 @problems.each do |p|
119 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
120 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
120 if (sub!=nil) and (sub.points!=nil)
121 if (sub!=nil) and (sub.points!=nil)
121 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
122 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
122 else
123 else
123 ustat << [0,false]
124 ustat << [0,false]
124 end
125 end
125 end
126 end
126 @scorearray << ustat
127 @scorearray << ustat
127 end
128 end
128 end
129 end
129
130
130 def import
131 def import
131 if params[:file]==''
132 if params[:file]==''
132 flash[:notice] = 'Error importing no file'
133 flash[:notice] = 'Error importing no file'
133 redirect_to :action => 'list' and return
134 redirect_to :action => 'list' and return
134 end
135 end
135 import_from_file(params[:file])
136 import_from_file(params[:file])
136 end
137 end
137
138
138 def random_all_passwords
139 def random_all_passwords
139 users = User.find(:all)
140 users = User.find(:all)
140 @prefix = params[:prefix] || ''
141 @prefix = params[:prefix] || ''
141 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
142 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
142 @changed = false
143 @changed = false
143 if request.request_method == :post
144 if request.request_method == :post
144 @non_admin_users.each do |user|
145 @non_admin_users.each do |user|
145 password = random_password
146 password = random_password
146 user.password = password
147 user.password = password
147 user.password_confirmation = password
148 user.password_confirmation = password
148 user.save
149 user.save
149 end
150 end
150 @changed = true
151 @changed = true
151 end
152 end
152 end
153 end
153
154
155 + # contest management
156 +
157 + def add_to_contest
158 + user = User.find(params[:id])
159 + contest = Contest.find(params[:contest_id])
160 + if user and contest
161 + user.contests << contest
162 + end
163 + redirect_to :action => 'list'
164 + end
165 +
166 + def remove_from_contest
167 + user = User.find(params[:id])
168 + contest = Contest.find(params[:contest_id])
169 + if user and contest
170 + user.contests.delete(contest)
171 + end
172 + redirect_to :action => 'list'
173 + end
174 +
175 + def contest_management
176 + end
177 +
178 + def manage_contest
179 + contest = Contest.find(params[:contest][:id])
180 + if !contest
181 + flash[:notice] = 'You did not choose the contest.'
182 + redirect_to :action => 'contest_management' and return
183 + end
184 +
185 + operation = params[:operation]
186 +
187 + if operation!='add' and operation!='remove'
188 + flash[:notice] = 'You did not choose the operation to perform.'
189 + redirect_to :action => 'contest_management' and return
190 + end
191 +
192 + lines = params[:login_list]
193 + if !lines or lines.blank?
194 + flash[:notice] = 'You entered an empty list.'
195 + redirect_to :action => 'contest_management' and return
196 + end
197 +
198 + note = []
199 + lines.split("\n").each do |line|
200 + puts line
201 + user = User.find_by_login(line.chomp)
202 + puts user
203 + if user
204 + if operation=='add'
205 + user.contests << contest
206 + else
207 + user.contests.delete(contest)
208 + end
209 + note << user.login
210 + end
211 + end
212 + flash[:notice] = 'User(s) ' + note.join(', ') +
213 + ' were successfully modified. '
214 + redirect_to :action => 'contest_management'
215 + end
216 +
154 # admin management
217 # admin management
155
218
156 def admin
219 def admin
157 @admins = User.find(:all).find_all {|user| user.admin? }
220 @admins = User.find(:all).find_all {|user| user.admin? }
158 end
221 end
159
222
160 def grant_admin
223 def grant_admin
161 login = params[:login]
224 login = params[:login]
162 user = User.find_by_login(login)
225 user = User.find_by_login(login)
163 if user!=nil
226 if user!=nil
164 admin_role = Role.find_by_name('admin')
227 admin_role = Role.find_by_name('admin')
165 user.roles << admin_role
228 user.roles << admin_role
166 else
229 else
167 flash[:notice] = 'Unknown user'
230 flash[:notice] = 'Unknown user'
168 end
231 end
169 flash[:notice] = 'User added as admins'
232 flash[:notice] = 'User added as admins'
170 redirect_to :action => 'admin'
233 redirect_to :action => 'admin'
171 end
234 end
172
235
173 def revoke_admin
236 def revoke_admin
174 user = User.find(params[:id])
237 user = User.find(params[:id])
175 if user==nil
238 if user==nil
176 flash[:notice] = 'Unknown user'
239 flash[:notice] = 'Unknown user'
177 redirect_to :action => 'admin' and return
240 redirect_to :action => 'admin' and return
178 elsif user.login == 'root'
241 elsif user.login == 'root'
179 flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
242 flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
180 redirect_to :action => 'admin' and return
243 redirect_to :action => 'admin' and return
181 end
244 end
182
245
183 admin_role = Role.find_by_name('admin')
246 admin_role = Role.find_by_name('admin')
184 user.roles.delete(admin_role)
247 user.roles.delete(admin_role)
185 flash[:notice] = 'User permission revoked'
248 flash[:notice] = 'User permission revoked'
186 redirect_to :action => 'admin'
249 redirect_to :action => 'admin'
187 end
250 end
188
251
189 protected
252 protected
190
253
191 def random_password(length=5)
254 def random_password(length=5)
192 chars = 'abcdefghijkmnopqrstuvwxyz23456789'
255 chars = 'abcdefghijkmnopqrstuvwxyz23456789'
193 newpass = ""
256 newpass = ""
194 length.times { newpass << chars[rand(chars.size-1)] }
257 length.times { newpass << chars[rand(chars.size-1)] }
195 return newpass
258 return newpass
196 end
259 end
197
260
198 def import_from_file(f)
261 def import_from_file(f)
199 data_hash = YAML.load(f)
262 data_hash = YAML.load(f)
200 @import_log = ""
263 @import_log = ""
201
264
@@ -1,52 +1,52
1 class Problem < ActiveRecord::Base
1 class Problem < ActiveRecord::Base
2
2
3 belongs_to :description
3 belongs_to :description
4 - has_and_belongs_to_many :contests
4 + has_and_belongs_to_many :contests, :uniq => true
5 has_many :test_pairs, :dependent => :delete_all
5 has_many :test_pairs, :dependent => :delete_all
6
6
7 validates_presence_of :name
7 validates_presence_of :name
8 validates_format_of :name, :with => /^\w+$/
8 validates_format_of :name, :with => /^\w+$/
9 validates_presence_of :full_name
9 validates_presence_of :full_name
10
10
11 named_scope :available, :conditions => {:available => true}
11 named_scope :available, :conditions => {:available => true}
12
12
13 DEFAULT_TIME_LIMIT = 1
13 DEFAULT_TIME_LIMIT = 1
14 DEFAULT_MEMORY_LIMIT = 32
14 DEFAULT_MEMORY_LIMIT = 32
15
15
16 def self.find_available_problems
16 def self.find_available_problems
17 Problem.available.all(:order => "date_added DESC")
17 Problem.available.all(:order => "date_added DESC")
18 end
18 end
19
19
20 def self.create_from_import_form_params(params, old_problem=nil)
20 def self.create_from_import_form_params(params, old_problem=nil)
21 problem = old_problem || Problem.new
21 problem = old_problem || Problem.new
22 import_params = Problem.extract_params_and_check(params, problem)
22 import_params = Problem.extract_params_and_check(params, problem)
23
23
24 if not problem.valid?
24 if not problem.valid?
25 return problem, 'Error importing'
25 return problem, 'Error importing'
26 end
26 end
27
27
28 problem.full_score = 100
28 problem.full_score = 100
29 problem.date_added = Time.new
29 problem.date_added = Time.new
30 problem.test_allowed = true
30 problem.test_allowed = true
31 problem.output_only = false
31 problem.output_only = false
32 problem.available = false
32 problem.available = false
33
33
34 if not problem.save
34 if not problem.save
35 return problem, 'Error importing'
35 return problem, 'Error importing'
36 end
36 end
37
37
38 import_to_db = params.has_key? :import_to_db
38 import_to_db = params.has_key? :import_to_db
39
39
40 importer = TestdataImporter.new(problem)
40 importer = TestdataImporter.new(problem)
41
41
42 if not importer.import_from_file(import_params[:file],
42 if not importer.import_from_file(import_params[:file],
43 import_params[:time_limit],
43 import_params[:time_limit],
44 import_params[:memory_limit],
44 import_params[:memory_limit],
45 import_to_db)
45 import_to_db)
46 problem.errors.add_to_base('Import error.')
46 problem.errors.add_to_base('Import error.')
47 end
47 end
48
48
49 return problem, importer.log_msg
49 return problem, importer.log_msg
50 end
50 end
51
51
52 def self.download_file_basedir
52 def self.download_file_basedir
@@ -1,72 +1,72
1 require 'digest/sha1'
1 require 'digest/sha1'
2
2
3 class User < ActiveRecord::Base
3 class User < ActiveRecord::Base
4
4
5 has_and_belongs_to_many :roles
5 has_and_belongs_to_many :roles
6
6
7 has_many :test_requests, :order => "submitted_at DESC"
7 has_many :test_requests, :order => "submitted_at DESC"
8
8
9 has_many :messages,
9 has_many :messages,
10 :class_name => "Message",
10 :class_name => "Message",
11 :foreign_key => "sender_id",
11 :foreign_key => "sender_id",
12 :order => 'created_at DESC'
12 :order => 'created_at DESC'
13
13
14 has_many :replied_messages,
14 has_many :replied_messages,
15 :class_name => "Message",
15 :class_name => "Message",
16 :foreign_key => "receiver_id",
16 :foreign_key => "receiver_id",
17 :order => 'created_at DESC'
17 :order => 'created_at DESC'
18
18
19 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
19 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
20
20
21 belongs_to :site
21 belongs_to :site
22 belongs_to :country
22 belongs_to :country
23
23
24 - has_and_belongs_to_many :contests
24 + has_and_belongs_to_many :contests, :uniq => true
25
25
26 named_scope :activated_users, :conditions => {:activated => true}
26 named_scope :activated_users, :conditions => {:activated => true}
27
27
28 validates_presence_of :login
28 validates_presence_of :login
29 validates_uniqueness_of :login
29 validates_uniqueness_of :login
30 validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
30 validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
31 validates_length_of :login, :within => 3..30
31 validates_length_of :login, :within => 3..30
32
32
33 validates_presence_of :full_name
33 validates_presence_of :full_name
34 validates_length_of :full_name, :minimum => 1
34 validates_length_of :full_name, :minimum => 1
35
35
36 validates_presence_of :password, :if => :password_required?
36 validates_presence_of :password, :if => :password_required?
37 validates_length_of :password, :within => 4..20, :if => :password_required?
37 validates_length_of :password, :within => 4..20, :if => :password_required?
38 validates_confirmation_of :password, :if => :password_required?
38 validates_confirmation_of :password, :if => :password_required?
39
39
40 validates_format_of :email,
40 validates_format_of :email,
41 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
41 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
42 :if => :email_validation?
42 :if => :email_validation?
43 validate :uniqueness_of_email_from_activated_users,
43 validate :uniqueness_of_email_from_activated_users,
44 :if => :email_validation?
44 :if => :email_validation?
45 validate :enough_time_interval_between_same_email_registrations,
45 validate :enough_time_interval_between_same_email_registrations,
46 :if => :email_validation?
46 :if => :email_validation?
47
47
48 # these are for ytopc
48 # these are for ytopc
49 # disable for now
49 # disable for now
50 #validates_presence_of :province
50 #validates_presence_of :province
51
51
52 attr_accessor :password
52 attr_accessor :password
53
53
54 before_save :encrypt_new_password
54 before_save :encrypt_new_password
55 before_save :assign_default_site
55 before_save :assign_default_site
56
56
57 def self.authenticate(login, password)
57 def self.authenticate(login, password)
58 user = find_by_login(login)
58 user = find_by_login(login)
59 return user if user && user.authenticated?(password)
59 return user if user && user.authenticated?(password)
60 end
60 end
61
61
62 def authenticated?(password)
62 def authenticated?(password)
63 if self.activated
63 if self.activated
64 hashed_password == User.encrypt(password,self.salt)
64 hashed_password == User.encrypt(password,self.salt)
65 else
65 else
66 false
66 false
67 end
67 end
68 end
68 end
69
69
70 def admin?
70 def admin?
71 self.roles.detect {|r| r.name == 'admin' }
71 self.roles.detect {|r| r.name == 'admin' }
72 end
72 end
@@ -1,51 +1,52
1 - content_for :head do
1 - content_for :head do
2 = javascript_include_tag :defaults
2 = javascript_include_tag :defaults
3 = javascript_include_tag 'announcement_refresh.js'
3 = javascript_include_tag 'announcement_refresh.js'
4
4
5 = user_title_bar(@user)
5 = user_title_bar(@user)
6
6
7 .announcementbox{:style => (@announcements.length==0 ? "display:none" : "")}
7 .announcementbox{:style => (@announcements.length==0 ? "display:none" : "")}
8 %span{:class => 'title'}
8 %span{:class => 'title'}
9 Announcements
9 Announcements
10 #announcementbox-body
10 #announcementbox-body
11 = render :partial => 'announcement', :collection => @announcements
11 = render :partial => 'announcement', :collection => @announcements
12
12
13 - if Configuration.show_submitbox_to?(@user)
13 - if Configuration.show_submitbox_to?(@user)
14 .submitbox
14 .submitbox
15 = error_messages_for 'submission'
15 = error_messages_for 'submission'
16 = render :partial => 'submission_box'
16 = render :partial => 'submission_box'
17
17
18
18
19 %hr/
19 %hr/
20
20
21 - if (Configuration.contest_mode?) and (@user.site!=nil) and (@user.site.started!=true)
21 - if (Configuration.contest_mode?) and (@user.site!=nil) and (@user.site.started!=true)
22 %p=t 'main.start_soon'
22 %p=t 'main.start_soon'
23
23
24 - if Configuration.show_tasks_to?(@user)
24 - if Configuration.show_tasks_to?(@user)
25 - if not Configuration.multicontests?
25 - if not Configuration.multicontests?
26 %table.info
26 %table.info
27 %tr.info-head
27 %tr.info-head
28 %th
28 %th
29 %th Tasks
29 %th Tasks
30 %th # of sub(s)
30 %th # of sub(s)
31 %th Results
31 %th Results
32 = render :partial => 'problem', :collection => @problems
32 = render :partial => 'problem', :collection => @problems
33 - else
33 - else
34 - @contest_problems.each do |cp|
34 - @contest_problems.each do |cp|
35 + - if cp[:problems].length > 0
35 %h2{:class =>'contest-title'}
36 %h2{:class =>'contest-title'}
36 = "#{cp[:contest] ? cp[:contest].title : 'Public problems'}"
37 = "#{cp[:contest] ? cp[:contest].title : 'Public problems'}"
37 %table.info
38 %table.info
38 %tr.info-head
39 %tr.info-head
39 %th
40 %th
40 %th Tasks
41 %th Tasks
41 %th # of sub(s)
42 %th # of sub(s)
42 %th Results
43 %th Results
43 = render :partial => 'problem', :collection => cp[:problems]
44 = render :partial => 'problem', :collection => cp[:problems]
44
45
45
46
46 %hr/
47 %hr/
47
48
48 %script{:type => 'text/javascript'}
49 %script{:type => 'text/javascript'}
49 = "Announcement.refreshUrl = '#{url_for :controller => 'main', :action => 'announcements'}';"
50 = "Announcement.refreshUrl = '#{url_for :controller => 'main', :action => 'announcements'}';"
50 Announcement.registerRefreshEventTimer();
51 Announcement.registerRefreshEventTimer();
51
52
@@ -1,25 +1,25
1 %h1 Administrators
1 %h1 Administrators
2
2
3 - %table
3 + %table{:class => 'info'}
4 - %tr
4 + %tr{:class => 'info-head'}
5 %th #
5 %th #
6 %th Login
6 %th Login
7 %th Full name
7 %th Full name
8 %th
8 %th
9 - @admins.each_with_index do |user, i|
9 - @admins.each_with_index do |user, i|
10 %tr
10 %tr
11 %td= i+1
11 %td= i+1
12 %td= user.login
12 %td= user.login
13 %td= user.full_name
13 %td= user.full_name
14 %td
14 %td
15 - if user.login!='root'
15 - if user.login!='root'
16 = link_to '[revoke]', :action => 'revoke_admin', :id => user.id
16 = link_to '[revoke]', :action => 'revoke_admin', :id => user.id
17 %hr
17 %hr
18
18
19 - form_tag :action => 'grant_admin' do
19 - form_tag :action => 'grant_admin' do
20 Grant admin permission to:
20 Grant admin permission to:
21 = text_field_tag 'login'
21 = text_field_tag 'login'
22 = submit_tag 'Grant'
22 = submit_tag 'Grant'
23
23
24 %hr/
24 %hr/
25 = link_to '[go back to index]', :action => 'index'
25 = link_to '[go back to index]', :action => 'index'
@@ -1,65 +1,89
1 <h1>Listing users</h1>
1 <h1>Listing users</h1>
2
2
3 <div class="submitbox">
3 <div class="submitbox">
4 <b>Quick add</b>
4 <b>Quick add</b>
5 <% form_tag :action => 'create' do %>
5 <% form_tag :action => 'create' do %>
6 <table border="0">
6 <table border="0">
7 <tr>
7 <tr>
8 <td><label for="user_login">Login</label></td>
8 <td><label for="user_login">Login</label></td>
9 <td><label for="user_full_name">Full name</label></td>
9 <td><label for="user_full_name">Full name</label></td>
10 <td><label for="user_password">Password</label></td>
10 <td><label for="user_password">Password</label></td>
11 <td><label for="user_password_confirmation">Confirm</label></td>
11 <td><label for="user_password_confirmation">Confirm</label></td>
12 <td><label for="user_email">Email</label></td>
12 <td><label for="user_email">Email</label></td>
13 </tr>
13 </tr>
14 <tr>
14 <tr>
15 <td><%= text_field 'user', 'login', :size => 10 %></td>
15 <td><%= text_field 'user', 'login', :size => 10 %></td>
16 <td><%= text_field 'user', 'full_name', :size => 30 %></td>
16 <td><%= text_field 'user', 'full_name', :size => 30 %></td>
17 <td><%= password_field 'user', 'password', :size => 10 %></td>
17 <td><%= password_field 'user', 'password', :size => 10 %></td>
18 <td><%= password_field 'user', 'password_confirmation', :size => 10 %></td>
18 <td><%= password_field 'user', 'password_confirmation', :size => 10 %></td>
19 <td><%= text_field 'user', 'email', :size => 15 %></td>
19 <td><%= text_field 'user', 'email', :size => 15 %></td>
20 <td><%= submit_tag "Create" %></td>
20 <td><%= submit_tag "Create" %></td>
21 </tr>
21 </tr>
22 </table>
22 </table>
23 <% end %>
23 <% end %>
24 <br/>
24 <br/>
25 <b>Import from site management</b>
25 <b>Import from site management</b>
26 <% form_tag({:action => 'import'}, :multipart => true) do %>
26 <% form_tag({:action => 'import'}, :multipart => true) do %>
27 File: <%= file_field_tag 'file' %> <%= submit_tag 'Import' %>
27 File: <%= file_field_tag 'file' %> <%= submit_tag 'Import' %>
28 <% end %>
28 <% end %>
29 <br/>
29 <br/>
30 <b>What else: </b>
30 <b>What else: </b>
31 <%= link_to '[New user]', :action => 'new' %>
31 <%= link_to '[New user]', :action => 'new' %>
32 <%= link_to '[New list of users]', :action => 'new_list' %>
32 <%= link_to '[New list of users]', :action => 'new_list' %>
33 <%= link_to '[View administrators]', :action => 'admin' %>
33 <%= link_to '[View administrators]', :action => 'admin' %>
34 <%= link_to '[Random passwords]', :action => 'random_all_passwords' %>
34 <%= link_to '[Random passwords]', :action => 'random_all_passwords' %>
35 <%= link_to '[View active users]', :action => 'active' %>
35 <%= link_to '[View active users]', :action => 'active' %>
36 + <% if Configuration.multicontests? %>
37 + <%= link_to '[Manage bulk users in contests]', :action => 'contest_management' %>
38 + <% end %>
36 </div>
39 </div>
37
40
38 - <table>
41 + <table class="info">
39 - <tr>
42 + <tr class="info-head">
40 <% for column in User.content_columns %>
43 <% for column in User.content_columns %>
41 <% if !@hidden_columns.index(column.name) %>
44 <% if !@hidden_columns.index(column.name) %>
42 <th><%= column.human_name %></th>
45 <th><%= column.human_name %></th>
43 <% end %>
46 <% end %>
44 <% end %>
47 <% end %>
48 + <th></th>
49 + <th></th>
50 + <th></th>
51 + <% if Configuration.multicontests? %>
52 + <th>Contests</th>
53 + <th>Other enabled contests</th>
54 + <% end %>
45 </tr>
55 </tr>
46
56
47 <% for user in @users %>
57 <% for user in @users %>
48 - <tr>
58 + <tr class="info-<%= cycle("odd","even") %>">
49 <% for column in User.content_columns %>
59 <% for column in User.content_columns %>
50 <% if !@hidden_columns.index(column.name) %>
60 <% if !@hidden_columns.index(column.name) %>
51 <td><%=h user.send(column.name) %></td>
61 <td><%=h user.send(column.name) %></td>
52 <% end %>
62 <% end %>
53 <% end %>
63 <% end %>
54 <td><%= link_to 'Show', :action => 'show', :id => user %></td>
64 <td><%= link_to 'Show', :action => 'show', :id => user %></td>
55 <td><%= link_to 'Edit', :action => 'edit', :id => user %></td>
65 <td><%= link_to 'Edit', :action => 'edit', :id => user %></td>
56 <td><%= link_to 'Destroy', { :action => 'destroy', :id => user }, :confirm => 'Are you sure?', :method => :post %></td>
66 <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 %>
57 </tr>
81 </tr>
58 <% end %>
82 <% end %>
59 </table>
83 </table>
60
84
61
85
62 <br />
86 <br />
63
87
64 <%= link_to 'New user', :action => 'new' %>
88 <%= link_to 'New user', :action => 'new' %>
65 <%= link_to 'New list of users', :action => 'new_list' %>
89 <%= link_to 'New list of users', :action => 'new_list' %>
You need to be logged in to leave comments. Login now