Description:
merge with master
Commit status:
[Not Reviewed]
References:
merge java
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r665:ecbd1a5dbc27 - - 7 files changed: 108 inserted, 8 deleted

@@ -0,0 +1,34
1 + .container-fluid
2 + %h1 Editing announcement
3 + = error_messages_for :announcement
4 + .row
5 + .col-md-6
6 + = form_for(@announcement) do |f|
7 + .form-group
8 + %label Title
9 + = f.text_field :title, class: 'form-control'
10 + .form-group
11 + %label Notes
12 + (shown internally, used to organize announcements)
13 + = f.text_field :notes, class: 'form-control'
14 + .form-group
15 + %label Body
16 + = f.text_area :body, class: 'form-control', style: 'height: 200px;'
17 + .form-group
18 + %label Author
19 + = f.text_field :author, class: 'form-control'
20 + .checkbox
21 + %label
22 + = f.check_box :published
23 + Published
24 + .checkbox
25 + %label
26 + = f.check_box :frontpage
27 + Show on front page?
28 + .checkbox
29 + %label
30 + = f.check_box :contest_only
31 + Show only in contest?
32 + = f.submit "Update", class: 'btn btn-primary'
33 + = link_to 'Show', @announcement, class: 'btn btn-default'
34 + = link_to 'Back', announcements_path, class: 'btn btn-default'
@@ -0,0 +1,52
1 + = error_messages_for 'problem'
2 + / [form:problem]
3 + .form-group
4 + %label{:for => "problem_name"} Name
5 + = text_field 'problem', 'name', class: 'form-control'
6 + %small
7 + 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.
8 + .form-group
9 + %label{:for => "problem_full_name"} Full name
10 + = text_field 'problem', 'full_name', class: 'form-control'
11 + .form-group
12 + %label{:for => "problem_full_score"} Full score
13 + = text_field 'problem', 'full_score', class: 'form-control'
14 + .form-group
15 + %label{:for => "problem_date_added"} Date added
16 + = date_select 'problem', 'date_added', class: 'form-control'
17 + - # TODO: these should be put in model Problem, but I can't think of
18 + - # nice default values for them. These values look fine only
19 + - # in this case (of lazily adding new problems).
20 + - @problem.available = true if @problem!=nil and @problem.available==nil
21 + - @problem.test_allowed = true if @problem!=nil and @problem.test_allowed==nil
22 + - @problem.output_only = false if @problem!=nil and @problem.output_only==nil
23 + .checkbox
24 + %label{:for => "problem_available"}
25 + = check_box :problem, :available
26 + Available?
27 + .checkbox
28 + %label{:for => "problem_test_allowed"}
29 + = check_box :problem, :test_allowed
30 + Test allowed?
31 + .checkbox
32 + %label{:for => "problem_output_only"}
33 + = check_box :problem, :output_only
34 + Output only?
35 + = error_messages_for 'description'
36 + .form-group
37 + %label{:for => "description_body"} Description
38 + %br/
39 + = text_area :description, :body, :rows => 10, :cols => 80,class: 'form-control'
40 + .form-group
41 + %label{:for => "description_markdowned"} Markdowned?
42 + = select "description", |
43 + "markdowned", |
44 + [['True',true],['False',false]], |
45 + {:selected => (@description) ? @description.markdowned : false } |
46 + .form-group
47 + %label{:for => "problem_url"} URL
48 + %br/
49 + = text_field 'problem', 'url',class: 'form-control'
50 + %p
51 + Task PDF #{file_field_tag 'file'}
52 + / [eoform:problem]
@@ -0,0 +1,14
1 + .container-fluid
2 + = form_for @problem,url:{action: 'update'},html: {multipart: true} do
3 + .row
4 + .col-md-6
5 + %h1 Editing problem
6 + = render :partial => 'form'
7 + .row
8 + .col-md-4
9 + = submit_tag 'Edit', class: 'btn btn-primary btn-block'
10 + .col-md-4
11 + = link_to 'Show', {:action => 'show', :id => @problem}, class: 'btn btn-default btn-block'
12 + .col-md-4
13 + = link_to 'Back', problems_path, class: 'btn btn-default btn-block'
14 + .div{style: 'height: 5em'}
@@ -0,0 +1,5
1 + require 'spec_helper'
2 +
3 + describe Testcases do
4 + pending "add some examples to (or delete) #{__FILE__}"
5 + end
@@ -132,193 +132,193
132 .select(:ip_address).uniq
132 .select(:ip_address).uniq
133
133
134 }
134 }
135 end
135 end
136 end
136 end
137
137
138 def submission_stat
138 def submission_stat
139
139
140 date_and_time = '%Y-%m-%d %H:%M'
140 date_and_time = '%Y-%m-%d %H:%M'
141 begin
141 begin
142 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
142 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
143 rescue
143 rescue
144 @since_time = DateTime.new(1000,1,1)
144 @since_time = DateTime.new(1000,1,1)
145 end
145 end
146 begin
146 begin
147 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
147 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
148 rescue
148 rescue
149 @until_time = DateTime.new(3000,1,1)
149 @until_time = DateTime.new(3000,1,1)
150 end
150 end
151
151
152 @submissions = {}
152 @submissions = {}
153
153
154 User.find_each do |user|
154 User.find_each do |user|
155 @submissions[user.id] = { login: user.login, full_name: user.full_name, count: 0, sub: { } }
155 @submissions[user.id] = { login: user.login, full_name: user.full_name, count: 0, sub: { } }
156 end
156 end
157
157
158 Submission.where("submitted_at >= ? AND submitted_at <= ?",@since_time,@until_time).find_each do |s|
158 Submission.where("submitted_at >= ? AND submitted_at <= ?",@since_time,@until_time).find_each do |s|
159 if @submissions[s.user_id]
159 if @submissions[s.user_id]
160 if not @submissions[s.user_id][:sub].has_key?(s.problem_id)
160 if not @submissions[s.user_id][:sub].has_key?(s.problem_id)
161 a = Problem.find_by_id(s.problem_id)
161 a = Problem.find_by_id(s.problem_id)
162 @submissions[s.user_id][:sub][s.problem_id] =
162 @submissions[s.user_id][:sub][s.problem_id] =
163 { prob_name: (a ? a.full_name : '(NULL)'),
163 { prob_name: (a ? a.full_name : '(NULL)'),
164 sub_ids: [s.id] }
164 sub_ids: [s.id] }
165 else
165 else
166 @submissions[s.user_id][:sub][s.problem_id][:sub_ids] << s.id
166 @submissions[s.user_id][:sub][s.problem_id][:sub_ids] << s.id
167 end
167 end
168 @submissions[s.user_id][:count] += 1
168 @submissions[s.user_id][:count] += 1
169 end
169 end
170 end
170 end
171 end
171 end
172
172
173 def problem_hof
173 def problem_hof
174 # gen problem list
174 # gen problem list
175 @user = User.find(session[:user_id])
175 @user = User.find(session[:user_id])
176 @problems = @user.available_problems
176 @problems = @user.available_problems
177
177
178 # get selected problems or the default
178 # get selected problems or the default
179 if params[:id]
179 if params[:id]
180 begin
180 begin
181 @problem = Problem.available.find(params[:id])
181 @problem = Problem.available.find(params[:id])
182 rescue
182 rescue
183 redirect_to action: :problem_hof
183 redirect_to action: :problem_hof
184 flash[:notice] = 'Error: submissions for that problem are not viewable.'
184 flash[:notice] = 'Error: submissions for that problem are not viewable.'
185 return
185 return
186 end
186 end
187 end
187 end
188
188
189 return unless @problem
189 return unless @problem
190
190
191 @by_lang = {} #aggregrate by language
191 @by_lang = {} #aggregrate by language
192
192
193 range =65
193 range =65
194 @histogram = { data: Array.new(range,0), summary: {} }
194 @histogram = { data: Array.new(range,0), summary: {} }
195 @summary = {count: 0, solve: 0, attempt: 0}
195 @summary = {count: 0, solve: 0, attempt: 0}
196 user = Hash.new(0)
196 user = Hash.new(0)
197 Submission.where(problem_id: @problem.id).find_each do |sub|
197 Submission.where(problem_id: @problem.id).find_each do |sub|
198 #histogram
198 #histogram
199 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
199 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
200 @histogram[:data][d.to_i] += 1 if d < range
200 @histogram[:data][d.to_i] += 1 if d < range
201
201
202 next unless sub.points
202 next unless sub.points
203 @summary[:count] += 1
203 @summary[:count] += 1
204 user[sub.user_id] = [user[sub.user_id], (sub.points >= @problem.full_score) ? 1 : 0].max
204 user[sub.user_id] = [user[sub.user_id], (sub.points >= @problem.full_score) ? 1 : 0].max
205
205
206 lang = Language.find_by_id(sub.language_id)
206 lang = Language.find_by_id(sub.language_id)
207 next unless lang
207 next unless lang
208 next unless sub.points >= @problem.full_score
208 next unless sub.points >= @problem.full_score
209
209
210 #initialize
210 #initialize
211 unless @by_lang.has_key?(lang.pretty_name)
211 unless @by_lang.has_key?(lang.pretty_name)
212 @by_lang[lang.pretty_name] = {
212 @by_lang[lang.pretty_name] = {
213 runtime: { avail: false, value: 2**30-1 },
213 runtime: { avail: false, value: 2**30-1 },
214 memory: { avail: false, value: 2**30-1 },
214 memory: { avail: false, value: 2**30-1 },
215 length: { avail: false, value: 2**30-1 },
215 length: { avail: false, value: 2**30-1 },
216 first: { avail: false, value: DateTime.new(3000,1,1) }
216 first: { avail: false, value: DateTime.new(3000,1,1) }
217 }
217 }
218 end
218 end
219
219
220 if sub.max_runtime and sub.max_runtime < @by_lang[lang.pretty_name][:runtime][:value]
220 if sub.max_runtime and sub.max_runtime < @by_lang[lang.pretty_name][:runtime][:value]
221 @by_lang[lang.pretty_name][:runtime] = { avail: true, user_id: sub.user_id, value: sub.max_runtime, sub_id: sub.id }
221 @by_lang[lang.pretty_name][:runtime] = { avail: true, user_id: sub.user_id, value: sub.max_runtime, sub_id: sub.id }
222 end
222 end
223
223
224 if sub.peak_memory and sub.peak_memory < @by_lang[lang.pretty_name][:memory][:value]
224 if sub.peak_memory and sub.peak_memory < @by_lang[lang.pretty_name][:memory][:value]
225 @by_lang[lang.pretty_name][:memory] = { avail: true, user_id: sub.user_id, value: sub.peak_memory, sub_id: sub.id }
225 @by_lang[lang.pretty_name][:memory] = { avail: true, user_id: sub.user_id, value: sub.peak_memory, sub_id: sub.id }
226 end
226 end
227
227
228 - if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value] and
228 + if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value] and sub.user and
229 !sub.user.admin?
229 !sub.user.admin?
230 @by_lang[lang.pretty_name][:first] = { avail: true, user_id: sub.user_id, value: sub.submitted_at, sub_id: sub.id }
230 @by_lang[lang.pretty_name][:first] = { avail: true, user_id: sub.user_id, value: sub.submitted_at, sub_id: sub.id }
231 end
231 end
232
232
233 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
233 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
234 @by_lang[lang.pretty_name][:length] = { avail: true, user_id: sub.user_id, value: sub.effective_code_length, sub_id: sub.id }
234 @by_lang[lang.pretty_name][:length] = { avail: true, user_id: sub.user_id, value: sub.effective_code_length, sub_id: sub.id }
235 end
235 end
236 end
236 end
237
237
238 #process user_id
238 #process user_id
239 @by_lang.each do |lang,prop|
239 @by_lang.each do |lang,prop|
240 prop.each do |k,v|
240 prop.each do |k,v|
241 v[:user] = User.exists?(v[:user_id]) ? User.find(v[:user_id]).full_name : "(NULL)"
241 v[:user] = User.exists?(v[:user_id]) ? User.find(v[:user_id]).full_name : "(NULL)"
242 end
242 end
243 end
243 end
244
244
245 #sum into best
245 #sum into best
246 if @by_lang and @by_lang.first
246 if @by_lang and @by_lang.first
247 @best = @by_lang.first[1].clone
247 @best = @by_lang.first[1].clone
248 @by_lang.each do |lang,prop|
248 @by_lang.each do |lang,prop|
249 if @best[:runtime][:value] >= prop[:runtime][:value]
249 if @best[:runtime][:value] >= prop[:runtime][:value]
250 @best[:runtime] = prop[:runtime]
250 @best[:runtime] = prop[:runtime]
251 @best[:runtime][:lang] = lang
251 @best[:runtime][:lang] = lang
252 end
252 end
253 if @best[:memory][:value] >= prop[:memory][:value]
253 if @best[:memory][:value] >= prop[:memory][:value]
254 @best[:memory] = prop[:memory]
254 @best[:memory] = prop[:memory]
255 @best[:memory][:lang] = lang
255 @best[:memory][:lang] = lang
256 end
256 end
257 if @best[:length][:value] >= prop[:length][:value]
257 if @best[:length][:value] >= prop[:length][:value]
258 @best[:length] = prop[:length]
258 @best[:length] = prop[:length]
259 @best[:length][:lang] = lang
259 @best[:length][:lang] = lang
260 end
260 end
261 if @best[:first][:value] >= prop[:first][:value]
261 if @best[:first][:value] >= prop[:first][:value]
262 @best[:first] = prop[:first]
262 @best[:first] = prop[:first]
263 @best[:first][:lang] = lang
263 @best[:first][:lang] = lang
264 end
264 end
265 end
265 end
266 end
266 end
267
267
268 @histogram[:summary][:max] = [@histogram[:data].max,1].max
268 @histogram[:summary][:max] = [@histogram[:data].max,1].max
269 @summary[:attempt] = user.count
269 @summary[:attempt] = user.count
270 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
270 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
271 end
271 end
272
272
273 def stuck #report struggling user,problem
273 def stuck #report struggling user,problem
274 # init
274 # init
275 user,problem = nil
275 user,problem = nil
276 solve = true
276 solve = true
277 tries = 0
277 tries = 0
278 @struggle = Array.new
278 @struggle = Array.new
279 record = {}
279 record = {}
280 Submission.includes(:problem,:user).order(:problem_id,:user_id).find_each do |sub|
280 Submission.includes(:problem,:user).order(:problem_id,:user_id).find_each do |sub|
281 next unless sub.problem and sub.user
281 next unless sub.problem and sub.user
282 if user != sub.user_id or problem != sub.problem_id
282 if user != sub.user_id or problem != sub.problem_id
283 @struggle << { user: record[:user], problem: record[:problem], tries: tries } unless solve
283 @struggle << { user: record[:user], problem: record[:problem], tries: tries } unless solve
284 record = {user: sub.user, problem: sub.problem}
284 record = {user: sub.user, problem: sub.problem}
285 user,problem = sub.user_id, sub.problem_id
285 user,problem = sub.user_id, sub.problem_id
286 solve = false
286 solve = false
287 tries = 0
287 tries = 0
288 end
288 end
289 if sub.points >= sub.problem.full_score
289 if sub.points >= sub.problem.full_score
290 solve = true
290 solve = true
291 else
291 else
292 tries += 1
292 tries += 1
293 end
293 end
294 end
294 end
295 @struggle.sort!{|a,b| b[:tries] <=> a[:tries] }
295 @struggle.sort!{|a,b| b[:tries] <=> a[:tries] }
296 @struggle = @struggle[0..50]
296 @struggle = @struggle[0..50]
297 end
297 end
298
298
299
299
300 def multiple_login
300 def multiple_login
301 #user with multiple IP
301 #user with multiple IP
302 raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:login)
302 raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:login)
303 last,count = 0,0
303 last,count = 0,0
304 first = 0
304 first = 0
305 @users = []
305 @users = []
306 raw.each do |r|
306 raw.each do |r|
307 if last != r.user.login
307 if last != r.user.login
308 count = 1
308 count = 1
309 last = r.user.login
309 last = r.user.login
310 first = r
310 first = r
311 else
311 else
312 @users << first if count == 1
312 @users << first if count == 1
313 @users << r
313 @users << r
314 count += 1
314 count += 1
315 end
315 end
316 end
316 end
317
317
318 #IP with multiple user
318 #IP with multiple user
319 raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:ip_address)
319 raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:ip_address)
320 last,count = 0,0
320 last,count = 0,0
321 first = 0
321 first = 0
322 @ip = []
322 @ip = []
323 raw.each do |r|
323 raw.each do |r|
324 if last != r.ip_address
324 if last != r.ip_address
@@ -18,193 +18,194
18
18
19 verify :method => :post, :only => [:chg_passwd],
19 verify :method => :post, :only => [:chg_passwd],
20 :redirect_to => { :action => :index }
20 :redirect_to => { :action => :index }
21
21
22 #in_place_edit_for :user, :alias_for_editing
22 #in_place_edit_for :user, :alias_for_editing
23 #in_place_edit_for :user, :email_for_editing
23 #in_place_edit_for :user, :email_for_editing
24
24
25 def index
25 def index
26 if !GraderConfiguration['system.user_setting_enabled']
26 if !GraderConfiguration['system.user_setting_enabled']
27 redirect_to :controller => 'main', :action => 'list'
27 redirect_to :controller => 'main', :action => 'list'
28 else
28 else
29 @user = User.find(session[:user_id])
29 @user = User.find(session[:user_id])
30 end
30 end
31 end
31 end
32
32
33 def chg_passwd
33 def chg_passwd
34 user = User.find(session[:user_id])
34 user = User.find(session[:user_id])
35 user.password = params[:passwd]
35 user.password = params[:passwd]
36 user.password_confirmation = params[:passwd_verify]
36 user.password_confirmation = params[:passwd_verify]
37 if user.save
37 if user.save
38 flash[:notice] = 'password changed'
38 flash[:notice] = 'password changed'
39 else
39 else
40 flash[:notice] = 'Error: password changing failed'
40 flash[:notice] = 'Error: password changing failed'
41 end
41 end
42 redirect_to :action => 'index'
42 redirect_to :action => 'index'
43 end
43 end
44
44
45 def new
45 def new
46 @user = User.new
46 @user = User.new
47 render :action => 'new', :layout => 'empty'
47 render :action => 'new', :layout => 'empty'
48 end
48 end
49
49
50 def register
50 def register
51 if(params[:cancel])
51 if(params[:cancel])
52 redirect_to :controller => 'main', :action => 'login'
52 redirect_to :controller => 'main', :action => 'login'
53 return
53 return
54 end
54 end
55 @user = User.new(user_params)
55 @user = User.new(user_params)
56 @user.password_confirmation = @user.password = User.random_password
56 @user.password_confirmation = @user.password = User.random_password
57 @user.activated = false
57 @user.activated = false
58 if (@user.valid?) and (@user.save)
58 if (@user.valid?) and (@user.save)
59 if send_confirmation_email(@user)
59 if send_confirmation_email(@user)
60 render :action => 'new_splash', :layout => 'empty'
60 render :action => 'new_splash', :layout => 'empty'
61 else
61 else
62 @admin_email = GraderConfiguration['system.admin_email']
62 @admin_email = GraderConfiguration['system.admin_email']
63 render :action => 'email_error', :layout => 'empty'
63 render :action => 'email_error', :layout => 'empty'
64 end
64 end
65 else
65 else
66 @user.errors.add(:base,"Email cannot be blank") if @user.email==''
66 @user.errors.add(:base,"Email cannot be blank") if @user.email==''
67 render :action => 'new', :layout => 'empty'
67 render :action => 'new', :layout => 'empty'
68 end
68 end
69 end
69 end
70
70
71 def confirm
71 def confirm
72 login = params[:login]
72 login = params[:login]
73 key = params[:activation]
73 key = params[:activation]
74 @user = User.find_by_login(login)
74 @user = User.find_by_login(login)
75 if (@user) and (@user.verify_activation_key(key))
75 if (@user) and (@user.verify_activation_key(key))
76 if @user.valid? # check uniquenss of email
76 if @user.valid? # check uniquenss of email
77 @user.activated = true
77 @user.activated = true
78 @user.save
78 @user.save
79 @result = :successful
79 @result = :successful
80 else
80 else
81 @result = :email_used
81 @result = :email_used
82 end
82 end
83 else
83 else
84 @result = :failed
84 @result = :failed
85 end
85 end
86 render :action => 'confirm', :layout => 'empty'
86 render :action => 'confirm', :layout => 'empty'
87 end
87 end
88
88
89 def forget
89 def forget
90 render :action => 'forget', :layout => 'empty'
90 render :action => 'forget', :layout => 'empty'
91 end
91 end
92
92
93 def retrieve_password
93 def retrieve_password
94 email = params[:email]
94 email = params[:email]
95 user = User.find_by_email(email)
95 user = User.find_by_email(email)
96 if user
96 if user
97 last_updated_time = user.updated_at || user.created_at || (Time.now.gmtime - 1.hour)
97 last_updated_time = user.updated_at || user.created_at || (Time.now.gmtime - 1.hour)
98 if last_updated_time > Time.now.gmtime - 5.minutes
98 if last_updated_time > Time.now.gmtime - 5.minutes
99 flash[:notice] = 'The account has recently created or new password has recently been requested. Please wait for 5 minutes'
99 flash[:notice] = 'The account has recently created or new password has recently been requested. Please wait for 5 minutes'
100 else
100 else
101 user.password = user.password_confirmation = User.random_password
101 user.password = user.password_confirmation = User.random_password
102 user.save
102 user.save
103 send_new_password_email(user)
103 send_new_password_email(user)
104 flash[:notice] = 'New password has been mailed to you.'
104 flash[:notice] = 'New password has been mailed to you.'
105 end
105 end
106 else
106 else
107 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
107 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
108 end
108 end
109 redirect_to :action => 'forget'
109 redirect_to :action => 'forget'
110 end
110 end
111
111
112 def stat
112 def stat
113 @user = User.find(params[:id])
113 @user = User.find(params[:id])
114 - @submission = Submission.includes(:problem).where(user_id: params[:id])
114 + @submission = Submission.joins(:problem).where(user_id: params[:id])
115 + @submission = @submission.where('problems.available = true') unless current_user.admin?
115
116
116 range = 120
117 range = 120
117 @histogram = { data: Array.new(range,0), summary: {} }
118 @histogram = { data: Array.new(range,0), summary: {} }
118 @summary = {count: 0, solve: 0, attempt: 0}
119 @summary = {count: 0, solve: 0, attempt: 0}
119 problem = Hash.new(0)
120 problem = Hash.new(0)
120
121
121 @submission.find_each do |sub|
122 @submission.find_each do |sub|
122 #histogram
123 #histogram
123 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
124 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
124 @histogram[:data][d.to_i] += 1 if d < range
125 @histogram[:data][d.to_i] += 1 if d < range
125
126
126 @summary[:count] += 1
127 @summary[:count] += 1
127 next unless sub.problem
128 next unless sub.problem
128 problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max
129 problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max
129 end
130 end
130
131
131 @histogram[:summary][:max] = [@histogram[:data].max,1].max
132 @histogram[:summary][:max] = [@histogram[:data].max,1].max
132 @summary[:attempt] = problem.count
133 @summary[:attempt] = problem.count
133 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
134 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
134 end
135 end
135
136
136 def toggle_activate
137 def toggle_activate
137 @user = User.find(params[:id])
138 @user = User.find(params[:id])
138 @user.update_attributes( activated: !@user.activated? )
139 @user.update_attributes( activated: !@user.activated? )
139 respond_to do |format|
140 respond_to do |format|
140 format.js { render partial: 'toggle_button',
141 format.js { render partial: 'toggle_button',
141 locals: {button_id: "#toggle_activate_user_#{@user.id}",button_on: @user.activated? } }
142 locals: {button_id: "#toggle_activate_user_#{@user.id}",button_on: @user.activated? } }
142 end
143 end
143 end
144 end
144
145
145 def toggle_enable
146 def toggle_enable
146 @user = User.find(params[:id])
147 @user = User.find(params[:id])
147 @user.update_attributes( enabled: !@user.enabled? )
148 @user.update_attributes( enabled: !@user.enabled? )
148 respond_to do |format|
149 respond_to do |format|
149 format.js { render partial: 'toggle_button',
150 format.js { render partial: 'toggle_button',
150 locals: {button_id: "#toggle_enable_user_#{@user.id}",button_on: @user.enabled? } }
151 locals: {button_id: "#toggle_enable_user_#{@user.id}",button_on: @user.enabled? } }
151 end
152 end
152 end
153 end
153
154
154 protected
155 protected
155
156
156 def verify_online_registration
157 def verify_online_registration
157 if !GraderConfiguration['system.online_registration']
158 if !GraderConfiguration['system.online_registration']
158 redirect_to :controller => 'main', :action => 'login'
159 redirect_to :controller => 'main', :action => 'login'
159 end
160 end
160 end
161 end
161
162
162 def send_confirmation_email(user)
163 def send_confirmation_email(user)
163 contest_name = GraderConfiguration['contest.name']
164 contest_name = GraderConfiguration['contest.name']
164 activation_url = url_for(:action => 'confirm',
165 activation_url = url_for(:action => 'confirm',
165 :login => user.login,
166 :login => user.login,
166 :activation => user.activation_key)
167 :activation => user.activation_key)
167 home_url = url_for(:controller => 'main', :action => 'index')
168 home_url = url_for(:controller => 'main', :action => 'index')
168 mail_subject = "[#{contest_name}] Confirmation"
169 mail_subject = "[#{contest_name}] Confirmation"
169 mail_body = t('registration.email_body', {
170 mail_body = t('registration.email_body', {
170 :full_name => user.full_name,
171 :full_name => user.full_name,
171 :contest_name => contest_name,
172 :contest_name => contest_name,
172 :login => user.login,
173 :login => user.login,
173 :password => user.password,
174 :password => user.password,
174 :activation_url => activation_url,
175 :activation_url => activation_url,
175 :admin_email => GraderConfiguration['system.admin_email']
176 :admin_email => GraderConfiguration['system.admin_email']
176 })
177 })
177
178
178 logger.info mail_body
179 logger.info mail_body
179
180
180 send_mail(user.email, mail_subject, mail_body)
181 send_mail(user.email, mail_subject, mail_body)
181 end
182 end
182
183
183 def send_new_password_email(user)
184 def send_new_password_email(user)
184 contest_name = GraderConfiguration['contest.name']
185 contest_name = GraderConfiguration['contest.name']
185 mail_subject = "[#{contest_name}] Password recovery"
186 mail_subject = "[#{contest_name}] Password recovery"
186 mail_body = t('registration.password_retrieval.email_body', {
187 mail_body = t('registration.password_retrieval.email_body', {
187 :full_name => user.full_name,
188 :full_name => user.full_name,
188 :contest_name => contest_name,
189 :contest_name => contest_name,
189 :login => user.login,
190 :login => user.login,
190 :password => user.password,
191 :password => user.password,
191 :admin_email => GraderConfiguration['system.admin_email']
192 :admin_email => GraderConfiguration['system.admin_email']
192 })
193 })
193
194
194 logger.info mail_body
195 logger.info mail_body
195
196
196 send_mail(user.email, mail_subject, mail_body)
197 send_mail(user.email, mail_subject, mail_body)
197 end
198 end
198
199
199 # allow viewing of regular user profile only when options allow so
200 # allow viewing of regular user profile only when options allow so
200 # only admins can view admins profile
201 # only admins can view admins profile
201 def profile_authorization
202 def profile_authorization
202 #if view admins' profile, allow only admin
203 #if view admins' profile, allow only admin
203 return false unless(params[:id])
204 return false unless(params[:id])
204 user = User.find(params[:id])
205 user = User.find(params[:id])
205 return false unless user
206 return false unless user
206 return admin_authorization if user.admin?
207 return admin_authorization if user.admin?
207 return true if GraderConfiguration["right.user_view_submission"]
208 return true if GraderConfiguration["right.user_view_submission"]
208
209
209 #finally, we allow only admin
210 #finally, we allow only admin
210 admin_authorization
211 admin_authorization
@@ -1,78 +1,72
1 require File.expand_path('../boot', __FILE__)
1 require File.expand_path('../boot', __FILE__)
2
2
3 require 'rails/all'
3 require 'rails/all'
4
4
5 if defined?(Bundler)
5 if defined?(Bundler)
6 # If you precompile assets before deploying to production, use this line
6 # If you precompile assets before deploying to production, use this line
7 Bundler.require(*Rails.groups(:assets => %w(development test)))
7 Bundler.require(*Rails.groups(:assets => %w(development test)))
8 # If you want your assets lazily compiled in production, use this line
8 # If you want your assets lazily compiled in production, use this line
9 # Bundler.require(:default, :assets, Rails.env)
9 # Bundler.require(:default, :assets, Rails.env)
10 end
10 end
11
11
12 module CafeGrader
12 module CafeGrader
13 class Application < Rails::Application
13 class Application < Rails::Application
14 # Settings in config/environments/* take precedence over those specified here.
14 # Settings in config/environments/* take precedence over those specified here.
15 # Application configuration should go into files in config/initializers
15 # Application configuration should go into files in config/initializers
16 # -- all .rb files in that directory are automatically loaded.
16 # -- all .rb files in that directory are automatically loaded.
17
17
18 # Custom directories with classes and modules you want to be autoloadable.
18 # Custom directories with classes and modules you want to be autoloadable.
19 config.autoload_paths += %W(#{config.root}/lib)
19 config.autoload_paths += %W(#{config.root}/lib)
20
20
21 # Only load the plugins named here, in the order given (default is alphabetical).
21 # Only load the plugins named here, in the order given (default is alphabetical).
22 # :all can be used as a placeholder for all plugins not explicitly named.
22 # :all can be used as a placeholder for all plugins not explicitly named.
23 # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
23 # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
24
24
25 # Activate observers that should always be running.
25 # Activate observers that should always be running.
26 # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
26 # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
27
27
28 # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
28 # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
29 # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
29 # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
30 config.time_zone = 'UTC'
30 config.time_zone = 'UTC'
31
31
32 # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
32 # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
33 # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
33 # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
34 config.i18n.default_locale = :en
34 config.i18n.default_locale = :en
35
35
36 # Configure the default encoding used in templates for Ruby 1.9.
36 # Configure the default encoding used in templates for Ruby 1.9.
37 config.encoding = "utf-8"
37 config.encoding = "utf-8"
38
38
39 # Configure sensitive parameters which will be filtered from the log file.
39 # Configure sensitive parameters which will be filtered from the log file.
40 config.filter_parameters += [:password]
40 config.filter_parameters += [:password]
41
41
42 # Enable escaping HTML in JSON.
42 # Enable escaping HTML in JSON.
43 config.active_support.escape_html_entities_in_json = true
43 config.active_support.escape_html_entities_in_json = true
44
44
45 # Use SQL instead of Active Record's schema dumper when creating the database.
45 # Use SQL instead of Active Record's schema dumper when creating the database.
46 # This is necessary if your schema can't be completely dumped by the schema dumper,
46 # This is necessary if your schema can't be completely dumped by the schema dumper,
47 # like if you have constraints or database-specific column types
47 # like if you have constraints or database-specific column types
48 # config.active_record.schema_format = :sql
48 # config.active_record.schema_format = :sql
49
49
50 - # Enforce whitelist mode for mass assignment.
51 - # This will create an empty whitelist of attributes available for mass-assignment for all models
52 - # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
53 - # parameters by using an attr_accessible or attr_protected declaration.
54 - config.active_record.whitelist_attributes = false
55 -
56 # Enable the asset pipeline
50 # Enable the asset pipeline
57 config.assets.enabled = true
51 config.assets.enabled = true
58
52
59 # Version of your assets, change this if you want to expire all your assets
53 # Version of your assets, change this if you want to expire all your assets
60 config.assets.version = '1.0'
54 config.assets.version = '1.0'
61
55
62 # ---------------- IMPORTANT ----------------------
56 # ---------------- IMPORTANT ----------------------
63 # If we deploy the app into a subdir name "grader", be sure to do "rake assets:precompile RAILS_RELATIVE_URL_ROOT=/grader"
57 # If we deploy the app into a subdir name "grader", be sure to do "rake assets:precompile RAILS_RELATIVE_URL_ROOT=/grader"
64 # moreover, using the following line instead also known to works
58 # moreover, using the following line instead also known to works
65 #config.action_controller.relative_url_root = '/grader'
59 #config.action_controller.relative_url_root = '/grader'
66
60
67 #font path
61 #font path
68 config.assets.paths << "#{Rails}/vendor/assets/fonts"
62 config.assets.paths << "#{Rails}/vendor/assets/fonts"
69
63
70 config.assets.precompile += ['announcement_refresh.js','effects.js','site_update.js']
64 config.assets.precompile += ['announcement_refresh.js','effects.js','site_update.js']
71 config.assets.precompile += ['local_jquery.js','tablesorter-theme.cafe.css']
65 config.assets.precompile += ['local_jquery.js','tablesorter-theme.cafe.css']
72 %w( announcements submissions configurations contests contest_management graders heartbeat
66 %w( announcements submissions configurations contests contest_management graders heartbeat
73 login main messages problems report site sites sources tasks
67 login main messages problems report site sites sources tasks
74 test user_admin users ).each do |controller|
68 test user_admin users ).each do |controller|
75 config.assets.precompile += ["#{controller}.js", "#{controller}.css"]
69 config.assets.precompile += ["#{controller}.js", "#{controller}.css"]
76 end
70 end
77 end
71 end
78 end
72 end
You need to be logged in to leave comments. Login now