Description:
better user import
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r798:46ce575fc051 - - 6 files changed: 29 inserted, 18 deleted

@@ -1,290 +1,300
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 error_msg = nil
65 ok_user = []
65 ok_user = []
66
66
67 lines.split("\n").each do |line|
67 lines.split("\n").each do |line|
68 - items = line.chomp.split(',')
68 + #split with large limit, this will cause consecutive ',' to be result in a blank
69 + items = line.chomp.split(',',1000)
69 if items.length>=2
70 if items.length>=2
70 login = items[0]
71 login = items[0]
71 full_name = items[1]
72 full_name = items[1]
72 remark =''
73 remark =''
73 user_alias = ''
74 user_alias = ''
74
75
75 added_random_password = false
76 added_random_password = false
76 - if items.length >= 3 and items[2].chomp(" ").length > 0;
77 + added_password = false
77 - password = items[2].chomp(" ")
78 + if items.length >= 3
79 + if items[2].chomp(" ").length > 0
80 + password = items[2].chomp(" ")
81 + added_password = true
82 + end
78 else
83 else
79 password = random_password
84 password = random_password
80 added_random_password=true;
85 added_random_password=true;
81 end
86 end
82
87
83 if items.length>= 4 and items[3].chomp(" ").length > 0;
88 if items.length>= 4 and items[3].chomp(" ").length > 0;
84 user_alias = items[3].chomp(" ")
89 user_alias = items[3].chomp(" ")
85 else
90 else
86 user_alias = login
91 user_alias = login
87 end
92 end
88
93
94 +
95 + has_remark = false
89 if items.length>=5
96 if items.length>=5
90 remark = items[4].strip;
97 remark = items[4].strip;
98 + has_remark = true
91 end
99 end
92
100
93 user = User.find_by_login(login)
101 user = User.find_by_login(login)
94 if (user)
102 if (user)
95 user.full_name = full_name
103 user.full_name = full_name
96 - user.password = password
104 + user.remark = remark if has_remark
97 - user.remark = remark
105 + user.password = password if added_password || added_random_password
98 else
106 else
107 + #create a random password if none are given
108 + password = random_password unless password
99 user = User.new({:login => login,
109 user = User.new({:login => login,
100 :full_name => full_name,
110 :full_name => full_name,
101 :password => password,
111 :password => password,
102 :password_confirmation => password,
112 :password_confirmation => password,
103 :alias => user_alias,
113 :alias => user_alias,
104 :remark => remark})
114 :remark => remark})
105 end
115 end
106 user.activated = true
116 user.activated = true
107
117
108 if user.save
118 if user.save
109 if added_random_password
119 if added_random_password
110 note << "'#{login}' (+)"
120 note << "'#{login}' (+)"
111 else
121 else
112 note << login
122 note << login
113 end
123 end
114 ok_user << user
124 ok_user << user
115 else
125 else
116 error_note << "'#{login}'"
126 error_note << "'#{login}'"
117 error_msg = user.errors.full_messages.to_sentence unless error_msg
127 error_msg = user.errors.full_messages.to_sentence unless error_msg
118 end
128 end
119
129
120 end
130 end
121 end
131 end
122
132
123 #add to group
133 #add to group
124 if params[:add_to_group]
134 if params[:add_to_group]
125 group = Group.where(id: params[:group_id]).first
135 group = Group.where(id: params[:group_id]).first
126 if group
136 if group
127 group.users << ok_user
137 group.users << ok_user
128 end
138 end
129 end
139 end
130
140
131 # show flash
141 # show flash
132 if note.size > 0
142 if note.size > 0
133 flash[:success] = 'User(s) ' + note.join(', ') +
143 flash[:success] = 'User(s) ' + note.join(', ') +
134 ' were successfully created. ' +
144 ' were successfully created. ' +
135 '( (+) - created with random passwords.)'
145 '( (+) - created with random passwords.)'
136 end
146 end
137 if error_note.size > 0
147 if error_note.size > 0
138 flash[:error] = "Following user(s) failed to be created: " + error_note.join(', ') + ". The error of the first failed one are: " + error_msg;
148 flash[:error] = "Following user(s) failed to be created: " + error_note.join(', ') + ". The error of the first failed one are: " + error_msg;
139 end
149 end
140 redirect_to :action => 'index'
150 redirect_to :action => 'index'
141 end
151 end
142
152
143 def edit
153 def edit
144 @user = User.find(params[:id])
154 @user = User.find(params[:id])
145 end
155 end
146
156
147 def update
157 def update
148 @user = User.find(params[:id])
158 @user = User.find(params[:id])
149 if @user.update_attributes(user_params)
159 if @user.update_attributes(user_params)
150 flash[:notice] = 'User was successfully updated.'
160 flash[:notice] = 'User was successfully updated.'
151 redirect_to :action => 'show', :id => @user
161 redirect_to :action => 'show', :id => @user
152 else
162 else
153 render :action => 'edit'
163 render :action => 'edit'
154 end
164 end
155 end
165 end
156
166
157 def destroy
167 def destroy
158 User.find(params[:id]).destroy
168 User.find(params[:id]).destroy
159 redirect_to :action => 'index'
169 redirect_to :action => 'index'
160 end
170 end
161
171
162 def user_stat
172 def user_stat
163 if params[:commit] == 'download csv'
173 if params[:commit] == 'download csv'
164 @problems = Problem.all
174 @problems = Problem.all
165 else
175 else
166 @problems = Problem.available_problems
176 @problems = Problem.available_problems
167 end
177 end
168 @users = User.includes(:contests, :contest_stat).where(enabled: true)
178 @users = User.includes(:contests, :contest_stat).where(enabled: true)
169 @scorearray = Array.new
179 @scorearray = Array.new
170 @users.each do |u|
180 @users.each do |u|
171 ustat = Array.new
181 ustat = Array.new
172 ustat[0] = u
182 ustat[0] = u
173 @problems.each do |p|
183 @problems.each do |p|
174 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
184 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
175 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
185 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
176 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
186 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
177 else
187 else
178 ustat << [0,false]
188 ustat << [0,false]
179 end
189 end
180 end
190 end
181 @scorearray << ustat
191 @scorearray << ustat
182 end
192 end
183 if params[:commit] == 'download csv' then
193 if params[:commit] == 'download csv' then
184 csv = gen_csv_from_scorearray(@scorearray,@problems)
194 csv = gen_csv_from_scorearray(@scorearray,@problems)
185 send_data csv, filename: 'last_score.csv'
195 send_data csv, filename: 'last_score.csv'
186 else
196 else
187 render template: 'user_admin/user_stat'
197 render template: 'user_admin/user_stat'
188 end
198 end
189 end
199 end
190
200
191 def user_stat_max
201 def user_stat_max
192 if params[:commit] == 'download csv'
202 if params[:commit] == 'download csv'
193 @problems = Problem.all
203 @problems = Problem.all
194 else
204 else
195 @problems = Problem.available_problems
205 @problems = Problem.available_problems
196 end
206 end
197 @users = User.includes(:contests).includes(:contest_stat).all
207 @users = User.includes(:contests).includes(:contest_stat).all
198 @scorearray = Array.new
208 @scorearray = Array.new
199 #set up range from param
209 #set up range from param
200 since_id = params.fetch(:since_id, 0).to_i
210 since_id = params.fetch(:since_id, 0).to_i
201 until_id = params.fetch(:until_id, 0).to_i
211 until_id = params.fetch(:until_id, 0).to_i
202 @users.each do |u|
212 @users.each do |u|
203 ustat = Array.new
213 ustat = Array.new
204 ustat[0] = u
214 ustat[0] = u
205 @problems.each do |p|
215 @problems.each do |p|
206 max_points = 0
216 max_points = 0
207 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
217 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
208 max_points = sub.points if sub and sub.points and (sub.points > max_points)
218 max_points = sub.points if sub and sub.points and (sub.points > max_points)
209 end
219 end
210 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
220 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
211 end
221 end
212 @scorearray << ustat
222 @scorearray << ustat
213 end
223 end
214
224
215 if params[:commit] == 'download csv' then
225 if params[:commit] == 'download csv' then
216 csv = gen_csv_from_scorearray(@scorearray,@problems)
226 csv = gen_csv_from_scorearray(@scorearray,@problems)
217 send_data csv, filename: 'max_score.csv'
227 send_data csv, filename: 'max_score.csv'
218 else
228 else
219 render template: 'user_admin/user_stat'
229 render template: 'user_admin/user_stat'
220 end
230 end
221 end
231 end
222
232
223 def import
233 def import
224 if params[:file]==''
234 if params[:file]==''
225 flash[:notice] = 'Error importing no file'
235 flash[:notice] = 'Error importing no file'
226 redirect_to :action => 'index' and return
236 redirect_to :action => 'index' and return
227 end
237 end
228 import_from_file(params[:file])
238 import_from_file(params[:file])
229 end
239 end
230
240
231 def random_all_passwords
241 def random_all_passwords
232 users = User.all
242 users = User.all
233 @prefix = params[:prefix] || ''
243 @prefix = params[:prefix] || ''
234 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
244 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
235 @changed = false
245 @changed = false
236 if params[:commit] == 'Go ahead'
246 if params[:commit] == 'Go ahead'
237 @non_admin_users.each do |user|
247 @non_admin_users.each do |user|
238 password = random_password
248 password = random_password
239 user.password = password
249 user.password = password
240 user.password_confirmation = password
250 user.password_confirmation = password
241 user.save
251 user.save
242 end
252 end
243 @changed = true
253 @changed = true
244 end
254 end
245 end
255 end
246
256
247 # contest management
257 # contest management
248
258
249 def contests
259 def contests
250 @contest, @users = find_contest_and_user_from_contest_id(params[:id])
260 @contest, @users = find_contest_and_user_from_contest_id(params[:id])
251 @contests = Contest.enabled
261 @contests = Contest.enabled
252 end
262 end
253
263
254 def assign_from_list
264 def assign_from_list
255 contest_id = params[:users_contest_id]
265 contest_id = params[:users_contest_id]
256 org_contest, users = find_contest_and_user_from_contest_id(contest_id)
266 org_contest, users = find_contest_and_user_from_contest_id(contest_id)
257 contest = Contest.find(params[:new_contest][:id])
267 contest = Contest.find(params[:new_contest][:id])
258 if !contest
268 if !contest
259 flash[:notice] = 'Error: no contest'
269 flash[:notice] = 'Error: no contest'
260 redirect_to :action => 'contests', :id =>contest_id
270 redirect_to :action => 'contests', :id =>contest_id
261 end
271 end
262
272
263 note = []
273 note = []
264 users.each do |u|
274 users.each do |u|
265 u.contests = [contest]
275 u.contests = [contest]
266 note << u.login
276 note << u.login
267 end
277 end
268 flash[:notice] = 'User(s) ' + note.join(', ') +
278 flash[:notice] = 'User(s) ' + note.join(', ') +
269 " were successfully reassigned to #{contest.title}."
279 " were successfully reassigned to #{contest.title}."
270 redirect_to :action => 'contests', :id =>contest.id
280 redirect_to :action => 'contests', :id =>contest.id
271 end
281 end
272
282
273 def add_to_contest
283 def add_to_contest
274 user = User.find(params[:id])
284 user = User.find(params[:id])
275 contest = Contest.find(params[:contest_id])
285 contest = Contest.find(params[:contest_id])
276 if user and contest
286 if user and contest
277 user.contests << contest
287 user.contests << contest
278 end
288 end
279 redirect_to :action => 'index'
289 redirect_to :action => 'index'
280 end
290 end
281
291
282 def remove_from_contest
292 def remove_from_contest
283 user = User.find(params[:id])
293 user = User.find(params[:id])
284 contest = Contest.find(params[:contest_id])
294 contest = Contest.find(params[:contest_id])
285 if user and contest
295 if user and contest
286 user.contests.delete(contest)
296 user.contests.delete(contest)
287 end
297 end
288 redirect_to :action => 'index'
298 redirect_to :action => 'index'
289 end
299 end
290
300
@@ -1,225 +1,222
1 # Methods added to this helper will be available to all templates in the application.
1 # Methods added to this helper will be available to all templates in the application.
2 module ApplicationHelper
2 module ApplicationHelper
3
3
4 #new bootstrap header
4 #new bootstrap header
5 def navbar_user_header
5 def navbar_user_header
6 left_menu = ''
6 left_menu = ''
7 right_menu = ''
7 right_menu = ''
8 user = User.find(session[:user_id])
8 user = User.find(session[:user_id])
9
9
10 if (user!=nil) and (GraderConfiguration.show_tasks_to?(user))
10 if (user!=nil) and (GraderConfiguration.show_tasks_to?(user))
11 left_menu << add_menu("#{I18n.t 'menu.tasks'}", 'tasks', 'list')
11 left_menu << add_menu("#{I18n.t 'menu.tasks'}", 'tasks', 'list')
12 left_menu << add_menu("#{I18n.t 'menu.submissions'}", 'main', 'submission')
12 left_menu << add_menu("#{I18n.t 'menu.submissions'}", 'main', 'submission')
13 left_menu << add_menu("#{I18n.t 'menu.test'}", 'test', 'index')
13 left_menu << add_menu("#{I18n.t 'menu.test'}", 'test', 'index')
14 end
14 end
15
15
16 if GraderConfiguration['right.user_hall_of_fame']
16 if GraderConfiguration['right.user_hall_of_fame']
17 left_menu << add_menu("#{I18n.t 'menu.hall_of_fame'}", 'report', 'problem_hof')
17 left_menu << add_menu("#{I18n.t 'menu.hall_of_fame'}", 'report', 'problem_hof')
18 end
18 end
19
19
20 right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-question-sign')}".html_safe, 'main', 'help')
20 right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-question-sign')}".html_safe, 'main', 'help')
21 right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-comment')}".html_safe, 'messages', 'list', {title: I18n.t('menu.messages'), data: {toggle: 'tooltip'}})
21 right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-comment')}".html_safe, 'messages', 'list', {title: I18n.t('menu.messages'), data: {toggle: 'tooltip'}})
22 if GraderConfiguration['system.user_setting_enabled']
22 if GraderConfiguration['system.user_setting_enabled']
23 right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-cog')}".html_safe, 'users', 'index', {title: I18n.t('menu.settings'), data: {toggle: 'tooltip'}})
23 right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-cog')}".html_safe, 'users', 'index', {title: I18n.t('menu.settings'), data: {toggle: 'tooltip'}})
24 end
24 end
25 right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-log-out')} #{user.full_name}".html_safe, 'main', 'login', {title: I18n.t('menu.log_out'), data: {toggle: 'tooltip'}})
25 right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-log-out')} #{user.full_name}".html_safe, 'main', 'login', {title: I18n.t('menu.log_out'), data: {toggle: 'tooltip'}})
26
26
27
27
28 result = content_tag(:ul,left_menu.html_safe,class: 'nav navbar-nav') + content_tag(:ul,right_menu.html_safe,class: 'nav navbar-nav navbar-right')
28 result = content_tag(:ul,left_menu.html_safe,class: 'nav navbar-nav') + content_tag(:ul,right_menu.html_safe,class: 'nav navbar-nav navbar-right')
29 end
29 end
30
30
31 def add_menu(title, controller, action, html_option = {})
31 def add_menu(title, controller, action, html_option = {})
32 link_option = {controller: controller, action: action}
32 link_option = {controller: controller, action: action}
33 html_option[:class] = (html_option[:class] || '') + " active" if current_page?(link_option)
33 html_option[:class] = (html_option[:class] || '') + " active" if current_page?(link_option)
34 content_tag(:li, link_to(title,link_option),html_option)
34 content_tag(:li, link_to(title,link_option),html_option)
35 end
35 end
36
36
37 def user_header
37 def user_header
38 menu_items = ''
38 menu_items = ''
39 user = User.find(session[:user_id])
39 user = User.find(session[:user_id])
40
40
41 if (user!=nil) and (session[:admin])
41 if (user!=nil) and (session[:admin])
42 # admin menu
42 # admin menu
43 menu_items << "<b>Administrative task:</b> "
43 menu_items << "<b>Administrative task:</b> "
44 append_to menu_items, '[Announcements]', 'announcements', 'index'
44 append_to menu_items, '[Announcements]', 'announcements', 'index'
45 append_to menu_items, '[Msg console]', 'messages', 'console'
45 append_to menu_items, '[Msg console]', 'messages', 'console'
46 append_to menu_items, '[Problems]', 'problems', 'index'
46 append_to menu_items, '[Problems]', 'problems', 'index'
47 append_to menu_items, '[Users]', 'user_admin', 'index'
47 append_to menu_items, '[Users]', 'user_admin', 'index'
48 append_to menu_items, '[Results]', 'user_admin', 'user_stat'
48 append_to menu_items, '[Results]', 'user_admin', 'user_stat'
49 append_to menu_items, '[Report]', 'report', 'multiple_login'
49 append_to menu_items, '[Report]', 'report', 'multiple_login'
50 append_to menu_items, '[Graders]', 'graders', 'list'
50 append_to menu_items, '[Graders]', 'graders', 'list'
51 append_to menu_items, '[Contests]', 'contest_management', 'index'
51 append_to menu_items, '[Contests]', 'contest_management', 'index'
52 append_to menu_items, '[Sites]', 'sites', 'index'
52 append_to menu_items, '[Sites]', 'sites', 'index'
53 append_to menu_items, '[System config]', 'configurations', 'index'
53 append_to menu_items, '[System config]', 'configurations', 'index'
54 menu_items << "<br/>"
54 menu_items << "<br/>"
55 end
55 end
56
56
57 # main page
57 # main page
58 append_to menu_items, "[#{I18n.t 'menu.main'}]", 'main', 'list'
58 append_to menu_items, "[#{I18n.t 'menu.main'}]", 'main', 'list'
59 append_to menu_items, "[#{I18n.t 'menu.messages'}]", 'messages', 'list'
59 append_to menu_items, "[#{I18n.t 'menu.messages'}]", 'messages', 'list'
60
60
61 if (user!=nil) and (GraderConfiguration.show_tasks_to?(user))
61 if (user!=nil) and (GraderConfiguration.show_tasks_to?(user))
62 append_to menu_items, "[#{I18n.t 'menu.tasks'}]", 'tasks', 'list'
62 append_to menu_items, "[#{I18n.t 'menu.tasks'}]", 'tasks', 'list'
63 append_to menu_items, "[#{I18n.t 'menu.submissions'}]", 'main', 'submission'
63 append_to menu_items, "[#{I18n.t 'menu.submissions'}]", 'main', 'submission'
64 append_to menu_items, "[#{I18n.t 'menu.test'}]", 'test', 'index'
64 append_to menu_items, "[#{I18n.t 'menu.test'}]", 'test', 'index'
65 end
65 end
66
66
67 if GraderConfiguration['right.user_hall_of_fame']
67 if GraderConfiguration['right.user_hall_of_fame']
68 append_to menu_items, "[#{I18n.t 'menu.hall_of_fame'}]", 'report', 'problem_hof'
68 append_to menu_items, "[#{I18n.t 'menu.hall_of_fame'}]", 'report', 'problem_hof'
69 end
69 end
70 append_to menu_items, "[#{I18n.t 'menu.help'}]", 'main', 'help'
70 append_to menu_items, "[#{I18n.t 'menu.help'}]", 'main', 'help'
71
71
72 if GraderConfiguration['system.user_setting_enabled']
72 if GraderConfiguration['system.user_setting_enabled']
73 append_to menu_items, "[#{I18n.t 'menu.settings'}]", 'users', 'index'
73 append_to menu_items, "[#{I18n.t 'menu.settings'}]", 'users', 'index'
74 end
74 end
75 append_to menu_items, "[#{I18n.t 'menu.log_out'}]", 'main', 'login'
75 append_to menu_items, "[#{I18n.t 'menu.log_out'}]", 'main', 'login'
76
76
77 menu_items.html_safe
77 menu_items.html_safe
78 end
78 end
79
79
80 def append_to(option,label, controller, action)
80 def append_to(option,label, controller, action)
81 option << ' ' if option!=''
81 option << ' ' if option!=''
82 option << link_to_unless_current(label,
82 option << link_to_unless_current(label,
83 :controller => controller,
83 :controller => controller,
84 :action => action)
84 :action => action)
85 end
85 end
86
86
87 def format_short_time(time)
87 def format_short_time(time)
88 now = Time.zone.now
88 now = Time.zone.now
89 st = ''
89 st = ''
90 if (time.yday != now.yday) or (time.year != now.year)
90 if (time.yday != now.yday) or (time.year != now.year)
91 st = time.strftime("%d/%m/%y ")
91 st = time.strftime("%d/%m/%y ")
92 end
92 end
93 st + time.strftime("%X")
93 st + time.strftime("%X")
94 end
94 end
95
95
96 def format_short_duration(duration)
96 def format_short_duration(duration)
97 return '' if duration==nil
97 return '' if duration==nil
98 d = duration.to_f
98 d = duration.to_f
99 return Time.at(d).gmtime.strftime("%X")
99 return Time.at(d).gmtime.strftime("%X")
100 end
100 end
101
101
102 def format_full_time_ago(time)
102 def format_full_time_ago(time)
103 st = time_ago_in_words(time) + ' ago (' + format_short_time(time) + ')'
103 st = time_ago_in_words(time) + ' ago (' + format_short_time(time) + ')'
104 end
104 end
105
105
106 def read_textfile(fname,max_size=2048)
106 def read_textfile(fname,max_size=2048)
107 begin
107 begin
108 File.open(fname).read(max_size)
108 File.open(fname).read(max_size)
109 rescue
109 rescue
110 nil
110 nil
111 end
111 end
112 end
112 end
113
113
114 def toggle_button(on,toggle_url,id, option={})
114 def toggle_button(on,toggle_url,id, option={})
115 btn_size = option[:size] || 'btn-xs'
115 btn_size = option[:size] || 'btn-xs'
116 btn_block = option[:block] || 'btn-block'
116 btn_block = option[:block] || 'btn-block'
117 link_to (on ? "Yes" : "No"), toggle_url,
117 link_to (on ? "Yes" : "No"), toggle_url,
118 {class: "btn #{btn_block} #{btn_size} btn-#{on ? 'success' : 'default'} ajax-toggle",
118 {class: "btn #{btn_block} #{btn_size} btn-#{on ? 'success' : 'default'} ajax-toggle",
119 id: id,
119 id: id,
120 data: {remote: true, method: 'get'}}
120 data: {remote: true, method: 'get'}}
121 end
121 end
122
122
123 def get_ace_mode(language)
123 def get_ace_mode(language)
124 # return ace mode string from Language
124 # return ace mode string from Language
125
125
126 case language.pretty_name
126 case language.pretty_name
127 when 'Pascal'
127 when 'Pascal'
128 'ace/mode/pascal'
128 'ace/mode/pascal'
129 when 'C++','C'
129 when 'C++','C'
130 'ace/mode/c_cpp'
130 'ace/mode/c_cpp'
131 when 'Ruby'
131 when 'Ruby'
132 'ace/mode/ruby'
132 'ace/mode/ruby'
133 when 'Python'
133 when 'Python'
134 'ace/mode/python'
134 'ace/mode/python'
135 when 'Java'
135 when 'Java'
136 'ace/mode/java'
136 'ace/mode/java'
137 else
137 else
138 'ace/mode/c_cpp'
138 'ace/mode/c_cpp'
139 end
139 end
140 end
140 end
141
141
142
142
143 def user_title_bar(user)
143 def user_title_bar(user)
144 header = ''
144 header = ''
145 time_left = ''
145 time_left = ''
146
146
147 #
147 #
148 # if the contest is over
148 # if the contest is over
149 if GraderConfiguration.time_limit_mode?
149 if GraderConfiguration.time_limit_mode?
150 if user.contest_finished?
150 if user.contest_finished?
151 header = <<CONTEST_OVER
151 header = <<CONTEST_OVER
152 <tr><td colspan="2" align="center">
152 <tr><td colspan="2" align="center">
153 <span class="contest-over-msg">THE CONTEST IS OVER</span>
153 <span class="contest-over-msg">THE CONTEST IS OVER</span>
154 </td></tr>
154 </td></tr>
155 CONTEST_OVER
155 CONTEST_OVER
156 end
156 end
157 if !user.contest_started?
157 if !user.contest_started?
158 time_left = "&nbsp;&nbsp;" + (t 'title_bar.contest_not_started')
158 time_left = "&nbsp;&nbsp;" + (t 'title_bar.contest_not_started')
159 else
159 else
160 time_left = "&nbsp;&nbsp;" + (t 'title_bar.remaining_time') +
160 time_left = "&nbsp;&nbsp;" + (t 'title_bar.remaining_time') +
161 " #{format_short_duration(user.contest_time_left)}"
161 " #{format_short_duration(user.contest_time_left)}"
162 end
162 end
163 end
163 end
164
164
165 #
165 #
166 # if the contest is in the anaysis mode
166 # if the contest is in the anaysis mode
167 if GraderConfiguration.analysis_mode?
167 if GraderConfiguration.analysis_mode?
168 header = <<ANALYSISMODE
168 header = <<ANALYSISMODE
169 <tr><td colspan="2" align="center">
169 <tr><td colspan="2" align="center">
170 <span class="contest-over-msg">ANALYSIS MODE</span>
170 <span class="contest-over-msg">ANALYSIS MODE</span>
171 </td></tr>
171 </td></tr>
172 ANALYSISMODE
172 ANALYSISMODE
173 end
173 end
174
174
175 contest_name = GraderConfiguration['contest.name']
175 contest_name = GraderConfiguration['contest.name']
176
176
177 #
177 #
178 # build real title bar
178 # build real title bar
179 result = <<TITLEBAR
179 result = <<TITLEBAR
180 <div class="title">
180 <div class="title">
181 <table>
181 <table>
182 #{header}
182 #{header}
183 <tr>
183 <tr>
184 <td class="left-col">
184 <td class="left-col">
185 - #{user.full_name}<br/>
186 - #{t 'title_bar.current_time'} #{format_short_time(Time.zone.now)}
187 - #{time_left}
188 <br/>
185 <br/>
189 </td>
186 </td>
190 <td class="right-col">#{contest_name}</td>
187 <td class="right-col">#{contest_name}</td>
191 </tr>
188 </tr>
192 </table>
189 </table>
193 </div>
190 </div>
194 TITLEBAR
191 TITLEBAR
195 result.html_safe
192 result.html_safe
196 end
193 end
197
194
198 def markdown(text)
195 def markdown(text)
199 markdown = RDiscount.new(text)
196 markdown = RDiscount.new(text)
200 markdown.to_html.html_safe
197 markdown.to_html.html_safe
201 end
198 end
202
199
203
200
204 BOOTSTRAP_FLASH_MSG = {
201 BOOTSTRAP_FLASH_MSG = {
205 success: 'alert-success',
202 success: 'alert-success',
206 error: 'alert-danger',
203 error: 'alert-danger',
207 alert: 'alert-danger',
204 alert: 'alert-danger',
208 notice: 'alert-info'
205 notice: 'alert-info'
209 }
206 }
210
207
211 def bootstrap_class_for(flash_type)
208 def bootstrap_class_for(flash_type)
212 BOOTSTRAP_FLASH_MSG.fetch(flash_type.to_sym, flash_type.to_s)
209 BOOTSTRAP_FLASH_MSG.fetch(flash_type.to_sym, flash_type.to_s)
213 end
210 end
214
211
215 def flash_messages
212 def flash_messages
216 flash.each do |msg_type, message|
213 flash.each do |msg_type, message|
217 concat(content_tag(:div, message, class: "alert #{bootstrap_class_for(msg_type)} fade in") do
214 concat(content_tag(:div, message, class: "alert #{bootstrap_class_for(msg_type)} fade in") do
218 concat content_tag(:button, 'x', class: "close", data: { dismiss: 'alert' })
215 concat content_tag(:button, 'x', class: "close", data: { dismiss: 'alert' })
219 concat message
216 concat message
220 end)
217 end)
221 end
218 end
222 nil
219 nil
223 end
220 end
224
221
225 end
222 end
@@ -1,20 +1,14
1 module MainHelper
1 module MainHelper
2
2
3 - def link_to_description_if_any(name, problem, options={})
3 + def link_to_description_if_any(name, problem)
4 if !problem.url.blank?
4 if !problem.url.blank?
5 - return link_to name, problem.url, options
5 + return link_to name, problem.url
6 elsif !problem.description_filename.blank?
6 elsif !problem.description_filename.blank?
7 - #build a link to a problem (via task controller)
8 basename, ext = problem.description_filename.split('.')
7 basename, ext = problem.description_filename.split('.')
9 - options[:controller] = 'tasks'
8 + return link_to name, download_task_path(problem.id,basename,ext), target: '_blank'
10 - options[:action] = 'download'
11 - options[:id] = problem.id
12 - options[:file] = basename
13 - options[:ext] = ext
14 - return link_to name, options
15 else
9 else
16 return ''
10 return ''
17 end
11 end
18 end
12 end
19
13
20 end
14 end
@@ -1,112 +1,113
1 %h1= "Submission: #{@submission.id}"
1 %h1= "Submission: #{@submission.id}"
2
2
3 %textarea#data{style: "display:none;"}
3 %textarea#data{style: "display:none;"}
4 :preserve
4 :preserve
5 #{@submission.source}
5 #{@submission.source}
6
6
7 //%div.highlight{:style => "border: 1px solid black;"}
7 //%div.highlight{:style => "border: 1px solid black;"}
8 //=@formatted_code.html_safe
8 //=@formatted_code.html_safe
9
9
10
10
11 .containter
11 .containter
12 .row
12 .row
13 .col-md-7
13 .col-md-7
14 %h2 Source Code
14 %h2 Source Code
15 .col-md-5
15 .col-md-5
16 %h2 Stat
16 %h2 Stat
17 .row
17 .row
18 .col-md-7
18 .col-md-7
19 %div#editor{ style: "font-size: 14px; height: 400px; border-radius:5px;" }
19 %div#editor{ style: "font-size: 14px; height: 400px; border-radius:5px;" }
20 :javascript
20 :javascript
21 e = ace.edit("editor")
21 e = ace.edit("editor")
22 e.setOptions({ maxLines: Infinity })
22 e.setOptions({ maxLines: Infinity })
23 e.setValue($("#data").text())
23 e.setValue($("#data").text())
24 e.gotoLine(1)
24 e.gotoLine(1)
25 e.getSession().setMode("#{get_ace_mode(@submission.language)}")
25 e.getSession().setMode("#{get_ace_mode(@submission.language)}")
26 e.setReadOnly(true)
26 e.setReadOnly(true)
27 .col-md-5
27 .col-md-5
28 %table.table.table-striped
28 %table.table.table-striped
29 %tr
29 %tr
30 %td.text-right
30 %td.text-right
31 %strong User
31 %strong User
32 %td
32 %td
33 - if @submission.user
33 - if @submission.user
34 = link_to "#{@submission.user.login}", stat_user_path(@submission.user)
34 = link_to "#{@submission.user.login}", stat_user_path(@submission.user)
35 = @submission.user.full_name
35 = @submission.user.full_name
36 - else
36 - else
37 = "(n/a)"
37 = "(n/a)"
38 %tr
38 %tr
39 %td.text-right
39 %td.text-right
40 %strong Task
40 %strong Task
41 %td
41 %td
42 - if @submission.problem!=nil
42 - if @submission.problem!=nil
43 = link_to "[#{@submission.problem.name}]", stat_problem_path(@submission.problem)
43 = link_to "[#{@submission.problem.name}]", stat_problem_path(@submission.problem)
44 = @submission.problem.full_name
44 = @submission.problem.full_name
45 + = link_to_description_if_any "[download] <span class='glyphicon glyphicon-file'></span>".html_safe, @submission.problem
45 - else
46 - else
46 = "(n/a)"
47 = "(n/a)"
47 %tr
48 %tr
48 %td.text-right
49 %td.text-right
49 %strong Tries
50 %strong Tries
50 %td= @submission.number
51 %td= @submission.number
51 %tr
52 %tr
52 %td.text-right
53 %td.text-right
53 %strong Language
54 %strong Language
54 %td= @submission.language.pretty_name
55 %td= @submission.language.pretty_name
55 %tr
56 %tr
56 %td.text-right
57 %td.text-right
57 %strong Submitted
58 %strong Submitted
58 %td #{time_ago_in_words(@submission.submitted_at)} ago (at #{@submission.submitted_at.to_formatted_s(:long)})
59 %td #{time_ago_in_words(@submission.submitted_at)} ago (at #{@submission.submitted_at.to_formatted_s(:long)})
59 %tr
60 %tr
60 %td.text-right
61 %td.text-right
61 %strong Graded
62 %strong Graded
62 - if @submission.graded_at
63 - if @submission.graded_at
63 %td #{time_ago_in_words(@submission.graded_at)} ago (at #{@submission.graded_at.to_formatted_s(:long)})
64 %td #{time_ago_in_words(@submission.graded_at)} ago (at #{@submission.graded_at.to_formatted_s(:long)})
64 - else
65 - else
65 %td -
66 %td -
66 %tr
67 %tr
67 %td.text-right
68 %td.text-right
68 %strong Points
69 %strong Points
69 %td #{@submission.points}/#{@submission.try(:problem).try(:full_score)}
70 %td #{@submission.points}/#{@submission.try(:problem).try(:full_score)}
70 %tr
71 %tr
71 %td.text-right
72 %td.text-right
72 %strong Comment
73 %strong Comment
73 %td #{@submission.grader_comment}
74 %td #{@submission.grader_comment}
74 %tr
75 %tr
75 %td.text-right
76 %td.text-right
76 %strong Runtime (s)
77 %strong Runtime (s)
77 %td #{@submission.max_runtime}
78 %td #{@submission.max_runtime}
78 %tr
79 %tr
79 %td.text-right
80 %td.text-right
80 %strong Memory (kb)
81 %strong Memory (kb)
81 %td #{@submission.peak_memory}
82 %td #{@submission.peak_memory}
82 %tr
83 %tr
83 %td.text-right
84 %td.text-right
84 %strong Compiler result
85 %strong Compiler result
85 %td
86 %td
86 %button.btn.btn-info.btn-xs{type: 'button', data: {toggle: 'modal', target: '#compiler'}}
87 %button.btn.btn-info.btn-xs{type: 'button', data: {toggle: 'modal', target: '#compiler'}}
87 view
88 view
88 - if session[:admin]
89 - if session[:admin]
89 %tr
90 %tr
90 %td.text-right
91 %td.text-right
91 %strong IP
92 %strong IP
92 %td #{@submission.ip_address}
93 %td #{@submission.ip_address}
93 %tr
94 %tr
94 %td.text-right
95 %td.text-right
95 %strong Grading Task Status
96 %strong Grading Task Status
96 %td
97 %td
97 = @task.status_str if @task
98 = @task.status_str if @task
98 - if session[:admin]
99 - if session[:admin]
99 = link_to "rejudge", rejudge_submission_path, data: {remote: true}, class: 'btn btn-info btn-xs'
100 = link_to "rejudge", rejudge_submission_path, data: {remote: true}, class: 'btn btn-info btn-xs'
100
101
101
102
102 .modal.fade#compiler{tabindex: -1,role: 'dialog'}
103 .modal.fade#compiler{tabindex: -1,role: 'dialog'}
103 .modal-dialog.modal-lg{role:'document'}
104 .modal-dialog.modal-lg{role:'document'}
104 .modal-content
105 .modal-content
105 .modal-header
106 .modal-header
106 %button.close{type: 'button', data: {dismissed: :modal}, aria: {label: 'close'}}
107 %button.close{type: 'button', data: {dismissed: :modal}, aria: {label: 'close'}}
107 %span{aria: {hidden: 'true'}, data: {dismiss: 'modal'}} &times;
108 %span{aria: {hidden: 'true'}, data: {dismiss: 'modal'}} &times;
108 %h4 Compiler message
109 %h4 Compiler message
109 .modal-body
110 .modal-body
110 %pre#compiler_msg= @submission.compiler_message
111 %pre#compiler_msg= @submission.compiler_message
111 .modal-footer
112 .modal-footer
112 %button.btn.btn-default{type: 'button', data: {dismiss: 'modal'}} Close
113 %button.btn.btn-default{type: 'button', data: {dismiss: 'modal'}} Close
@@ -1,45 +1,54
1 .container-fluid
1 .container-fluid
2 .row
2 .row
3 .col-md-6
3 .col-md-6
4 %h1 Adding list of users
4 %h1 Adding list of users
5 .row
5 .row
6 .col-md-6
6 .col-md-6
7 .panel.panel-default
7 .panel.panel-default
8 .panel-heading
8 .panel-heading
9 .panel-title Info
9 .panel-title Info
10 .panel-body
10 .panel-body
11 %ul
11 %ul
12 %li
12 %li
13 List of user information in this format:
13 List of user information in this format:
14 %tt user_id,name(,passwd(,alias(,remark)))
14 %tt user_id,name(,passwd(,alias(,remark)))
15 %li
15 %li
16 Note that
16 Note that
17 %tt passwd, alias
17 %tt passwd, alias
18 and
18 and
19 %tt remark
19 %tt remark
20 is optional.
20 is optional.
21 %li
21 %li
22 When
22 When
23 %tt passwd
23 %tt passwd
24 or
24 or
25 %tt alias
25 %tt alias
26 is empty, the original value will be used instead.
26 is empty, the original value will be used instead.
27 %li
27 %li
28 If the users with the same user_id already exists, existing information will be overwritten.
28 If the users with the same user_id already exists, existing information will be overwritten.
29 + Example:
30 + %ol
31 + %li
32 + %pre user1,Somchai Jaidee
33 + will create (or update) a user with login "user1" and setting the fullname to "Somchai Jaidee", also setting a random password.
34 + %li
35 + %pre user1,Somchai Jaidee,
36 + will create (or update) a user with login "user1" and and setting the fullname "Somchai Jaidee". No change is made to the password unless this is a new user. If this is a new user, a random password will be generated.
37 +
29
38
30 .row
39 .row
31 .col-md-6
40 .col-md-6
32 = form_tag :action => 'create_from_list' do
41 = form_tag :action => 'create_from_list' do
33 .form-group
42 .form-group
34 = submit_tag 'Create following users',class: 'btn btn-success'
43 = submit_tag 'Create following users',class: 'btn btn-success'
35 .form-group
44 .form-group
36 .div.checkbox
45 .div.checkbox
37 %label
46 %label
38 = check_box_tag :add_to_group
47 = check_box_tag :add_to_group
39 Also add these users to the following group
48 Also add these users to the following group
40 = select_tag "group_id", options_from_collection_for_select( Group.all, 'id','name',params[:group_name]), id: 'group_name',class: 'select2'
49 = select_tag "group_id", options_from_collection_for_select( Group.all, 'id','name',params[:group_name]), id: 'group_name',class: 'select2'
41 .form-group
50 .form-group
42 = text_area_tag 'user_list', nil, :rows => 50, :cols => 80
51 = text_area_tag 'user_list', nil, :rows => 50, :cols => 80
43 .col-md-6
52 .col-md-6
44
53
45
54
@@ -1,204 +1,204
1 Rails.application.routes.draw do
1 Rails.application.routes.draw do
2 resources :tags
2 resources :tags
3 get "sources/direct_edit"
3 get "sources/direct_edit"
4
4
5 root :to => 'main#login'
5 root :to => 'main#login'
6
6
7 #logins
7 #logins
8 match 'login/login', to: 'login#login', via: [:get,:post]
8 match 'login/login', to: 'login#login', via: [:get,:post]
9
9
10 resources :contests
10 resources :contests
11 resources :sites
11 resources :sites
12 resources :test
12 resources :test
13
13
14 resources :messages do
14 resources :messages do
15 member do
15 member do
16 get 'hide'
16 get 'hide'
17 post 'reply'
17 post 'reply'
18 end
18 end
19 collection do
19 collection do
20 get 'console'
20 get 'console'
21 get 'list_all'
21 get 'list_all'
22 end
22 end
23 end
23 end
24
24
25 resources :announcements do
25 resources :announcements do
26 member do
26 member do
27 get 'toggle','toggle_front'
27 get 'toggle','toggle_front'
28 end
28 end
29 end
29 end
30
30
31 resources :problems do
31 resources :problems do
32 member do
32 member do
33 get 'toggle'
33 get 'toggle'
34 get 'toggle_test'
34 get 'toggle_test'
35 get 'toggle_view_testcase'
35 get 'toggle_view_testcase'
36 get 'stat'
36 get 'stat'
37 end
37 end
38 collection do
38 collection do
39 get 'turn_all_off'
39 get 'turn_all_off'
40 get 'turn_all_on'
40 get 'turn_all_on'
41 get 'import'
41 get 'import'
42 get 'manage'
42 get 'manage'
43 get 'quick_create'
43 get 'quick_create'
44 post 'do_manage'
44 post 'do_manage'
45 post 'do_import'
45 post 'do_import'
46 end
46 end
47 end
47 end
48
48
49 resources :groups do
49 resources :groups do
50 member do
50 member do
51 post 'add_user', to: 'groups#add_user', as: 'add_user'
51 post 'add_user', to: 'groups#add_user', as: 'add_user'
52 delete 'remove_user/:user_id', to: 'groups#remove_user', as: 'remove_user'
52 delete 'remove_user/:user_id', to: 'groups#remove_user', as: 'remove_user'
53 delete 'remove_all_user', to: 'groups#remove_all_user', as: 'remove_all_user'
53 delete 'remove_all_user', to: 'groups#remove_all_user', as: 'remove_all_user'
54 post 'add_problem', to: 'groups#add_problem', as: 'add_problem'
54 post 'add_problem', to: 'groups#add_problem', as: 'add_problem'
55 delete 'remove_problem/:problem_id', to: 'groups#remove_problem', as: 'remove_problem'
55 delete 'remove_problem/:problem_id', to: 'groups#remove_problem', as: 'remove_problem'
56 delete 'remove_all_problem', to: 'groups#remove_all_problem', as: 'remove_all_problem'
56 delete 'remove_all_problem', to: 'groups#remove_all_problem', as: 'remove_all_problem'
57 get 'toggle'
57 get 'toggle'
58 end
58 end
59 collection do
59 collection do
60
60
61 end
61 end
62 end
62 end
63
63
64 resources :testcases, only: [] do
64 resources :testcases, only: [] do
65 member do
65 member do
66 get 'download_input'
66 get 'download_input'
67 get 'download_sol'
67 get 'download_sol'
68 end
68 end
69 collection do
69 collection do
70 get 'show_problem/:problem_id(/:test_num)' => 'testcases#show_problem', as: 'show_problem'
70 get 'show_problem/:problem_id(/:test_num)' => 'testcases#show_problem', as: 'show_problem'
71 end
71 end
72 end
72 end
73
73
74 resources :grader_configuration, controller: 'configurations' do
74 resources :grader_configuration, controller: 'configurations' do
75 collection do
75 collection do
76 get 'set_exam_right(/:value)', action: 'set_exam_right', as: 'set_exam_right'
76 get 'set_exam_right(/:value)', action: 'set_exam_right', as: 'set_exam_right'
77 end
77 end
78 end
78 end
79
79
80 resources :users do
80 resources :users do
81 member do
81 member do
82 get 'toggle_activate', 'toggle_enable'
82 get 'toggle_activate', 'toggle_enable'
83 get 'stat'
83 get 'stat'
84 end
84 end
85 collection do
85 collection do
86 get 'profile'
86 get 'profile'
87 post 'chg_passwd'
87 post 'chg_passwd'
88 end
88 end
89 end
89 end
90
90
91 resources :submissions do
91 resources :submissions do
92 member do
92 member do
93 get 'download'
93 get 'download'
94 get 'compiler_msg'
94 get 'compiler_msg'
95 get 'rejudge'
95 get 'rejudge'
96 end
96 end
97 collection do
97 collection do
98 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
98 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
99 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
99 get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
100 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
100 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
101 end
101 end
102 end
102 end
103
103
104
104
105 #user admin
105 #user admin
106 resources :user_admin do
106 resources :user_admin do
107 collection do
107 collection do
108 match 'bulk_manage', via: [:get, :post]
108 match 'bulk_manage', via: [:get, :post]
109 get 'bulk_mail'
109 get 'bulk_mail'
110 get 'user_stat'
110 get 'user_stat'
111 get 'import'
111 get 'import'
112 get 'new_list'
112 get 'new_list'
113 get 'admin'
113 get 'admin'
114 get 'active'
114 get 'active'
115 get 'mass_mailing'
115 get 'mass_mailing'
116 get 'revoke_admin'
116 get 'revoke_admin'
117 post 'grant_admin'
117 post 'grant_admin'
118 match 'create_from_list', via: [:get, :post]
118 match 'create_from_list', via: [:get, :post]
119 match 'random_all_passwords', via: [:get, :post]
119 match 'random_all_passwords', via: [:get, :post]
120 end
120 end
121 member do
121 member do
122 get 'clear_last_ip'
122 get 'clear_last_ip'
123 end
123 end
124 end
124 end
125
125
126 resources :contest_management, only: [:index] do
126 resources :contest_management, only: [:index] do
127 collection do
127 collection do
128 get 'user_stat'
128 get 'user_stat'
129 get 'clear_stat'
129 get 'clear_stat'
130 get 'clear_all_stat'
130 get 'clear_all_stat'
131 get 'change_contest_mode'
131 get 'change_contest_mode'
132 end
132 end
133 end
133 end
134
134
135 #get 'user_admin', to: 'user_admin#index'
135 #get 'user_admin', to: 'user_admin#index'
136 #get 'user_admin/bulk_manage', to: 'user_admin#bulk_manage', as: 'bulk_manage_user_admin'
136 #get 'user_admin/bulk_manage', to: 'user_admin#bulk_manage', as: 'bulk_manage_user_admin'
137 #post 'user_admin', to: 'user_admin#create'
137 #post 'user_admin', to: 'user_admin#create'
138 #delete 'user_admin/:id', to: 'user_admin#destroy', as: 'user_admin_destroy'
138 #delete 'user_admin/:id', to: 'user_admin#destroy', as: 'user_admin_destroy'
139
139
140 #singular resource
140 #singular resource
141 #---- BEWARE ---- singular resource maps to plural controller by default, we can override by provide controller name directly
141 #---- BEWARE ---- singular resource maps to plural controller by default, we can override by provide controller name directly
142 #report
142 #report
143 resource :report, only: [], controller: 'report' do
143 resource :report, only: [], controller: 'report' do
144 get 'login'
144 get 'login'
145 get 'multiple_login'
145 get 'multiple_login'
146 get 'problem_hof(/:id)', action: 'problem_hof', as: 'problem_hof'
146 get 'problem_hof(/:id)', action: 'problem_hof', as: 'problem_hof'
147 get 'current_score(/:group_id)', action: 'current_score', as: 'current_score'
147 get 'current_score(/:group_id)', action: 'current_score', as: 'current_score'
148 get 'max_score'
148 get 'max_score'
149 post 'show_max_score'
149 post 'show_max_score'
150 get 'stuck'
150 get 'stuck'
151 get 'cheat_report'
151 get 'cheat_report'
152 post 'cheat_report'
152 post 'cheat_report'
153 get 'cheat_scruntinize'
153 get 'cheat_scruntinize'
154 post 'cheat_scruntinize'
154 post 'cheat_scruntinize'
155 end
155 end
156 #get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
156 #get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
157 #get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
157 #get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
158 #get "report/login"
158 #get "report/login"
159 #get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
159 #get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
160 #post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
160 #post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
161
161
162 resource :main, only: [], controller: 'main' do
162 resource :main, only: [], controller: 'main' do
163 get 'login'
163 get 'login'
164 get 'logout'
164 get 'logout'
165 get 'list'
165 get 'list'
166 get 'submission(/:id)', action: 'submission', as: 'main_submission'
166 get 'submission(/:id)', action: 'submission', as: 'main_submission'
167 get 'announcements'
167 get 'announcements'
168 get 'help'
168 get 'help'
169 post 'submit'
169 post 'submit'
170 end
170 end
171 #main
171 #main
172 #get "main/list"
172 #get "main/list"
173 #get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
173 #get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
174 #post 'main/submit', to: 'main#submit'
174 #post 'main/submit', to: 'main#submit'
175 #get 'main/announcements', to: 'main#announcements'
175 #get 'main/announcements', to: 'main#announcements'
176
176
177
177
178 #
178 #
179 get 'tasks/view/:file.:ext' => 'tasks#view'
179 get 'tasks/view/:file.:ext' => 'tasks#view'
180 - get 'tasks/download/:id/:file.:ext' => 'tasks#download'
180 + get 'tasks/download/:id/:file.:ext' => 'tasks#download', as: 'download_task'
181 get 'heartbeat/:id/edit' => 'heartbeat#edit'
181 get 'heartbeat/:id/edit' => 'heartbeat#edit'
182
182
183 #grader
183 #grader
184 get 'graders/list', to: 'graders#list', as: 'grader_list'
184 get 'graders/list', to: 'graders#list', as: 'grader_list'
185 namespace :graders do
185 namespace :graders do
186 get 'task/:id/:type', action: 'task', as: 'task'
186 get 'task/:id/:type', action: 'task', as: 'task'
187 get 'view/:id/:type', action: 'view', as: 'view'
187 get 'view/:id/:type', action: 'view', as: 'view'
188 get 'clear/:id', action: 'clear', as: 'clear'
188 get 'clear/:id', action: 'clear', as: 'clear'
189 get 'stop'
189 get 'stop'
190 get 'stop_all'
190 get 'stop_all'
191 get 'clear_all'
191 get 'clear_all'
192 get 'clear_terminated'
192 get 'clear_terminated'
193 get 'start_grading'
193 get 'start_grading'
194 get 'start_exam'
194 get 'start_exam'
195
195
196 end
196 end
197
197
198
198
199 # See how all your routes lay out with "rake routes"
199 # See how all your routes lay out with "rake routes"
200
200
201 # This is a legacy wild controller route that's not recommended for RESTful applications.
201 # This is a legacy wild controller route that's not recommended for RESTful applications.
202 # Note: This route will make all actions in every controller accessible via GET requests.
202 # Note: This route will make all actions in every controller accessible via GET requests.
203 # match ':controller(/:action(/:id))(.:format)', via: [:get, :post]
203 # match ':controller(/:action(/:id))(.:format)', via: [:get, :post]
204 end
204 end
You need to be logged in to leave comments. Login now