Description:
- fix pdf loading fail
Commit status:
[Not Reviewed]
References:
Diff options:
Comments:
0 Commit comments
0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
r634:56cf4357ce2a - - 4 files changed: 11 inserted, 4 deleted
@@ -1,288 +1,294 | |||
|
1 | 1 | class ProblemsController < ApplicationController |
|
2 | 2 | |
|
3 | 3 | before_action :authenticate, :authorization |
|
4 | 4 | before_action :testcase_authorization, only: [:show_testcase] |
|
5 | 5 | |
|
6 | 6 | in_place_edit_for :problem, :name |
|
7 | 7 | in_place_edit_for :problem, :full_name |
|
8 | 8 | in_place_edit_for :problem, :full_score |
|
9 | 9 | |
|
10 | 10 | def index |
|
11 | 11 | @problems = Problem.order(date_added: :desc) |
|
12 | 12 | end |
|
13 | 13 | |
|
14 | 14 | # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html) |
|
15 | 15 | verify :method => :post, :only => [ :create, :quick_create, |
|
16 | 16 | :do_manage, |
|
17 | 17 | :do_import, |
|
18 | 18 | ], |
|
19 | 19 | :redirect_to => { :action => :index } |
|
20 | 20 | |
|
21 | 21 | def show |
|
22 | 22 | @problem = Problem.find(params[:id]) |
|
23 | 23 | end |
|
24 | 24 | |
|
25 | 25 | def new |
|
26 | 26 | @problem = Problem.new |
|
27 | 27 | @description = nil |
|
28 | 28 | end |
|
29 | 29 | |
|
30 | 30 | def create |
|
31 | 31 | @problem = Problem.new(params[:problem]) |
|
32 | 32 | @description = Description.new(params[:description]) |
|
33 | 33 | if @description.body!='' |
|
34 | 34 | if !@description.save |
|
35 | 35 | render :action => new and return |
|
36 | 36 | end |
|
37 | 37 | else |
|
38 | 38 | @description = nil |
|
39 | 39 | end |
|
40 | 40 | @problem.description = @description |
|
41 | 41 | if @problem.save |
|
42 | 42 | flash[:notice] = 'Problem was successfully created.' |
|
43 | 43 | redirect_to action: :index |
|
44 | 44 | else |
|
45 | 45 | render :action => 'new' |
|
46 | 46 | end |
|
47 | 47 | end |
|
48 | 48 | |
|
49 | 49 | def quick_create |
|
50 | 50 | @problem = Problem.new(params[:problem]) |
|
51 | 51 | @problem.full_name = @problem.name if @problem.full_name == '' |
|
52 | 52 | @problem.full_score = 100 |
|
53 | 53 | @problem.available = false |
|
54 | 54 | @problem.test_allowed = true |
|
55 | 55 | @problem.output_only = false |
|
56 | 56 | @problem.date_added = Time.new |
|
57 | 57 | if @problem.save |
|
58 | 58 | flash[:notice] = 'Problem was successfully created.' |
|
59 | 59 | redirect_to action: :index |
|
60 | 60 | else |
|
61 | 61 | flash[:notice] = 'Error saving problem' |
|
62 | 62 | redirect_to action: :index |
|
63 | 63 | end |
|
64 | 64 | end |
|
65 | 65 | |
|
66 | 66 | def edit |
|
67 | 67 | @problem = Problem.find(params[:id]) |
|
68 | 68 | @description = @problem.description |
|
69 | 69 | end |
|
70 | 70 | |
|
71 | 71 | def update |
|
72 | 72 | @problem = Problem.find(params[:id]) |
|
73 | 73 | @description = @problem.description |
|
74 | 74 | if @description.nil? and params[:description][:body]!='' |
|
75 | 75 | @description = Description.new(params[:description]) |
|
76 | 76 | if !@description.save |
|
77 | 77 | flash[:notice] = 'Error saving description' |
|
78 | 78 | render :action => 'edit' and return |
|
79 | 79 | end |
|
80 | 80 | @problem.description = @description |
|
81 | 81 | elsif @description |
|
82 | 82 | if !@description.update_attributes(params[:description]) |
|
83 | 83 | flash[:notice] = 'Error saving description' |
|
84 | 84 | render :action => 'edit' and return |
|
85 | 85 | end |
|
86 | 86 | end |
|
87 | 87 | if params[:file] and params[:file].content_type != 'application/pdf' |
|
88 | 88 | flash[:notice] = 'Error: Uploaded file is not PDF' |
|
89 | 89 | render :action => 'edit' and return |
|
90 | 90 | end |
|
91 |
- if @problem.update_attributes( |
|
|
91 | + if @problem.update_attributes(problem_params) | |
|
92 | 92 | flash[:notice] = 'Problem was successfully updated.' |
|
93 | 93 | unless params[:file] == nil or params[:file] == '' |
|
94 | 94 | flash[:notice] = 'Problem was successfully updated and a new PDF file is uploaded.' |
|
95 | 95 | out_dirname = "#{Problem.download_file_basedir}/#{@problem.id}" |
|
96 | 96 | if not FileTest.exists? out_dirname |
|
97 | 97 | Dir.mkdir out_dirname |
|
98 | 98 | end |
|
99 | 99 | |
|
100 | 100 | out_filename = "#{out_dirname}/#{@problem.name}.pdf" |
|
101 | 101 | if FileTest.exists? out_filename |
|
102 | 102 | File.delete out_filename |
|
103 | 103 | end |
|
104 | 104 | |
|
105 | 105 | File.open(out_filename,"wb") do |file| |
|
106 | 106 | file.write(params[:file].read) |
|
107 | 107 | end |
|
108 | 108 | @problem.description_filename = "#{@problem.name}.pdf" |
|
109 | 109 | @problem.save |
|
110 | 110 | end |
|
111 | 111 | redirect_to :action => 'show', :id => @problem |
|
112 | 112 | else |
|
113 | 113 | render :action => 'edit' |
|
114 | 114 | end |
|
115 | 115 | end |
|
116 | 116 | |
|
117 | 117 | def destroy |
|
118 | 118 | p = Problem.find(params[:id]).destroy |
|
119 | 119 | redirect_to action: :index |
|
120 | 120 | end |
|
121 | 121 | |
|
122 | 122 | def toggle |
|
123 | 123 | @problem = Problem.find(params[:id]) |
|
124 | 124 | @problem.update_attributes(available: !(@problem.available) ) |
|
125 | 125 | respond_to do |format| |
|
126 | 126 | format.js { } |
|
127 | 127 | end |
|
128 | 128 | end |
|
129 | 129 | |
|
130 | 130 | def toggle_test |
|
131 | 131 | @problem = Problem.find(params[:id]) |
|
132 | 132 | @problem.update_attributes(test_allowed: !(@problem.test_allowed?) ) |
|
133 | 133 | respond_to do |format| |
|
134 | 134 | format.js { } |
|
135 | 135 | end |
|
136 | 136 | end |
|
137 | 137 | |
|
138 | 138 | def toggle_view_testcase |
|
139 | 139 | @problem = Problem.find(params[:id]) |
|
140 | 140 | @problem.update_attributes(view_testcase: !(@problem.view_testcase?) ) |
|
141 | 141 | respond_to do |format| |
|
142 | 142 | format.js { } |
|
143 | 143 | end |
|
144 | 144 | end |
|
145 | 145 | |
|
146 | 146 | def turn_all_off |
|
147 | 147 | Problem.available.all.each do |problem| |
|
148 | 148 | problem.available = false |
|
149 | 149 | problem.save |
|
150 | 150 | end |
|
151 | 151 | redirect_to action: :index |
|
152 | 152 | end |
|
153 | 153 | |
|
154 | 154 | def turn_all_on |
|
155 | 155 | Problem.where.not(available: true).each do |problem| |
|
156 | 156 | problem.available = true |
|
157 | 157 | problem.save |
|
158 | 158 | end |
|
159 | 159 | redirect_to action: :index |
|
160 | 160 | end |
|
161 | 161 | |
|
162 | 162 | def stat |
|
163 | 163 | @problem = Problem.find(params[:id]) |
|
164 | 164 | unless @problem.available or session[:admin] |
|
165 | 165 | redirect_to :controller => 'main', :action => 'list' |
|
166 | 166 | return |
|
167 | 167 | end |
|
168 | 168 | @submissions = Submission.includes(:user).where(problem_id: params[:id]).order(:user_id,:id) |
|
169 | 169 | |
|
170 | 170 | #stat summary |
|
171 | 171 | range =65 |
|
172 | 172 | @histogram = { data: Array.new(range,0), summary: {} } |
|
173 | 173 | user = Hash.new(0) |
|
174 | 174 | @submissions.find_each do |sub| |
|
175 | 175 | d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60 |
|
176 | 176 | @histogram[:data][d.to_i] += 1 if d < range |
|
177 | 177 | user[sub.user_id] = [user[sub.user_id], ((sub.try(:points) || 0) >= @problem.full_score) ? 1 : 0].max |
|
178 | 178 | end |
|
179 | 179 | @histogram[:summary][:max] = [@histogram[:data].max,1].max |
|
180 | 180 | |
|
181 | 181 | @summary = { attempt: user.count, solve: 0 } |
|
182 | 182 | user.each_value { |v| @summary[:solve] += 1 if v == 1 } |
|
183 | 183 | end |
|
184 | 184 | |
|
185 | 185 | def manage |
|
186 | 186 | @problems = Problem.order(date_added: :desc) |
|
187 | 187 | end |
|
188 | 188 | |
|
189 | 189 | def do_manage |
|
190 | 190 | if params.has_key? 'change_date_added' |
|
191 | 191 | change_date_added |
|
192 | 192 | elsif params.has_key? 'add_to_contest' |
|
193 | 193 | add_to_contest |
|
194 | 194 | elsif params.has_key? 'enable_problem' |
|
195 | 195 | set_available(true) |
|
196 | 196 | elsif params.has_key? 'disable_problem' |
|
197 | 197 | set_available(false) |
|
198 | 198 | end |
|
199 | 199 | redirect_to :action => 'manage' |
|
200 | 200 | end |
|
201 | 201 | |
|
202 | 202 | def import |
|
203 | 203 | @allow_test_pair_import = allow_test_pair_import? |
|
204 | 204 | end |
|
205 | 205 | |
|
206 | 206 | def do_import |
|
207 | 207 | old_problem = Problem.find_by_name(params[:name]) |
|
208 | 208 | if !allow_test_pair_import? and params.has_key? :import_to_db |
|
209 | 209 | params.delete :import_to_db |
|
210 | 210 | end |
|
211 | 211 | @problem, import_log = Problem.create_from_import_form_params(params, |
|
212 | 212 | old_problem) |
|
213 | 213 | |
|
214 | 214 | if !@problem.errors.empty? |
|
215 | 215 | render :action => 'import' and return |
|
216 | 216 | end |
|
217 | 217 | |
|
218 | 218 | if old_problem!=nil |
|
219 | 219 | flash[:notice] = "The test data has been replaced for problem #{@problem.name}" |
|
220 | 220 | end |
|
221 | 221 | @log = import_log |
|
222 | 222 | end |
|
223 | 223 | |
|
224 | 224 | def remove_contest |
|
225 | 225 | problem = Problem.find(params[:id]) |
|
226 | 226 | contest = Contest.find(params[:contest_id]) |
|
227 | 227 | if problem!=nil and contest!=nil |
|
228 | 228 | problem.contests.delete(contest) |
|
229 | 229 | end |
|
230 | 230 | redirect_to :action => 'manage' |
|
231 | 231 | end |
|
232 | 232 | |
|
233 | 233 | ################################## |
|
234 | 234 | protected |
|
235 | 235 | |
|
236 | 236 | def allow_test_pair_import? |
|
237 | 237 | if defined? ALLOW_TEST_PAIR_IMPORT |
|
238 | 238 | return ALLOW_TEST_PAIR_IMPORT |
|
239 | 239 | else |
|
240 | 240 | return false |
|
241 | 241 | end |
|
242 | 242 | end |
|
243 | 243 | |
|
244 | 244 | def change_date_added |
|
245 | 245 | problems = get_problems_from_params |
|
246 | 246 | year = params[:date_added][:year].to_i |
|
247 | 247 | month = params[:date_added][:month].to_i |
|
248 | 248 | day = params[:date_added][:day].to_i |
|
249 | 249 | date = Date.new(year,month,day) |
|
250 | 250 | problems.each do |p| |
|
251 | 251 | p.date_added = date |
|
252 | 252 | p.save |
|
253 | 253 | end |
|
254 | 254 | end |
|
255 | 255 | |
|
256 | 256 | def add_to_contest |
|
257 | 257 | problems = get_problems_from_params |
|
258 | 258 | contest = Contest.find(params[:contest][:id]) |
|
259 | 259 | if contest!=nil and contest.enabled |
|
260 | 260 | problems.each do |p| |
|
261 | 261 | p.contests << contest |
|
262 | 262 | end |
|
263 | 263 | end |
|
264 | 264 | end |
|
265 | 265 | |
|
266 | 266 | def set_available(avail) |
|
267 | 267 | problems = get_problems_from_params |
|
268 | 268 | problems.each do |p| |
|
269 | 269 | p.available = avail |
|
270 | 270 | p.save |
|
271 | 271 | end |
|
272 | 272 | end |
|
273 | 273 | |
|
274 | 274 | def get_problems_from_params |
|
275 | 275 | problems = [] |
|
276 | 276 | params.keys.each do |k| |
|
277 | 277 | if k.index('prob-')==0 |
|
278 | 278 | name, id, order = k.split('-') |
|
279 | 279 | problems << Problem.find(id) |
|
280 | 280 | end |
|
281 | 281 | end |
|
282 | 282 | problems |
|
283 | 283 | end |
|
284 | 284 | |
|
285 | 285 | def get_problems_stat |
|
286 | 286 | end |
|
287 | 287 | |
|
288 | + private | |
|
289 | + | |
|
290 | + def problem_params | |
|
291 | + params.require(:problem).permit(:name, :full_name, :full_score, :date_added, :available, :test_allowed,:output_only, :url, :description) | |
|
288 | 292 | end |
|
293 | + | |
|
294 | + end |
@@ -1,505 +1,505 | |||
|
1 | 1 | require 'csv' |
|
2 | 2 | |
|
3 | 3 | class UserAdminController < ApplicationController |
|
4 | 4 | |
|
5 | 5 | include MailHelperMethods |
|
6 | 6 | |
|
7 | 7 | before_filter :admin_authorization |
|
8 | 8 | |
|
9 | 9 | # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html) |
|
10 | 10 | verify :method => :post, :only => [ |
|
11 | 11 | :create, :create_from_list, |
|
12 | 12 | :update, |
|
13 | 13 | :manage_contest, |
|
14 | 14 | :bulk_mail |
|
15 | 15 | ], |
|
16 | 16 | :redirect_to => { :action => :list } |
|
17 | 17 | |
|
18 | 18 | def index |
|
19 | 19 | @user_count = User.count |
|
20 | 20 | if params[:page] == 'all' |
|
21 | 21 | @users = User.all |
|
22 | 22 | @paginated = false |
|
23 | 23 | else |
|
24 | 24 | @users = User.paginate :page => params[:page] |
|
25 | 25 | @paginated = true |
|
26 | 26 | end |
|
27 | 27 | @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at'] |
|
28 | 28 | @contests = Contest.enabled |
|
29 | 29 | end |
|
30 | 30 | |
|
31 | 31 | def active |
|
32 | 32 | sessions = ActiveRecord::SessionStore::Session.where("updated_at >= ?", 60.minutes.ago) |
|
33 | 33 | @users = [] |
|
34 | 34 | sessions.each do |session| |
|
35 | 35 | if session.data[:user_id] |
|
36 | 36 | @users << User.find(session.data[:user_id]) |
|
37 | 37 | end |
|
38 | 38 | end |
|
39 | 39 | end |
|
40 | 40 | |
|
41 | 41 | def show |
|
42 | 42 | @user = User.find(params[:id]) |
|
43 | 43 | end |
|
44 | 44 | |
|
45 | 45 | def new |
|
46 | 46 | @user = User.new |
|
47 | 47 | end |
|
48 | 48 | |
|
49 | 49 | def create |
|
50 | 50 | @user = User.new(params[:user]) |
|
51 | 51 | @user.activated = true |
|
52 | 52 | if @user.save |
|
53 | 53 | flash[:notice] = 'User was successfully created.' |
|
54 | 54 | redirect_to :action => 'index' |
|
55 | 55 | else |
|
56 | 56 | render :action => 'new' |
|
57 | 57 | end |
|
58 | 58 | end |
|
59 | 59 | |
|
60 | 60 | def clear_last_ip |
|
61 | 61 | @user = User.find(params[:id]) |
|
62 | 62 | @user.last_ip = nil |
|
63 | 63 | @user.save |
|
64 | 64 | redirect_to action: 'index', page: params[:page] |
|
65 | 65 | end |
|
66 | 66 | |
|
67 | 67 | def create_from_list |
|
68 | 68 | lines = params[:user_list] |
|
69 | 69 | |
|
70 | 70 | note = [] |
|
71 | 71 | |
|
72 | 72 | lines.split("\n").each do |line| |
|
73 | 73 | items = line.chomp.split(',') |
|
74 | 74 | if items.length>=2 |
|
75 | 75 | login = items[0] |
|
76 | 76 | full_name = items[1] |
|
77 | 77 | remark ='' |
|
78 | 78 | user_alias = '' |
|
79 | 79 | |
|
80 | 80 | added_random_password = false |
|
81 | 81 | if items.length >= 3 and items[2].chomp(" ").length > 0; |
|
82 | 82 | password = items[2].chomp(" ") |
|
83 | 83 | else |
|
84 | 84 | password = random_password |
|
85 | 85 | add_random_password=true; |
|
86 | 86 | end |
|
87 | 87 | |
|
88 | 88 | if items.length>= 4 and items[3].chomp(" ").length > 0; |
|
89 | 89 | user_alias = items[3].chomp(" ") |
|
90 | 90 | else |
|
91 | 91 | user_alias = login |
|
92 | 92 | end |
|
93 | 93 | |
|
94 | 94 | if items.length>=5 |
|
95 | 95 | remark = items[4].strip; |
|
96 | 96 | end |
|
97 | 97 | |
|
98 | 98 | user = User.find_by_login(login) |
|
99 | 99 | if (user) |
|
100 | 100 | user.full_name = full_name |
|
101 | 101 | user.password = password |
|
102 | 102 | user.remark = remark |
|
103 | 103 | else |
|
104 | 104 | user = User.new({:login => login, |
|
105 | 105 | :full_name => full_name, |
|
106 | 106 | :password => password, |
|
107 | 107 | :password_confirmation => password, |
|
108 | 108 | :alias => user_alias, |
|
109 | 109 | :remark => remark}) |
|
110 | 110 | end |
|
111 | 111 | user.activated = true |
|
112 | 112 | user.save |
|
113 | 113 | |
|
114 | 114 | if added_random_password |
|
115 | 115 | note << "'#{login}' (+)" |
|
116 | 116 | else |
|
117 | 117 | note << login |
|
118 | 118 | end |
|
119 | 119 | end |
|
120 | 120 | end |
|
121 |
- flash[: |
|
|
121 | + flash[:success] = 'User(s) ' + note.join(', ') + | |
|
122 | 122 | ' were successfully created. ' + |
|
123 | 123 | '( (+) - created with random passwords.)' |
|
124 | 124 | redirect_to :action => 'index' |
|
125 | 125 | end |
|
126 | 126 | |
|
127 | 127 | def edit |
|
128 | 128 | @user = User.find(params[:id]) |
|
129 | 129 | end |
|
130 | 130 | |
|
131 | 131 | def update |
|
132 | 132 | @user = User.find(params[:id]) |
|
133 | 133 | if @user.update_attributes(user_params) |
|
134 | 134 | flash[:notice] = 'User was successfully updated.' |
|
135 | 135 | redirect_to :action => 'show', :id => @user |
|
136 | 136 | else |
|
137 | 137 | render :action => 'edit' |
|
138 | 138 | end |
|
139 | 139 | end |
|
140 | 140 | |
|
141 | 141 | def destroy |
|
142 | 142 | User.find(params[:id]).destroy |
|
143 | 143 | redirect_to :action => 'index' |
|
144 | 144 | end |
|
145 | 145 | |
|
146 | 146 | def user_stat |
|
147 | 147 | if params[:commit] == 'download csv' |
|
148 | 148 | @problems = Problem.all |
|
149 | 149 | else |
|
150 | 150 | @problems = Problem.available_problems |
|
151 | 151 | end |
|
152 | 152 | @users = User.includes(:contests, :contest_stat).where(enabled: true) |
|
153 | 153 | @scorearray = Array.new |
|
154 | 154 | @users.each do |u| |
|
155 | 155 | ustat = Array.new |
|
156 | 156 | ustat[0] = u |
|
157 | 157 | @problems.each do |p| |
|
158 | 158 | sub = Submission.find_last_by_user_and_problem(u.id,p.id) |
|
159 | 159 | if (sub!=nil) and (sub.points!=nil) and p and p.full_score |
|
160 | 160 | ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)] |
|
161 | 161 | else |
|
162 | 162 | ustat << [0,false] |
|
163 | 163 | end |
|
164 | 164 | end |
|
165 | 165 | @scorearray << ustat |
|
166 | 166 | end |
|
167 | 167 | if params[:commit] == 'download csv' then |
|
168 | 168 | csv = gen_csv_from_scorearray(@scorearray,@problems) |
|
169 | 169 | send_data csv, filename: 'last_score.csv' |
|
170 | 170 | else |
|
171 | 171 | render template: 'user_admin/user_stat' |
|
172 | 172 | end |
|
173 | 173 | end |
|
174 | 174 | |
|
175 | 175 | def user_stat_max |
|
176 | 176 | if params[:commit] == 'download csv' |
|
177 | 177 | @problems = Problem.all |
|
178 | 178 | else |
|
179 | 179 | @problems = Problem.available_problems |
|
180 | 180 | end |
|
181 | 181 | @users = User.includes(:contests).includes(:contest_stat).all |
|
182 | 182 | @scorearray = Array.new |
|
183 | 183 | #set up range from param |
|
184 | 184 | since_id = params.fetch(:since_id, 0).to_i |
|
185 | 185 | until_id = params.fetch(:until_id, 0).to_i |
|
186 | 186 | @users.each do |u| |
|
187 | 187 | ustat = Array.new |
|
188 | 188 | ustat[0] = u |
|
189 | 189 | @problems.each do |p| |
|
190 | 190 | max_points = 0 |
|
191 | 191 | Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub| |
|
192 | 192 | max_points = sub.points if sub and sub.points and (sub.points > max_points) |
|
193 | 193 | end |
|
194 | 194 | ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)] |
|
195 | 195 | end |
|
196 | 196 | @scorearray << ustat |
|
197 | 197 | end |
|
198 | 198 | |
|
199 | 199 | if params[:commit] == 'download csv' then |
|
200 | 200 | csv = gen_csv_from_scorearray(@scorearray,@problems) |
|
201 | 201 | send_data csv, filename: 'max_score.csv' |
|
202 | 202 | else |
|
203 | 203 | render template: 'user_admin/user_stat' |
|
204 | 204 | end |
|
205 | 205 | end |
|
206 | 206 | |
|
207 | 207 | def import |
|
208 | 208 | if params[:file]=='' |
|
209 | 209 | flash[:notice] = 'Error importing no file' |
|
210 | 210 | redirect_to :action => 'index' and return |
|
211 | 211 | end |
|
212 | 212 | import_from_file(params[:file]) |
|
213 | 213 | end |
|
214 | 214 | |
|
215 | 215 | def random_all_passwords |
|
216 | 216 | users = User.all |
|
217 | 217 | @prefix = params[:prefix] || '' |
|
218 | 218 | @non_admin_users = User.find_non_admin_with_prefix(@prefix) |
|
219 | 219 | @changed = false |
|
220 | 220 | if request.request_method == 'POST' |
|
221 | 221 | @non_admin_users.each do |user| |
|
222 | 222 | password = random_password |
|
223 | 223 | user.password = password |
|
224 | 224 | user.password_confirmation = password |
|
225 | 225 | user.save |
|
226 | 226 | end |
|
227 | 227 | @changed = true |
|
228 | 228 | end |
|
229 | 229 | end |
|
230 | 230 | |
|
231 | 231 | # contest management |
|
232 | 232 | |
|
233 | 233 | def contests |
|
234 | 234 | @contest, @users = find_contest_and_user_from_contest_id(params[:id]) |
|
235 | 235 | @contests = Contest.enabled |
|
236 | 236 | end |
|
237 | 237 | |
|
238 | 238 | def assign_from_list |
|
239 | 239 | contest_id = params[:users_contest_id] |
|
240 | 240 | org_contest, users = find_contest_and_user_from_contest_id(contest_id) |
|
241 | 241 | contest = Contest.find(params[:new_contest][:id]) |
|
242 | 242 | if !contest |
|
243 | 243 | flash[:notice] = 'Error: no contest' |
|
244 | 244 | redirect_to :action => 'contests', :id =>contest_id |
|
245 | 245 | end |
|
246 | 246 | |
|
247 | 247 | note = [] |
|
248 | 248 | users.each do |u| |
|
249 | 249 | u.contests = [contest] |
|
250 | 250 | note << u.login |
|
251 | 251 | end |
|
252 | 252 | flash[:notice] = 'User(s) ' + note.join(', ') + |
|
253 | 253 | " were successfully reassigned to #{contest.title}." |
|
254 | 254 | redirect_to :action => 'contests', :id =>contest.id |
|
255 | 255 | end |
|
256 | 256 | |
|
257 | 257 | def add_to_contest |
|
258 | 258 | user = User.find(params[:id]) |
|
259 | 259 | contest = Contest.find(params[:contest_id]) |
|
260 | 260 | if user and contest |
|
261 | 261 | user.contests << contest |
|
262 | 262 | end |
|
263 | 263 | redirect_to :action => 'index' |
|
264 | 264 | end |
|
265 | 265 | |
|
266 | 266 | def remove_from_contest |
|
267 | 267 | user = User.find(params[:id]) |
|
268 | 268 | contest = Contest.find(params[:contest_id]) |
|
269 | 269 | if user and contest |
|
270 | 270 | user.contests.delete(contest) |
|
271 | 271 | end |
|
272 | 272 | redirect_to :action => 'index' |
|
273 | 273 | end |
|
274 | 274 | |
|
275 | 275 | def contest_management |
|
276 | 276 | end |
|
277 | 277 | |
|
278 | 278 | def manage_contest |
|
279 | 279 | contest = Contest.find(params[:contest][:id]) |
|
280 | 280 | if !contest |
|
281 | 281 | flash[:notice] = 'You did not choose the contest.' |
|
282 | 282 | redirect_to :action => 'contest_management' and return |
|
283 | 283 | end |
|
284 | 284 | |
|
285 | 285 | operation = params[:operation] |
|
286 | 286 | |
|
287 | 287 | if not ['add','remove','assign'].include? operation |
|
288 | 288 | flash[:notice] = 'You did not choose the operation to perform.' |
|
289 | 289 | redirect_to :action => 'contest_management' and return |
|
290 | 290 | end |
|
291 | 291 | |
|
292 | 292 | lines = params[:login_list] |
|
293 | 293 | if !lines or lines.blank? |
|
294 | 294 | flash[:notice] = 'You entered an empty list.' |
|
295 | 295 | redirect_to :action => 'contest_management' and return |
|
296 | 296 | end |
|
297 | 297 | |
|
298 | 298 | note = [] |
|
299 | 299 | users = [] |
|
300 | 300 | lines.split("\n").each do |line| |
|
301 | 301 | user = User.find_by_login(line.chomp) |
|
302 | 302 | if user |
|
303 | 303 | if operation=='add' |
|
304 | 304 | if ! user.contests.include? contest |
|
305 | 305 | user.contests << contest |
|
306 | 306 | end |
|
307 | 307 | elsif operation=='remove' |
|
308 | 308 | user.contests.delete(contest) |
|
309 | 309 | else |
|
310 | 310 | user.contests = [contest] |
|
311 | 311 | end |
|
312 | 312 | |
|
313 | 313 | if params[:reset_timer] |
|
314 | 314 | user.contest_stat.forced_logout = true |
|
315 | 315 | user.contest_stat.reset_timer_and_save |
|
316 | 316 | end |
|
317 | 317 | |
|
318 | 318 | if params[:notification_emails] |
|
319 | 319 | send_contest_update_notification_email(user, contest) |
|
320 | 320 | end |
|
321 | 321 | |
|
322 | 322 | note << user.login |
|
323 | 323 | users << user |
|
324 | 324 | end |
|
325 | 325 | end |
|
326 | 326 | |
|
327 | 327 | if params[:reset_timer] |
|
328 | 328 | logout_users(users) |
|
329 | 329 | end |
|
330 | 330 | |
|
331 | 331 | flash[:notice] = 'User(s) ' + note.join(', ') + |
|
332 | 332 | ' were successfully modified. ' |
|
333 | 333 | redirect_to :action => 'contest_management' |
|
334 | 334 | end |
|
335 | 335 | |
|
336 | 336 | # admin management |
|
337 | 337 | |
|
338 | 338 | def admin |
|
339 | 339 | @admins = User.all.find_all {|user| user.admin? } |
|
340 | 340 | end |
|
341 | 341 | |
|
342 | 342 | def grant_admin |
|
343 | 343 | login = params[:login] |
|
344 | 344 | user = User.find_by_login(login) |
|
345 | 345 | if user!=nil |
|
346 | 346 | admin_role = Role.find_by_name('admin') |
|
347 | 347 | user.roles << admin_role |
|
348 | 348 | else |
|
349 | 349 | flash[:notice] = 'Unknown user' |
|
350 | 350 | end |
|
351 | 351 | flash[:notice] = 'User added as admins' |
|
352 | 352 | redirect_to :action => 'admin' |
|
353 | 353 | end |
|
354 | 354 | |
|
355 | 355 | def revoke_admin |
|
356 | 356 | user = User.find(params[:id]) |
|
357 | 357 | if user==nil |
|
358 | 358 | flash[:notice] = 'Unknown user' |
|
359 | 359 | redirect_to :action => 'admin' and return |
|
360 | 360 | elsif user.login == 'root' |
|
361 | 361 | flash[:notice] = 'You cannot revoke admisnistrator permission from root.' |
|
362 | 362 | redirect_to :action => 'admin' and return |
|
363 | 363 | end |
|
364 | 364 | |
|
365 | 365 | admin_role = Role.find_by_name('admin') |
|
366 | 366 | user.roles.delete(admin_role) |
|
367 | 367 | flash[:notice] = 'User permission revoked' |
|
368 | 368 | redirect_to :action => 'admin' |
|
369 | 369 | end |
|
370 | 370 | |
|
371 | 371 | # mass mailing |
|
372 | 372 | |
|
373 | 373 | def mass_mailing |
|
374 | 374 | end |
|
375 | 375 | |
|
376 | 376 | def bulk_mail |
|
377 | 377 | lines = params[:login_list] |
|
378 | 378 | if !lines or lines.blank? |
|
379 | 379 | flash[:notice] = 'You entered an empty list.' |
|
380 | 380 | redirect_to :action => 'mass_mailing' and return |
|
381 | 381 | end |
|
382 | 382 | |
|
383 | 383 | mail_subject = params[:subject] |
|
384 | 384 | if !mail_subject or mail_subject.blank? |
|
385 | 385 | flash[:notice] = 'You entered an empty mail subject.' |
|
386 | 386 | redirect_to :action => 'mass_mailing' and return |
|
387 | 387 | end |
|
388 | 388 | |
|
389 | 389 | mail_body = params[:email_body] |
|
390 | 390 | if !mail_body or mail_body.blank? |
|
391 | 391 | flash[:notice] = 'You entered an empty mail body.' |
|
392 | 392 | redirect_to :action => 'mass_mailing' and return |
|
393 | 393 | end |
|
394 | 394 | |
|
395 | 395 | note = [] |
|
396 | 396 | users = [] |
|
397 | 397 | lines.split("\n").each do |line| |
|
398 | 398 | user = User.find_by_login(line.chomp) |
|
399 | 399 | if user |
|
400 | 400 | send_mail(user.email, mail_subject, mail_body) |
|
401 | 401 | note << user.login |
|
402 | 402 | end |
|
403 | 403 | end |
|
404 | 404 | |
|
405 | 405 | flash[:notice] = 'User(s) ' + note.join(', ') + |
|
406 | 406 | ' were successfully modified. ' |
|
407 | 407 | redirect_to :action => 'mass_mailing' |
|
408 | 408 | end |
|
409 | 409 | |
|
410 | 410 | protected |
|
411 | 411 | |
|
412 | 412 | def random_password(length=5) |
|
413 | 413 | chars = 'abcdefghijkmnopqrstuvwxyz23456789' |
|
414 | 414 | newpass = "" |
|
415 | 415 | length.times { newpass << chars[rand(chars.size-1)] } |
|
416 | 416 | return newpass |
|
417 | 417 | end |
|
418 | 418 | |
|
419 | 419 | def import_from_file(f) |
|
420 | 420 | data_hash = YAML.load(f) |
|
421 | 421 | @import_log = "" |
|
422 | 422 | |
|
423 | 423 | country_data = data_hash[:countries] |
|
424 | 424 | site_data = data_hash[:sites] |
|
425 | 425 | user_data = data_hash[:users] |
|
426 | 426 | |
|
427 | 427 | # import country |
|
428 | 428 | countries = {} |
|
429 | 429 | country_data.each_pair do |id,country| |
|
430 | 430 | c = Country.find_by_name(country[:name]) |
|
431 | 431 | if c!=nil |
|
432 | 432 | countries[id] = c |
|
433 | 433 | @import_log << "Found #{country[:name]}\n" |
|
434 | 434 | else |
|
435 | 435 | countries[id] = Country.new(:name => country[:name]) |
|
436 | 436 | countries[id].save |
|
437 | 437 | @import_log << "Created #{country[:name]}\n" |
|
438 | 438 | end |
|
439 | 439 | end |
|
440 | 440 | |
|
441 | 441 | # import sites |
|
442 | 442 | sites = {} |
|
443 | 443 | site_data.each_pair do |id,site| |
|
444 | 444 | s = Site.find_by_name(site[:name]) |
|
445 | 445 | if s!=nil |
|
446 | 446 | @import_log << "Found #{site[:name]}\n" |
|
447 | 447 | else |
|
448 | 448 | s = Site.new(:name => site[:name]) |
|
449 | 449 | @import_log << "Created #{site[:name]}\n" |
|
450 | 450 | end |
|
451 | 451 | s.password = site[:password] |
|
452 | 452 | s.country = countries[site[:country_id]] |
|
453 | 453 | s.save |
|
454 | 454 | sites[id] = s |
|
455 | 455 | end |
|
456 | 456 | |
|
457 | 457 | # import users |
|
458 | 458 | user_data.each_pair do |id,user| |
|
459 | 459 | u = User.find_by_login(user[:login]) |
|
460 | 460 | if u!=nil |
|
461 | 461 | @import_log << "Found #{user[:login]}\n" |
|
462 | 462 | else |
|
463 | 463 | u = User.new(:login => user[:login]) |
|
464 | 464 | @import_log << "Created #{user[:login]}\n" |
|
465 | 465 | end |
|
466 | 466 | u.full_name = user[:name] |
|
467 | 467 | u.password = user[:password] |
|
468 | 468 | u.country = countries[user[:country_id]] |
|
469 | 469 | u.site = sites[user[:site_id]] |
|
470 | 470 | u.activated = true |
|
471 | 471 | u.email = "empty-#{u.login}@none.com" |
|
472 | 472 | if not u.save |
|
473 | 473 | @import_log << "Errors\n" |
|
474 | 474 | u.errors.each { |attr,msg| @import_log << "#{attr} - #{msg}\n" } |
|
475 | 475 | end |
|
476 | 476 | end |
|
477 | 477 | |
|
478 | 478 | end |
|
479 | 479 | |
|
480 | 480 | def logout_users(users) |
|
481 | 481 | users.each do |user| |
|
482 | 482 | contest_stat = user.contest_stat(true) |
|
483 | 483 | if contest_stat and !contest_stat.forced_logout |
|
484 | 484 | contest_stat.forced_logout = true |
|
485 | 485 | contest_stat.save |
|
486 | 486 | end |
|
487 | 487 | end |
|
488 | 488 | end |
|
489 | 489 | |
|
490 | 490 | def send_contest_update_notification_email(user, contest) |
|
491 | 491 | contest_title_name = GraderConfiguration['contest.name'] |
|
492 | 492 | contest_name = contest.name |
|
493 | 493 | mail_subject = t('contest.notification.email_subject', { |
|
494 | 494 | :contest_title_name => contest_title_name, |
|
495 | 495 | :contest_name => contest_name }) |
|
496 | 496 | mail_body = t('contest.notification.email_body', { |
|
497 | 497 | :full_name => user.full_name, |
|
498 | 498 | :contest_title_name => contest_title_name, |
|
499 | 499 | :contest_name => contest.name, |
|
500 | 500 | }) |
|
501 | 501 | |
|
502 | 502 | logger.info mail_body |
|
503 | 503 | send_mail(user.email, mail_subject, mail_body) |
|
504 | 504 | end |
|
505 | 505 |
@@ -1,54 +1,55 | |||
|
1 | 1 | <%= error_messages_for 'problem' %> |
|
2 | 2 | |
|
3 | 3 | <!--[form:problem]--> |
|
4 | 4 | <p><label for="problem_name">Name</label><br/> |
|
5 | - <%= text_field 'problem', 'name' %></p> | |
|
5 | + <%= text_field 'problem', 'name' %> Do not directly edit the problem name, unless you know what you are doing. If you want to change the name, use the name change button in the problem management menu instead. | |
|
6 | + </p> | |
|
6 | 7 | |
|
7 | 8 | <p><label for="problem_full_name">Full name</label><br/> |
|
8 | 9 | <%= text_field 'problem', 'full_name' %></p> |
|
9 | 10 | |
|
10 | 11 | <p><label for="problem_full_score">Full score</label><br/> |
|
11 | 12 | <%= text_field 'problem', 'full_score' %></p> |
|
12 | 13 | |
|
13 | 14 | <p><label for="problem_date_added">Date added</label><br/> |
|
14 | 15 | <%= date_select 'problem', 'date_added' %></p> |
|
15 | 16 | |
|
16 | 17 | <% |
|
17 | 18 | # TODO: these should be put in model Problem, but I can't think of |
|
18 | 19 | # nice default values for them. These values look fine only |
|
19 | 20 | # in this case (of lazily adding new problems). |
|
20 | 21 | @problem.available = true if @problem!=nil and @problem.available==nil |
|
21 | 22 | @problem.test_allowed = true if @problem!=nil and @problem.test_allowed==nil |
|
22 | 23 | @problem.output_only = false if @problem!=nil and @problem.output_only==nil |
|
23 | 24 | %> |
|
24 | 25 | |
|
25 | 26 | <p> |
|
26 | 27 | <label for="problem_available">Available?</label> |
|
27 | 28 | <%= check_box :problem, :available %> |
|
28 | 29 | |
|
29 | 30 | <label for="problem_test_allowed">Test allowed?</label> |
|
30 | 31 | <%= check_box :problem, :test_allowed %> |
|
31 | 32 | |
|
32 | 33 | <label for="problem_output_only">Output only?</label> |
|
33 | 34 | <%= check_box :problem, :output_only %> |
|
34 | 35 | </p> |
|
35 | 36 | |
|
36 | 37 | <%= error_messages_for 'description' %> |
|
37 | 38 | |
|
38 | 39 | <p><label for="description_body">Description</label><br/> |
|
39 | 40 | <%= text_area :description, :body, :rows => 10, :cols => 80 %></p> |
|
40 | 41 | |
|
41 | 42 | <p><label for="description_markdowned">Markdowned?</label> |
|
42 | 43 | <%= select "description", |
|
43 | 44 | "markdowned", |
|
44 | 45 | [['True',true],['False',false]], |
|
45 | 46 | {:selected => (@description) ? @description.markdowned : false } |
|
46 | 47 | %></p> |
|
47 | 48 | |
|
48 | 49 | <p><label for="problem_url">URL</label><br/> |
|
49 | 50 | <%= text_field 'problem', 'url' %></p> |
|
50 | 51 | |
|
51 | 52 | <p>Task PDF <%= file_field_tag 'file' %></p> |
|
52 | 53 | |
|
53 | 54 | |
|
54 | 55 | <!--[eoform:problem]--> |
@@ -1,24 +1,24 | |||
|
1 | 1 | <% for column in Problem.content_columns %> |
|
2 | 2 | <p> |
|
3 | 3 | <b><%= column.human_name %>:</b> |
|
4 | 4 | <%=h @problem.send(column.name) %> |
|
5 | 5 | </p> |
|
6 | 6 | <% end %> |
|
7 | 7 | |
|
8 | 8 | <p> |
|
9 | 9 | <b>Description:</b><br/> |
|
10 | 10 | <% if @problem.description!=nil %> |
|
11 | 11 | <% if @problem.description.markdowned %> |
|
12 | 12 | <%= markdown(@problem.description.body) %> |
|
13 | 13 | <% else %> |
|
14 | 14 | <pre> |
|
15 | 15 | <%= @problem.description.body %> |
|
16 | 16 | </pre> |
|
17 | 17 | <% end %> |
|
18 | 18 | <% else %> |
|
19 | 19 | (not available) |
|
20 | 20 | <% end %> |
|
21 | 21 | </p> |
|
22 | 22 | |
|
23 | 23 | <%= link_to 'Edit', :action => 'edit', :id => @problem %> | |
|
24 |
- <%= link_to 'Back', |
|
|
24 | + <%= link_to 'Back', problems_path %> |
You need to be logged in to leave comments.
Login now