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: 28 inserted, 17 deleted

@@ -1,194 +1,204
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
78 + if items.length >= 3
79 + if items[2].chomp(" ").length > 0
77 password = items[2].chomp(" ")
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
@@ -89,137 +89,134
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
@@ -84,121 +84,121
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