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,58 +1,62
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
@@ -138,96 +142,107
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
@@ -289,68 +304,73
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
@@ -127,97 +127,100
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
@@ -56,96 +56,102
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;
You need to be logged in to leave comments. Login now