Description:
shows contest start confirmation for indv contest
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r302:77a5c6e76df3 - - 4 files changed: 45 inserted, 4 deleted

@@ -0,0 +1,12
1 + = user_title_bar(@user)
2 +
3 + %center
4 + You will participate in contest:
5 + - @contests.each do |contest|
6 + = contest.title
7 + %br
8 +
9 + The timer will start after you click the start button.
10 +
11 + - form_tag :action => 'confirm_contest_start', :method => 'post' do
12 + = submit_tag 'Start!', :confirm => 'Are you sure?'
@@ -1,356 +1,376
1 class MainController < ApplicationController
1 class MainController < ApplicationController
2
2
3 before_filter :authenticate, :except => [:index, :login]
3 before_filter :authenticate, :except => [:index, :login]
4 before_filter :check_viewability, :except => [:index, :login]
4 before_filter :check_viewability, :except => [:index, :login]
5
5
6 - append_before_filter :update_user_start_time, :except => [:index, :login]
6 + append_before_filter :confirm_and_update_start_time,
7 + :except => [:index,
8 + :login,
9 + :confirm_contest_start]
7
10
8 # to prevent log in box to be shown when user logged out of the
11 # to prevent log in box to be shown when user logged out of the
9 # system only in some tab
12 # system only in some tab
10 - prepend_before_filter :reject_announcement_refresh_when_logged_out, :only => [:announcements]
13 + prepend_before_filter :reject_announcement_refresh_when_logged_out,
14 + :only => [:announcements]
11
15
12 # COMMENTED OUT: filter in each action instead
16 # COMMENTED OUT: filter in each action instead
13 # before_filter :verify_time_limit, :only => [:submit]
17 # before_filter :verify_time_limit, :only => [:submit]
14
18
15 verify :method => :post, :only => [:submit],
19 verify :method => :post, :only => [:submit],
16 :redirect_to => { :action => :index }
20 :redirect_to => { :action => :index }
17
21
18 # COMMENT OUT: only need when having high load
22 # COMMENT OUT: only need when having high load
19 # caches_action :index, :login
23 # caches_action :index, :login
20
24
21 # NOTE: This method is not actually needed, 'config/routes.rb' has
25 # NOTE: This method is not actually needed, 'config/routes.rb' has
22 # assigned action login as a default action.
26 # assigned action login as a default action.
23 def index
27 def index
24 redirect_to :action => 'login'
28 redirect_to :action => 'login'
25 end
29 end
26
30
27 def login
31 def login
28 saved_notice = flash[:notice]
32 saved_notice = flash[:notice]
29 reset_session
33 reset_session
30 flash.now[:notice] = saved_notice
34 flash.now[:notice] = saved_notice
31
35
32 # EXPERIMENT:
36 # EXPERIMENT:
33 # Hide login if in single user mode and the url does not
37 # Hide login if in single user mode and the url does not
34 # explicitly specify /login
38 # explicitly specify /login
35 #
39 #
36 # logger.info "PATH: #{request.path}"
40 # logger.info "PATH: #{request.path}"
37 # if Configuration['system.single_user_mode'] and
41 # if Configuration['system.single_user_mode'] and
38 # request.path!='/main/login'
42 # request.path!='/main/login'
39 # @hidelogin = true
43 # @hidelogin = true
40 # end
44 # end
41
45
42 @announcements = Announcement.find_for_frontpage
46 @announcements = Announcement.find_for_frontpage
43 render :action => 'login', :layout => 'empty'
47 render :action => 'login', :layout => 'empty'
44 end
48 end
45
49
46 def list
50 def list
47 prepare_list_information
51 prepare_list_information
48 end
52 end
49
53
50 def help
54 def help
51 @user = User.find(session[:user_id])
55 @user = User.find(session[:user_id])
52 end
56 end
53
57
54 def submit
58 def submit
55 user = User.find(session[:user_id])
59 user = User.find(session[:user_id])
56
60
57 @submission = Submission.new(params[:submission])
61 @submission = Submission.new(params[:submission])
58 @submission.user = user
62 @submission.user = user
59 @submission.language_id = 0
63 @submission.language_id = 0
60 if (params['file']) and (params['file']!='')
64 if (params['file']) and (params['file']!='')
61 @submission.source = params['file'].read
65 @submission.source = params['file'].read
62 @submission.source_filename = params['file'].original_filename
66 @submission.source_filename = params['file'].original_filename
63 end
67 end
64 @submission.submitted_at = Time.new.gmtime
68 @submission.submitted_at = Time.new.gmtime
65
69
66 if Configuration.time_limit_mode? and user.contest_finished?
70 if Configuration.time_limit_mode? and user.contest_finished?
67 @submission.errors.add_to_base "The contest is over."
71 @submission.errors.add_to_base "The contest is over."
68 prepare_list_information
72 prepare_list_information
69 render :action => 'list' and return
73 render :action => 'list' and return
70 end
74 end
71
75
72 if @submission.valid?
76 if @submission.valid?
73 if @submission.save == false
77 if @submission.save == false
74 flash[:notice] = 'Error saving your submission'
78 flash[:notice] = 'Error saving your submission'
75 elsif Task.create(:submission_id => @submission.id,
79 elsif Task.create(:submission_id => @submission.id,
76 :status => Task::STATUS_INQUEUE) == false
80 :status => Task::STATUS_INQUEUE) == false
77 flash[:notice] = 'Error adding your submission to task queue'
81 flash[:notice] = 'Error adding your submission to task queue'
78 end
82 end
79 else
83 else
80 prepare_list_information
84 prepare_list_information
81 render :action => 'list' and return
85 render :action => 'list' and return
82 end
86 end
83 redirect_to :action => 'list'
87 redirect_to :action => 'list'
84 end
88 end
85
89
86 def source
90 def source
87 submission = Submission.find(params[:id])
91 submission = Submission.find(params[:id])
88 if submission.user_id == session[:user_id]
92 if submission.user_id == session[:user_id]
89 send_data(submission.source,
93 send_data(submission.source,
90 {:filename => submission.download_filename,
94 {:filename => submission.download_filename,
91 :type => 'text/plain'})
95 :type => 'text/plain'})
92 else
96 else
93 flash[:notice] = 'Error viewing source'
97 flash[:notice] = 'Error viewing source'
94 redirect_to :action => 'list'
98 redirect_to :action => 'list'
95 end
99 end
96 end
100 end
97
101
98 def compiler_msg
102 def compiler_msg
99 @submission = Submission.find(params[:id])
103 @submission = Submission.find(params[:id])
100 if @submission.user_id == session[:user_id]
104 if @submission.user_id == session[:user_id]
101 render :action => 'compiler_msg', :layout => 'empty'
105 render :action => 'compiler_msg', :layout => 'empty'
102 else
106 else
103 flash[:notice] = 'Error viewing source'
107 flash[:notice] = 'Error viewing source'
104 redirect_to :action => 'list'
108 redirect_to :action => 'list'
105 end
109 end
106 end
110 end
107
111
108 def submission
112 def submission
109 @user = User.find(session[:user_id])
113 @user = User.find(session[:user_id])
110 @problems = @user.available_problems
114 @problems = @user.available_problems
111 if params[:id]==nil
115 if params[:id]==nil
112 @problem = nil
116 @problem = nil
113 @submissions = nil
117 @submissions = nil
114 else
118 else
115 @problem = Problem.find_by_name(params[:id])
119 @problem = Problem.find_by_name(params[:id])
116 if not @problem.available
120 if not @problem.available
117 redirect_to :action => 'list'
121 redirect_to :action => 'list'
118 flash[:notice] = 'Error: submissions for that problem are not viewable.'
122 flash[:notice] = 'Error: submissions for that problem are not viewable.'
119 return
123 return
120 end
124 end
121 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
125 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
122 end
126 end
123 end
127 end
124
128
125 def result
129 def result
126 if !Configuration.show_grading_result
130 if !Configuration.show_grading_result
127 redirect_to :action => 'list' and return
131 redirect_to :action => 'list' and return
128 end
132 end
129 @user = User.find(session[:user_id])
133 @user = User.find(session[:user_id])
130 @submission = Submission.find(params[:id])
134 @submission = Submission.find(params[:id])
131 if @submission.user!=@user
135 if @submission.user!=@user
132 flash[:notice] = 'You are not allowed to view result of other users.'
136 flash[:notice] = 'You are not allowed to view result of other users.'
133 redirect_to :action => 'list' and return
137 redirect_to :action => 'list' and return
134 end
138 end
135 prepare_grading_result(@submission)
139 prepare_grading_result(@submission)
136 end
140 end
137
141
138 def load_output
142 def load_output
139 if !Configuration.show_grading_result or params[:num]==nil
143 if !Configuration.show_grading_result or params[:num]==nil
140 redirect_to :action => 'list' and return
144 redirect_to :action => 'list' and return
141 end
145 end
142 @user = User.find(session[:user_id])
146 @user = User.find(session[:user_id])
143 @submission = Submission.find(params[:id])
147 @submission = Submission.find(params[:id])
144 if @submission.user!=@user
148 if @submission.user!=@user
145 flash[:notice] = 'You are not allowed to view result of other users.'
149 flash[:notice] = 'You are not allowed to view result of other users.'
146 redirect_to :action => 'list' and return
150 redirect_to :action => 'list' and return
147 end
151 end
148 case_num = params[:num].to_i
152 case_num = params[:num].to_i
149 out_filename = output_filename(@user.login,
153 out_filename = output_filename(@user.login,
150 @submission.problem.name,
154 @submission.problem.name,
151 @submission.id,
155 @submission.id,
152 case_num)
156 case_num)
153 if !FileTest.exists?(out_filename)
157 if !FileTest.exists?(out_filename)
154 flash[:notice] = 'Output not found.'
158 flash[:notice] = 'Output not found.'
155 redirect_to :action => 'list' and return
159 redirect_to :action => 'list' and return
156 end
160 end
157
161
158 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
162 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
159 response.headers['Content-Type'] = "application/force-download"
163 response.headers['Content-Type'] = "application/force-download"
160 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
164 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
161 response.headers["X-Sendfile"] = out_filename
165 response.headers["X-Sendfile"] = out_filename
162 response.headers['Content-length'] = File.size(out_filename)
166 response.headers['Content-length'] = File.size(out_filename)
163 render :nothing => true
167 render :nothing => true
164 else
168 else
165 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
169 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
166 end
170 end
167 end
171 end
168
172
169 def error
173 def error
170 @user = User.find(session[:user_id])
174 @user = User.find(session[:user_id])
171 end
175 end
172
176
173 # announcement refreshing and hiding methods
177 # announcement refreshing and hiding methods
174
178
175 def announcements
179 def announcements
176 if params.has_key? 'recent'
180 if params.has_key? 'recent'
177 prepare_announcements(params[:recent])
181 prepare_announcements(params[:recent])
178 else
182 else
179 prepare_announcements
183 prepare_announcements
180 end
184 end
181 render(:partial => 'announcement',
185 render(:partial => 'announcement',
182 :collection => @announcements,
186 :collection => @announcements,
183 :locals => {:announcement_effect => true})
187 :locals => {:announcement_effect => true})
184 end
188 end
185
189
190 + def confirm_contest_start
191 + user = User.find(session[:user_id])
192 + if request.method == :post
193 + user.update_start_time
194 + redirect_to :action => 'list'
195 + else
196 + @contests = user.contests
197 + @user = user
198 + end
199 + end
200 +
186 protected
201 protected
187
202
188 def prepare_announcements(recent=nil)
203 def prepare_announcements(recent=nil)
189 if Configuration.show_tasks_to?(@user)
204 if Configuration.show_tasks_to?(@user)
190 @announcements = Announcement.find_published(true)
205 @announcements = Announcement.find_published(true)
191 else
206 else
192 @announcements = Announcement.find_published
207 @announcements = Announcement.find_published
193 end
208 end
194 if recent!=nil
209 if recent!=nil
195 recent_id = recent.to_i
210 recent_id = recent.to_i
196 @announcements = @announcements.find_all { |a| a.id > recent_id }
211 @announcements = @announcements.find_all { |a| a.id > recent_id }
197 end
212 end
198 end
213 end
199
214
200 def prepare_list_information
215 def prepare_list_information
201 @user = User.find(session[:user_id])
216 @user = User.find(session[:user_id])
202 if not Configuration.multicontests?
217 if not Configuration.multicontests?
203 @problems = @user.available_problems
218 @problems = @user.available_problems
204 else
219 else
205 @contest_problems = @user.available_problems_group_by_contests
220 @contest_problems = @user.available_problems_group_by_contests
206 @problems = @user.available_problems
221 @problems = @user.available_problems
207 end
222 end
208 @prob_submissions = {}
223 @prob_submissions = {}
209 @problems.each do |p|
224 @problems.each do |p|
210 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
225 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
211 if sub!=nil
226 if sub!=nil
212 @prob_submissions[p.id] = { :count => sub.number, :submission => sub }
227 @prob_submissions[p.id] = { :count => sub.number, :submission => sub }
213 else
228 else
214 @prob_submissions[p.id] = { :count => 0, :submission => nil }
229 @prob_submissions[p.id] = { :count => 0, :submission => nil }
215 end
230 end
216 end
231 end
217 prepare_announcements
232 prepare_announcements
218 end
233 end
219
234
220 def check_viewability
235 def check_viewability
221 @user = User.find(session[:user_id])
236 @user = User.find(session[:user_id])
222 if (!Configuration.show_tasks_to?(@user)) and
237 if (!Configuration.show_tasks_to?(@user)) and
223 ((action_name=='submission') or (action_name=='submit'))
238 ((action_name=='submission') or (action_name=='submit'))
224 redirect_to :action => 'list' and return
239 redirect_to :action => 'list' and return
225 end
240 end
226 end
241 end
227
242
228 def prepare_grading_result(submission)
243 def prepare_grading_result(submission)
229 if Configuration.task_grading_info.has_key? submission.problem.name
244 if Configuration.task_grading_info.has_key? submission.problem.name
230 grading_info = Configuration.task_grading_info[submission.problem.name]
245 grading_info = Configuration.task_grading_info[submission.problem.name]
231 else
246 else
232 # guess task info from problem.full_score
247 # guess task info from problem.full_score
233 cases = submission.problem.full_score / 10
248 cases = submission.problem.full_score / 10
234 grading_info = {
249 grading_info = {
235 'testruns' => cases,
250 'testruns' => cases,
236 'testcases' => cases
251 'testcases' => cases
237 }
252 }
238 end
253 end
239 @test_runs = []
254 @test_runs = []
240 if grading_info['testruns'].is_a? Integer
255 if grading_info['testruns'].is_a? Integer
241 trun_count = grading_info['testruns']
256 trun_count = grading_info['testruns']
242 trun_count.times do |i|
257 trun_count.times do |i|
243 @test_runs << [ read_grading_result(@user.login,
258 @test_runs << [ read_grading_result(@user.login,
244 submission.problem.name,
259 submission.problem.name,
245 submission.id,
260 submission.id,
246 i+1) ]
261 i+1) ]
247 end
262 end
248 else
263 else
249 grading_info['testruns'].keys.sort.each do |num|
264 grading_info['testruns'].keys.sort.each do |num|
250 run = []
265 run = []
251 testrun = grading_info['testruns'][num]
266 testrun = grading_info['testruns'][num]
252 testrun.each do |c|
267 testrun.each do |c|
253 run << read_grading_result(@user.login,
268 run << read_grading_result(@user.login,
254 submission.problem.name,
269 submission.problem.name,
255 submission.id,
270 submission.id,
256 c)
271 c)
257 end
272 end
258 @test_runs << run
273 @test_runs << run
259 end
274 end
260 end
275 end
261 end
276 end
262
277
263 def grading_result_dir(user_name, problem_name, submission_id, case_num)
278 def grading_result_dir(user_name, problem_name, submission_id, case_num)
264 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
279 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
265 end
280 end
266
281
267 def output_filename(user_name, problem_name, submission_id, case_num)
282 def output_filename(user_name, problem_name, submission_id, case_num)
268 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
283 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
269 return "#{dir}/output.txt"
284 return "#{dir}/output.txt"
270 end
285 end
271
286
272 def read_grading_result(user_name, problem_name, submission_id, case_num)
287 def read_grading_result(user_name, problem_name, submission_id, case_num)
273 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
288 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
274 result_file_name = "#{dir}/result"
289 result_file_name = "#{dir}/result"
275 if !FileTest.exists?(result_file_name)
290 if !FileTest.exists?(result_file_name)
276 return {:num => case_num, :msg => 'program did not run'}
291 return {:num => case_num, :msg => 'program did not run'}
277 else
292 else
278 results = File.open(result_file_name).readlines
293 results = File.open(result_file_name).readlines
279 run_stat = extract_running_stat(results)
294 run_stat = extract_running_stat(results)
280 output_filename = "#{dir}/output.txt"
295 output_filename = "#{dir}/output.txt"
281 if FileTest.exists?(output_filename)
296 if FileTest.exists?(output_filename)
282 output_file = true
297 output_file = true
283 output_size = File.size(output_filename)
298 output_size = File.size(output_filename)
284 else
299 else
285 output_file = false
300 output_file = false
286 output_size = 0
301 output_size = 0
287 end
302 end
288
303
289 return {
304 return {
290 :num => case_num,
305 :num => case_num,
291 :msg => results[0],
306 :msg => results[0],
292 :run_stat => run_stat,
307 :run_stat => run_stat,
293 :output => output_file,
308 :output => output_file,
294 :output_size => output_size
309 :output_size => output_size
295 }
310 }
296 end
311 end
297 end
312 end
298
313
299 # copied from grader/script/lib/test_request_helper.rb
314 # copied from grader/script/lib/test_request_helper.rb
300 def extract_running_stat(results)
315 def extract_running_stat(results)
301 running_stat_line = results[-1]
316 running_stat_line = results[-1]
302
317
303 # extract exit status line
318 # extract exit status line
304 run_stat = ""
319 run_stat = ""
305 if !(/[Cc]orrect/.match(results[0]))
320 if !(/[Cc]orrect/.match(results[0]))
306 run_stat = results[0].chomp
321 run_stat = results[0].chomp
307 else
322 else
308 run_stat = 'Program exited normally'
323 run_stat = 'Program exited normally'
309 end
324 end
310
325
311 logger.info "Stat line: #{running_stat_line}"
326 logger.info "Stat line: #{running_stat_line}"
312
327
313 # extract running time
328 # extract running time
314 if res = /r(.*)u(.*)s/.match(running_stat_line)
329 if res = /r(.*)u(.*)s/.match(running_stat_line)
315 seconds = (res[1].to_f + res[2].to_f)
330 seconds = (res[1].to_f + res[2].to_f)
316 time_stat = "Time used: #{seconds} sec."
331 time_stat = "Time used: #{seconds} sec."
317 else
332 else
318 seconds = nil
333 seconds = nil
319 time_stat = "Time used: n/a sec."
334 time_stat = "Time used: n/a sec."
320 end
335 end
321
336
322 # extract memory usage
337 # extract memory usage
323 if res = /s(.*)m/.match(running_stat_line)
338 if res = /s(.*)m/.match(running_stat_line)
324 memory_used = res[1].to_i
339 memory_used = res[1].to_i
325 else
340 else
326 memory_used = -1
341 memory_used = -1
327 end
342 end
328
343
329 return {
344 return {
330 :msg => "#{run_stat}\n#{time_stat}",
345 :msg => "#{run_stat}\n#{time_stat}",
331 :running_time => seconds,
346 :running_time => seconds,
332 :exit_status => run_stat,
347 :exit_status => run_stat,
333 :memory_usage => memory_used
348 :memory_usage => memory_used
334 }
349 }
335 end
350 end
336
351
337 - def update_user_start_time
352 + def confirm_and_update_start_time
338 user = User.find(session[:user_id])
353 user = User.find(session[:user_id])
354 + if (Configuration.indv_contest_mode? and
355 + Configuration['contest.confirm_indv_contest_start'] and
356 + !user.contest_started?)
357 + redirect_to :action => 'confirm_contest_start' and return
358 + end
339 user.update_start_time
359 user.update_start_time
340 end
360 end
341
361
342 def reject_announcement_refresh_when_logged_out
362 def reject_announcement_refresh_when_logged_out
343 if not session[:user_id]
363 if not session[:user_id]
344 render :text => 'Access forbidden', :status => 403
364 render :text => 'Access forbidden', :status => 403
345 end
365 end
346
366
347 if Configuration.multicontests?
367 if Configuration.multicontests?
348 user = User.find(session[:user_id])
368 user = User.find(session[:user_id])
349 if user.contest_stat.forced_logout
369 if user.contest_stat.forced_logout
350 render :text => 'Access forbidden', :status => 403
370 render :text => 'Access forbidden', :status => 403
351 end
371 end
352 end
372 end
353 end
373 end
354
374
355 end
375 end
356
376
@@ -79,193 +79,196
79 if self.email==nil
79 if self.email==nil
80 "(unknown)"
80 "(unknown)"
81 elsif self.email==''
81 elsif self.email==''
82 "(blank)"
82 "(blank)"
83 else
83 else
84 self.email
84 self.email
85 end
85 end
86 end
86 end
87
87
88 def email_for_editing=(e)
88 def email_for_editing=(e)
89 self.email=e
89 self.email=e
90 end
90 end
91
91
92 def alias_for_editing
92 def alias_for_editing
93 if self.alias==nil
93 if self.alias==nil
94 "(unknown)"
94 "(unknown)"
95 elsif self.alias==''
95 elsif self.alias==''
96 "(blank)"
96 "(blank)"
97 else
97 else
98 self.alias
98 self.alias
99 end
99 end
100 end
100 end
101
101
102 def alias_for_editing=(e)
102 def alias_for_editing=(e)
103 self.alias=e
103 self.alias=e
104 end
104 end
105
105
106 def activation_key
106 def activation_key
107 if self.hashed_password==nil
107 if self.hashed_password==nil
108 encrypt_new_password
108 encrypt_new_password
109 end
109 end
110 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
110 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
111 end
111 end
112
112
113 def verify_activation_key(key)
113 def verify_activation_key(key)
114 key == activation_key
114 key == activation_key
115 end
115 end
116
116
117 def self.random_password(length=5)
117 def self.random_password(length=5)
118 chars = 'abcdefghjkmnopqrstuvwxyz'
118 chars = 'abcdefghjkmnopqrstuvwxyz'
119 password = ''
119 password = ''
120 length.times { password << chars[rand(chars.length - 1)] }
120 length.times { password << chars[rand(chars.length - 1)] }
121 password
121 password
122 end
122 end
123
123
124 def self.find_non_admin_with_prefix(prefix='')
124 def self.find_non_admin_with_prefix(prefix='')
125 users = User.find(:all)
125 users = User.find(:all)
126 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
126 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
127 end
127 end
128
128
129 # Contest information
129 # Contest information
130
130
131 def self.find_users_with_no_contest()
131 def self.find_users_with_no_contest()
132 users = User.find(:all)
132 users = User.find(:all)
133 return users.find_all { |u| u.contests.length == 0 }
133 return users.find_all { |u| u.contests.length == 0 }
134 end
134 end
135
135
136
136
137 def contest_time_left
137 def contest_time_left
138 if Configuration.contest_mode?
138 if Configuration.contest_mode?
139 return nil if site==nil
139 return nil if site==nil
140 return site.time_left
140 return site.time_left
141 elsif Configuration.indv_contest_mode?
141 elsif Configuration.indv_contest_mode?
142 time_limit = Configuration.contest_time_limit
142 time_limit = Configuration.contest_time_limit
143 if time_limit == nil
143 if time_limit == nil
144 return nil
144 return nil
145 end
145 end
146 if contest_stat==nil or contest_stat.started_at==nil
146 if contest_stat==nil or contest_stat.started_at==nil
147 return (Time.now.gmtime + time_limit) - Time.now.gmtime
147 return (Time.now.gmtime + time_limit) - Time.now.gmtime
148 else
148 else
149 finish_time = contest_stat.started_at + time_limit
149 finish_time = contest_stat.started_at + time_limit
150 current_time = Time.now.gmtime
150 current_time = Time.now.gmtime
151 if current_time > finish_time
151 if current_time > finish_time
152 return 0
152 return 0
153 else
153 else
154 return finish_time - current_time
154 return finish_time - current_time
155 end
155 end
156 end
156 end
157 else
157 else
158 return nil
158 return nil
159 end
159 end
160 end
160 end
161
161
162 def contest_finished?
162 def contest_finished?
163 if Configuration.contest_mode?
163 if Configuration.contest_mode?
164 return false if site==nil
164 return false if site==nil
165 return site.finished?
165 return site.finished?
166 elsif Configuration.indv_contest_mode?
166 elsif Configuration.indv_contest_mode?
167 return false if self.contest_stat(true)==nil
167 return false if self.contest_stat(true)==nil
168 return contest_time_left == 0
168 return contest_time_left == 0
169 else
169 else
170 return false
170 return false
171 end
171 end
172 end
172 end
173
173
174 def contest_started?
174 def contest_started?
175 - if Configuration.contest_mode?
175 + if Configuration.indv_contest_mode?
176 + stat = self.contest_stat
177 + return ((stat != nil) and (stat.started_at != nil))
178 + elsif Configuration.contest_mode?
176 return true if site==nil
179 return true if site==nil
177 return site.started
180 return site.started
178 else
181 else
179 return true
182 return true
180 end
183 end
181 end
184 end
182
185
183 def update_start_time
186 def update_start_time
184 stat = self.contest_stat
187 stat = self.contest_stat
185 if stat == nil or stat.started_at == nil
188 if stat == nil or stat.started_at == nil
186 stat ||= UserContestStat.new(:user => self)
189 stat ||= UserContestStat.new(:user => self)
187 stat.started_at = Time.now.gmtime
190 stat.started_at = Time.now.gmtime
188 stat.save
191 stat.save
189 end
192 end
190 end
193 end
191
194
192 def problem_in_user_contests?(problem)
195 def problem_in_user_contests?(problem)
193 problem_contests = problem.contests.all
196 problem_contests = problem.contests.all
194
197
195 if problem_contests.length == 0 # this is public contest
198 if problem_contests.length == 0 # this is public contest
196 return true
199 return true
197 end
200 end
198
201
199 contests.each do |contest|
202 contests.each do |contest|
200 if problem_contests.find {|c| c.id == contest.id }
203 if problem_contests.find {|c| c.id == contest.id }
201 return true
204 return true
202 end
205 end
203 end
206 end
204 return false
207 return false
205 end
208 end
206
209
207 def available_problems_group_by_contests
210 def available_problems_group_by_contests
208 contest_problems = []
211 contest_problems = []
209 pin = {}
212 pin = {}
210 contests.enabled.each do |contest|
213 contests.enabled.each do |contest|
211 available_problems = contest.problems.available
214 available_problems = contest.problems.available
212 contest_problems << {
215 contest_problems << {
213 :contest => contest,
216 :contest => contest,
214 :problems => available_problems
217 :problems => available_problems
215 }
218 }
216 available_problems.each {|p| pin[p.id] = true}
219 available_problems.each {|p| pin[p.id] = true}
217 end
220 end
218 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
221 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
219 contest_problems << {
222 contest_problems << {
220 :contest => nil,
223 :contest => nil,
221 :problems => other_avaiable_problems
224 :problems => other_avaiable_problems
222 }
225 }
223 return contest_problems
226 return contest_problems
224 end
227 end
225
228
226 def available_problems
229 def available_problems
227 if not Configuration.multicontests?
230 if not Configuration.multicontests?
228 return Problem.find_available_problems
231 return Problem.find_available_problems
229 else
232 else
230 contest_problems = []
233 contest_problems = []
231 pin = {}
234 pin = {}
232 contests.enabled.each do |contest|
235 contests.enabled.each do |contest|
233 contest.problems.available.each do |problem|
236 contest.problems.available.each do |problem|
234 if not pin.has_key? problem.id
237 if not pin.has_key? problem.id
235 contest_problems << problem
238 contest_problems << problem
236 end
239 end
237 pin[problem.id] = true
240 pin[problem.id] = true
238 end
241 end
239 end
242 end
240 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
243 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
241 return contest_problems + other_avaiable_problems
244 return contest_problems + other_avaiable_problems
242 end
245 end
243 end
246 end
244
247
245 def can_view_problem?(problem)
248 def can_view_problem?(problem)
246 if not Configuration.multicontests?
249 if not Configuration.multicontests?
247 return problem.available
250 return problem.available
248 else
251 else
249 return problem_in_user_contests? problem
252 return problem_in_user_contests? problem
250 end
253 end
251 end
254 end
252
255
253 protected
256 protected
254 def encrypt_new_password
257 def encrypt_new_password
255 return if password.blank?
258 return if password.blank?
256 self.salt = (10+rand(90)).to_s
259 self.salt = (10+rand(90)).to_s
257 self.hashed_password = User.encrypt(self.password,self.salt)
260 self.hashed_password = User.encrypt(self.password,self.salt)
258 end
261 end
259
262
260 def assign_default_site
263 def assign_default_site
261 # have to catch error when migrating (because self.site is not available).
264 # have to catch error when migrating (because self.site is not available).
262 begin
265 begin
263 if self.site==nil
266 if self.site==nil
264 self.site = Site.find_by_name('default')
267 self.site = Site.find_by_name('default')
265 if self.site==nil
268 if self.site==nil
266 self.site = Site.find(1) # when 'default has be renamed'
269 self.site = Site.find(1) # when 'default has be renamed'
267 end
270 end
268 end
271 end
269 rescue
272 rescue
270 end
273 end
271 end
274 end
@@ -8,177 +8,183
8 },
8 },
9
9
10 {
10 {
11 :key => 'ui.front.title',
11 :key => 'ui.front.title',
12 :value_type => 'string',
12 :value_type => 'string',
13 :default_value => 'Grader'
13 :default_value => 'Grader'
14 },
14 },
15
15
16 {
16 {
17 :key => 'ui.front.welcome_message',
17 :key => 'ui.front.welcome_message',
18 :value_type => 'string',
18 :value_type => 'string',
19 :default_value => 'Welcome!'
19 :default_value => 'Welcome!'
20 },
20 },
21
21
22 {
22 {
23 :key => 'ui.show_score',
23 :key => 'ui.show_score',
24 :value_type => 'boolean',
24 :value_type => 'boolean',
25 :default_value => 'true'
25 :default_value => 'true'
26 },
26 },
27
27
28 {
28 {
29 :key => 'contest.time_limit',
29 :key => 'contest.time_limit',
30 :value_type => 'string',
30 :value_type => 'string',
31 :default_value => 'unlimited',
31 :default_value => 'unlimited',
32 :description => 'Time limit in format hh:mm, or "unlimited" for contests with no time limits. This config is CACHED. Restart the server before the change can take effect.'
32 :description => 'Time limit in format hh:mm, or "unlimited" for contests with no time limits. This config is CACHED. Restart the server before the change can take effect.'
33 },
33 },
34
34
35 {
35 {
36 :key => 'system.mode',
36 :key => 'system.mode',
37 :value_type => 'string',
37 :value_type => 'string',
38 :default_value => 'standard',
38 :default_value => 'standard',
39 :description => 'Current modes are "standard", "contest", "indv-contest", and "analysis".'
39 :description => 'Current modes are "standard", "contest", "indv-contest", and "analysis".'
40 },
40 },
41
41
42 {
42 {
43 :key => 'contest.name',
43 :key => 'contest.name',
44 :value_type => 'string',
44 :value_type => 'string',
45 :default_value => 'Grader',
45 :default_value => 'Grader',
46 :description => 'This name will be shown on the user header bar.'
46 :description => 'This name will be shown on the user header bar.'
47 },
47 },
48
48
49 {
49 {
50 :key => 'contest.multisites',
50 :key => 'contest.multisites',
51 :value_type => 'boolean',
51 :value_type => 'boolean',
52 :default_value => 'false',
52 :default_value => 'false',
53 :description => 'If the server is in contest mode and this option is true, on the log in of the admin a menu for site selections is shown.'
53 :description => 'If the server is in contest mode and this option is true, on the log in of the admin a menu for site selections is shown.'
54 },
54 },
55
55
56 {
56 {
57 :key => 'system.online_registration',
57 :key => 'system.online_registration',
58 :value_type => 'boolean',
58 :value_type => 'boolean',
59 :default_value => 'false',
59 :default_value => 'false',
60 :description => 'This option enables online registration.'
60 :description => 'This option enables online registration.'
61 },
61 },
62
62
63 # If Configuration['system.online_registration'] is true, the
63 # If Configuration['system.online_registration'] is true, the
64 # system allows online registration, and will use these
64 # system allows online registration, and will use these
65 # information for sending confirmation emails.
65 # information for sending confirmation emails.
66 {
66 {
67 :key => 'system.online_registration.smtp',
67 :key => 'system.online_registration.smtp',
68 :value_type => 'string',
68 :value_type => 'string',
69 :default_value => 'smtp.somehost.com'
69 :default_value => 'smtp.somehost.com'
70 },
70 },
71
71
72 {
72 {
73 :key => 'system.online_registration.from',
73 :key => 'system.online_registration.from',
74 :value_type => 'string',
74 :value_type => 'string',
75 :default_value => 'your.email@address'
75 :default_value => 'your.email@address'
76 },
76 },
77
77
78 {
78 {
79 :key => 'system.admin_email',
79 :key => 'system.admin_email',
80 :value_type => 'string',
80 :value_type => 'string',
81 :default_value => 'admin@admin.email'
81 :default_value => 'admin@admin.email'
82 },
82 },
83
83
84 {
84 {
85 :key => 'system.user_setting_enabled',
85 :key => 'system.user_setting_enabled',
86 :value_type => 'boolean',
86 :value_type => 'boolean',
87 :default_value => 'true',
87 :default_value => 'true',
88 :description => 'If this option is true, users can change their settings'
88 :description => 'If this option is true, users can change their settings'
89 },
89 },
90
90
91 # If Configuration['contest.test_request.early_timeout'] is true
91 # If Configuration['contest.test_request.early_timeout'] is true
92 # the user will not be able to use test request at 30 minutes
92 # the user will not be able to use test request at 30 minutes
93 # before the contest ends.
93 # before the contest ends.
94 {
94 {
95 :key => 'contest.test_request.early_timeout',
95 :key => 'contest.test_request.early_timeout',
96 :value_type => 'boolean',
96 :value_type => 'boolean',
97 :default_value => 'false'
97 :default_value => 'false'
98 },
98 },
99
99
100 {
100 {
101 :key => 'system.multicontests',
101 :key => 'system.multicontests',
102 :value_type => 'boolean',
102 :value_type => 'boolean',
103 :default_value => 'false'
103 :default_value => 'false'
104 + },
105 +
106 + {
107 + :key => 'contest.confirm_indv_contest_start',
108 + :value_type => 'boolean',
109 + :default_value => 'false'
104 }
110 }
105 ]
111 ]
106
112
107
113
108 def create_configuration_key(key,
114 def create_configuration_key(key,
109 value_type,
115 value_type,
110 default_value,
116 default_value,
111 description='')
117 description='')
112 conf = (Configuration.find_by_key(key) ||
118 conf = (Configuration.find_by_key(key) ||
113 Configuration.new(:key => key,
119 Configuration.new(:key => key,
114 :value_type => value_type,
120 :value_type => value_type,
115 :value => default_value))
121 :value => default_value))
116 conf.description = description
122 conf.description = description
117 conf.save
123 conf.save
118 end
124 end
119
125
120 def seed_config
126 def seed_config
121 CONFIGURATIONS.each do |conf|
127 CONFIGURATIONS.each do |conf|
122 if conf.has_key? :description
128 if conf.has_key? :description
123 desc = conf[:description]
129 desc = conf[:description]
124 else
130 else
125 desc = ''
131 desc = ''
126 end
132 end
127 create_configuration_key(conf[:key],
133 create_configuration_key(conf[:key],
128 conf[:value_type],
134 conf[:value_type],
129 conf[:default_value],
135 conf[:default_value],
130 desc)
136 desc)
131 end
137 end
132 end
138 end
133
139
134 def seed_roles
140 def seed_roles
135 return if Role.find_by_name('admin')
141 return if Role.find_by_name('admin')
136
142
137 role = Role.create(:name => 'admin')
143 role = Role.create(:name => 'admin')
138 user_admin_right = Right.create(:name => 'user_admin',
144 user_admin_right = Right.create(:name => 'user_admin',
139 :controller => 'user_admin',
145 :controller => 'user_admin',
140 :action => 'all')
146 :action => 'all')
141 problem_admin_right = Right.create(:name=> 'problem_admin',
147 problem_admin_right = Right.create(:name=> 'problem_admin',
142 :controller => 'problems',
148 :controller => 'problems',
143 :action => 'all')
149 :action => 'all')
144
150
145 graders_right = Right.create(:name => 'graders_admin',
151 graders_right = Right.create(:name => 'graders_admin',
146 :controller => 'graders',
152 :controller => 'graders',
147 :action => 'all')
153 :action => 'all')
148
154
149 role.rights << user_admin_right;
155 role.rights << user_admin_right;
150 role.rights << problem_admin_right;
156 role.rights << problem_admin_right;
151 role.rights << graders_right;
157 role.rights << graders_right;
152 role.save
158 role.save
153 end
159 end
154
160
155 def seed_root
161 def seed_root
156 return if User.find_by_login('root')
162 return if User.find_by_login('root')
157
163
158 root = User.new(:login => 'root',
164 root = User.new(:login => 'root',
159 :full_name => 'Administrator',
165 :full_name => 'Administrator',
160 :alias => 'root')
166 :alias => 'root')
161 root.password = 'ioionrails';
167 root.password = 'ioionrails';
162
168
163 class << root
169 class << root
164 public :encrypt_new_password
170 public :encrypt_new_password
165 def valid?
171 def valid?
166 true
172 true
167 end
173 end
168 end
174 end
169
175
170 root.encrypt_new_password
176 root.encrypt_new_password
171
177
172 root.roles << Role.find_by_name('admin')
178 root.roles << Role.find_by_name('admin')
173
179
174 root.activated = true
180 root.activated = true
175 root.save
181 root.save
176 end
182 end
177
183
178 def seed_users_and_roles
184 def seed_users_and_roles
179 seed_roles
185 seed_roles
180 seed_root
186 seed_root
181 end
187 end
182
188
183 seed_config
189 seed_config
184 seed_users_and_roles
190 seed_users_and_roles
You need to be logged in to leave comments. Login now