Description:
does not record login time in analysis mode
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r317:df35763dc517 - - 1 file changed: 2 inserted, 0 deleted

@@ -1,378 +1,380
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 :confirm_and_update_start_time,
6 append_before_filter :confirm_and_update_start_time,
7 :except => [:index,
7 :except => [:index,
8 :login,
8 :login,
9 :confirm_contest_start]
9 :confirm_contest_start]
10
10
11 # 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
12 # system only in some tab
12 # system only in some tab
13 prepend_before_filter :reject_announcement_refresh_when_logged_out,
13 prepend_before_filter :reject_announcement_refresh_when_logged_out,
14 :only => [:announcements]
14 :only => [:announcements]
15
15
16 # COMMENTED OUT: filter in each action instead
16 # COMMENTED OUT: filter in each action instead
17 # before_filter :verify_time_limit, :only => [:submit]
17 # before_filter :verify_time_limit, :only => [:submit]
18
18
19 verify :method => :post, :only => [:submit],
19 verify :method => :post, :only => [:submit],
20 :redirect_to => { :action => :index }
20 :redirect_to => { :action => :index }
21
21
22 # COMMENT OUT: only need when having high load
22 # COMMENT OUT: only need when having high load
23 # caches_action :index, :login
23 # caches_action :index, :login
24
24
25 # NOTE: This method is not actually needed, 'config/routes.rb' has
25 # NOTE: This method is not actually needed, 'config/routes.rb' has
26 # assigned action login as a default action.
26 # assigned action login as a default action.
27 def index
27 def index
28 redirect_to :action => 'login'
28 redirect_to :action => 'login'
29 end
29 end
30
30
31 def login
31 def login
32 saved_notice = flash[:notice]
32 saved_notice = flash[:notice]
33 reset_session
33 reset_session
34 flash.now[:notice] = saved_notice
34 flash.now[:notice] = saved_notice
35
35
36 # EXPERIMENT:
36 # EXPERIMENT:
37 # 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
38 # explicitly specify /login
38 # explicitly specify /login
39 #
39 #
40 # logger.info "PATH: #{request.path}"
40 # logger.info "PATH: #{request.path}"
41 # if Configuration['system.single_user_mode'] and
41 # if Configuration['system.single_user_mode'] and
42 # request.path!='/main/login'
42 # request.path!='/main/login'
43 # @hidelogin = true
43 # @hidelogin = true
44 # end
44 # end
45
45
46 @announcements = Announcement.find_for_frontpage
46 @announcements = Announcement.find_for_frontpage
47 render :action => 'login', :layout => 'empty'
47 render :action => 'login', :layout => 'empty'
48 end
48 end
49
49
50 def list
50 def list
51 prepare_list_information
51 prepare_list_information
52 end
52 end
53
53
54 def help
54 def help
55 @user = User.find(session[:user_id])
55 @user = User.find(session[:user_id])
56 end
56 end
57
57
58 def submit
58 def submit
59 user = User.find(session[:user_id])
59 user = User.find(session[:user_id])
60
60
61 @submission = Submission.new(params[:submission])
61 @submission = Submission.new(params[:submission])
62 @submission.user = user
62 @submission.user = user
63 @submission.language_id = 0
63 @submission.language_id = 0
64 if (params['file']) and (params['file']!='')
64 if (params['file']) and (params['file']!='')
65 @submission.source = params['file'].read
65 @submission.source = params['file'].read
66 @submission.source_filename = params['file'].original_filename
66 @submission.source_filename = params['file'].original_filename
67 end
67 end
68 @submission.submitted_at = Time.new.gmtime
68 @submission.submitted_at = Time.new.gmtime
69
69
70 if Configuration.time_limit_mode? and user.contest_finished?
70 if Configuration.time_limit_mode? and user.contest_finished?
71 @submission.errors.add_to_base "The contest is over."
71 @submission.errors.add_to_base "The contest is over."
72 prepare_list_information
72 prepare_list_information
73 render :action => 'list' and return
73 render :action => 'list' and return
74 end
74 end
75
75
76 if @submission.valid?
76 if @submission.valid?
77 if @submission.save == false
77 if @submission.save == false
78 flash[:notice] = 'Error saving your submission'
78 flash[:notice] = 'Error saving your submission'
79 elsif Task.create(:submission_id => @submission.id,
79 elsif Task.create(:submission_id => @submission.id,
80 :status => Task::STATUS_INQUEUE) == false
80 :status => Task::STATUS_INQUEUE) == false
81 flash[:notice] = 'Error adding your submission to task queue'
81 flash[:notice] = 'Error adding your submission to task queue'
82 end
82 end
83 else
83 else
84 prepare_list_information
84 prepare_list_information
85 render :action => 'list' and return
85 render :action => 'list' and return
86 end
86 end
87 redirect_to :action => 'list'
87 redirect_to :action => 'list'
88 end
88 end
89
89
90 def source
90 def source
91 submission = Submission.find(params[:id])
91 submission = Submission.find(params[:id])
92 if ((submission.user_id == session[:user_id]) and
92 if ((submission.user_id == session[:user_id]) and
93 (submission.problem != nil) and
93 (submission.problem != nil) and
94 (submission.problem.available))
94 (submission.problem.available))
95 send_data(submission.source,
95 send_data(submission.source,
96 {:filename => submission.download_filename,
96 {:filename => submission.download_filename,
97 :type => 'text/plain'})
97 :type => 'text/plain'})
98 else
98 else
99 flash[:notice] = 'Error viewing source'
99 flash[:notice] = 'Error viewing source'
100 redirect_to :action => 'list'
100 redirect_to :action => 'list'
101 end
101 end
102 end
102 end
103
103
104 def compiler_msg
104 def compiler_msg
105 @submission = Submission.find(params[:id])
105 @submission = Submission.find(params[:id])
106 if @submission.user_id == session[:user_id]
106 if @submission.user_id == session[:user_id]
107 render :action => 'compiler_msg', :layout => 'empty'
107 render :action => 'compiler_msg', :layout => 'empty'
108 else
108 else
109 flash[:notice] = 'Error viewing source'
109 flash[:notice] = 'Error viewing source'
110 redirect_to :action => 'list'
110 redirect_to :action => 'list'
111 end
111 end
112 end
112 end
113
113
114 def submission
114 def submission
115 @user = User.find(session[:user_id])
115 @user = User.find(session[:user_id])
116 @problems = @user.available_problems
116 @problems = @user.available_problems
117 if params[:id]==nil
117 if params[:id]==nil
118 @problem = nil
118 @problem = nil
119 @submissions = nil
119 @submissions = nil
120 else
120 else
121 @problem = Problem.find_by_name(params[:id])
121 @problem = Problem.find_by_name(params[:id])
122 if not @problem.available
122 if not @problem.available
123 redirect_to :action => 'list'
123 redirect_to :action => 'list'
124 flash[:notice] = 'Error: submissions for that problem are not viewable.'
124 flash[:notice] = 'Error: submissions for that problem are not viewable.'
125 return
125 return
126 end
126 end
127 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
127 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
128 end
128 end
129 end
129 end
130
130
131 def result
131 def result
132 if !Configuration.show_grading_result
132 if !Configuration.show_grading_result
133 redirect_to :action => 'list' and return
133 redirect_to :action => 'list' and return
134 end
134 end
135 @user = User.find(session[:user_id])
135 @user = User.find(session[:user_id])
136 @submission = Submission.find(params[:id])
136 @submission = Submission.find(params[:id])
137 if @submission.user!=@user
137 if @submission.user!=@user
138 flash[:notice] = 'You are not allowed to view result of other users.'
138 flash[:notice] = 'You are not allowed to view result of other users.'
139 redirect_to :action => 'list' and return
139 redirect_to :action => 'list' and return
140 end
140 end
141 prepare_grading_result(@submission)
141 prepare_grading_result(@submission)
142 end
142 end
143
143
144 def load_output
144 def load_output
145 if !Configuration.show_grading_result or params[:num]==nil
145 if !Configuration.show_grading_result or params[:num]==nil
146 redirect_to :action => 'list' and return
146 redirect_to :action => 'list' and return
147 end
147 end
148 @user = User.find(session[:user_id])
148 @user = User.find(session[:user_id])
149 @submission = Submission.find(params[:id])
149 @submission = Submission.find(params[:id])
150 if @submission.user!=@user
150 if @submission.user!=@user
151 flash[:notice] = 'You are not allowed to view result of other users.'
151 flash[:notice] = 'You are not allowed to view result of other users.'
152 redirect_to :action => 'list' and return
152 redirect_to :action => 'list' and return
153 end
153 end
154 case_num = params[:num].to_i
154 case_num = params[:num].to_i
155 out_filename = output_filename(@user.login,
155 out_filename = output_filename(@user.login,
156 @submission.problem.name,
156 @submission.problem.name,
157 @submission.id,
157 @submission.id,
158 case_num)
158 case_num)
159 if !FileTest.exists?(out_filename)
159 if !FileTest.exists?(out_filename)
160 flash[:notice] = 'Output not found.'
160 flash[:notice] = 'Output not found.'
161 redirect_to :action => 'list' and return
161 redirect_to :action => 'list' and return
162 end
162 end
163
163
164 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
164 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
165 response.headers['Content-Type'] = "application/force-download"
165 response.headers['Content-Type'] = "application/force-download"
166 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
166 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
167 response.headers["X-Sendfile"] = out_filename
167 response.headers["X-Sendfile"] = out_filename
168 response.headers['Content-length'] = File.size(out_filename)
168 response.headers['Content-length'] = File.size(out_filename)
169 render :nothing => true
169 render :nothing => true
170 else
170 else
171 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
171 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
172 end
172 end
173 end
173 end
174
174
175 def error
175 def error
176 @user = User.find(session[:user_id])
176 @user = User.find(session[:user_id])
177 end
177 end
178
178
179 # announcement refreshing and hiding methods
179 # announcement refreshing and hiding methods
180
180
181 def announcements
181 def announcements
182 if params.has_key? 'recent'
182 if params.has_key? 'recent'
183 prepare_announcements(params[:recent])
183 prepare_announcements(params[:recent])
184 else
184 else
185 prepare_announcements
185 prepare_announcements
186 end
186 end
187 render(:partial => 'announcement',
187 render(:partial => 'announcement',
188 :collection => @announcements,
188 :collection => @announcements,
189 :locals => {:announcement_effect => true})
189 :locals => {:announcement_effect => true})
190 end
190 end
191
191
192 def confirm_contest_start
192 def confirm_contest_start
193 user = User.find(session[:user_id])
193 user = User.find(session[:user_id])
194 if request.method == :post
194 if request.method == :post
195 user.update_start_time
195 user.update_start_time
196 redirect_to :action => 'list'
196 redirect_to :action => 'list'
197 else
197 else
198 @contests = user.contests
198 @contests = user.contests
199 @user = user
199 @user = user
200 end
200 end
201 end
201 end
202
202
203 protected
203 protected
204
204
205 def prepare_announcements(recent=nil)
205 def prepare_announcements(recent=nil)
206 if Configuration.show_tasks_to?(@user)
206 if Configuration.show_tasks_to?(@user)
207 @announcements = Announcement.find_published(true)
207 @announcements = Announcement.find_published(true)
208 else
208 else
209 @announcements = Announcement.find_published
209 @announcements = Announcement.find_published
210 end
210 end
211 if recent!=nil
211 if recent!=nil
212 recent_id = recent.to_i
212 recent_id = recent.to_i
213 @announcements = @announcements.find_all { |a| a.id > recent_id }
213 @announcements = @announcements.find_all { |a| a.id > recent_id }
214 end
214 end
215 end
215 end
216
216
217 def prepare_list_information
217 def prepare_list_information
218 @user = User.find(session[:user_id])
218 @user = User.find(session[:user_id])
219 if not Configuration.multicontests?
219 if not Configuration.multicontests?
220 @problems = @user.available_problems
220 @problems = @user.available_problems
221 else
221 else
222 @contest_problems = @user.available_problems_group_by_contests
222 @contest_problems = @user.available_problems_group_by_contests
223 @problems = @user.available_problems
223 @problems = @user.available_problems
224 end
224 end
225 @prob_submissions = {}
225 @prob_submissions = {}
226 @problems.each do |p|
226 @problems.each do |p|
227 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
227 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
228 if sub!=nil
228 if sub!=nil
229 @prob_submissions[p.id] = { :count => sub.number, :submission => sub }
229 @prob_submissions[p.id] = { :count => sub.number, :submission => sub }
230 else
230 else
231 @prob_submissions[p.id] = { :count => 0, :submission => nil }
231 @prob_submissions[p.id] = { :count => 0, :submission => nil }
232 end
232 end
233 end
233 end
234 prepare_announcements
234 prepare_announcements
235 end
235 end
236
236
237 def check_viewability
237 def check_viewability
238 @user = User.find(session[:user_id])
238 @user = User.find(session[:user_id])
239 if (!Configuration.show_tasks_to?(@user)) and
239 if (!Configuration.show_tasks_to?(@user)) and
240 ((action_name=='submission') or (action_name=='submit'))
240 ((action_name=='submission') or (action_name=='submit'))
241 redirect_to :action => 'list' and return
241 redirect_to :action => 'list' and return
242 end
242 end
243 end
243 end
244
244
245 def prepare_grading_result(submission)
245 def prepare_grading_result(submission)
246 if Configuration.task_grading_info.has_key? submission.problem.name
246 if Configuration.task_grading_info.has_key? submission.problem.name
247 grading_info = Configuration.task_grading_info[submission.problem.name]
247 grading_info = Configuration.task_grading_info[submission.problem.name]
248 else
248 else
249 # guess task info from problem.full_score
249 # guess task info from problem.full_score
250 cases = submission.problem.full_score / 10
250 cases = submission.problem.full_score / 10
251 grading_info = {
251 grading_info = {
252 'testruns' => cases,
252 'testruns' => cases,
253 'testcases' => cases
253 'testcases' => cases
254 }
254 }
255 end
255 end
256 @test_runs = []
256 @test_runs = []
257 if grading_info['testruns'].is_a? Integer
257 if grading_info['testruns'].is_a? Integer
258 trun_count = grading_info['testruns']
258 trun_count = grading_info['testruns']
259 trun_count.times do |i|
259 trun_count.times do |i|
260 @test_runs << [ read_grading_result(@user.login,
260 @test_runs << [ read_grading_result(@user.login,
261 submission.problem.name,
261 submission.problem.name,
262 submission.id,
262 submission.id,
263 i+1) ]
263 i+1) ]
264 end
264 end
265 else
265 else
266 grading_info['testruns'].keys.sort.each do |num|
266 grading_info['testruns'].keys.sort.each do |num|
267 run = []
267 run = []
268 testrun = grading_info['testruns'][num]
268 testrun = grading_info['testruns'][num]
269 testrun.each do |c|
269 testrun.each do |c|
270 run << read_grading_result(@user.login,
270 run << read_grading_result(@user.login,
271 submission.problem.name,
271 submission.problem.name,
272 submission.id,
272 submission.id,
273 c)
273 c)
274 end
274 end
275 @test_runs << run
275 @test_runs << run
276 end
276 end
277 end
277 end
278 end
278 end
279
279
280 def grading_result_dir(user_name, problem_name, submission_id, case_num)
280 def grading_result_dir(user_name, problem_name, submission_id, case_num)
281 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
281 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
282 end
282 end
283
283
284 def output_filename(user_name, problem_name, submission_id, case_num)
284 def output_filename(user_name, problem_name, submission_id, case_num)
285 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
285 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
286 return "#{dir}/output.txt"
286 return "#{dir}/output.txt"
287 end
287 end
288
288
289 def read_grading_result(user_name, problem_name, submission_id, case_num)
289 def read_grading_result(user_name, problem_name, submission_id, case_num)
290 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
290 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
291 result_file_name = "#{dir}/result"
291 result_file_name = "#{dir}/result"
292 if !FileTest.exists?(result_file_name)
292 if !FileTest.exists?(result_file_name)
293 return {:num => case_num, :msg => 'program did not run'}
293 return {:num => case_num, :msg => 'program did not run'}
294 else
294 else
295 results = File.open(result_file_name).readlines
295 results = File.open(result_file_name).readlines
296 run_stat = extract_running_stat(results)
296 run_stat = extract_running_stat(results)
297 output_filename = "#{dir}/output.txt"
297 output_filename = "#{dir}/output.txt"
298 if FileTest.exists?(output_filename)
298 if FileTest.exists?(output_filename)
299 output_file = true
299 output_file = true
300 output_size = File.size(output_filename)
300 output_size = File.size(output_filename)
301 else
301 else
302 output_file = false
302 output_file = false
303 output_size = 0
303 output_size = 0
304 end
304 end
305
305
306 return {
306 return {
307 :num => case_num,
307 :num => case_num,
308 :msg => results[0],
308 :msg => results[0],
309 :run_stat => run_stat,
309 :run_stat => run_stat,
310 :output => output_file,
310 :output => output_file,
311 :output_size => output_size
311 :output_size => output_size
312 }
312 }
313 end
313 end
314 end
314 end
315
315
316 # copied from grader/script/lib/test_request_helper.rb
316 # copied from grader/script/lib/test_request_helper.rb
317 def extract_running_stat(results)
317 def extract_running_stat(results)
318 running_stat_line = results[-1]
318 running_stat_line = results[-1]
319
319
320 # extract exit status line
320 # extract exit status line
321 run_stat = ""
321 run_stat = ""
322 if !(/[Cc]orrect/.match(results[0]))
322 if !(/[Cc]orrect/.match(results[0]))
323 run_stat = results[0].chomp
323 run_stat = results[0].chomp
324 else
324 else
325 run_stat = 'Program exited normally'
325 run_stat = 'Program exited normally'
326 end
326 end
327
327
328 logger.info "Stat line: #{running_stat_line}"
328 logger.info "Stat line: #{running_stat_line}"
329
329
330 # extract running time
330 # extract running time
331 if res = /r(.*)u(.*)s/.match(running_stat_line)
331 if res = /r(.*)u(.*)s/.match(running_stat_line)
332 seconds = (res[1].to_f + res[2].to_f)
332 seconds = (res[1].to_f + res[2].to_f)
333 time_stat = "Time used: #{seconds} sec."
333 time_stat = "Time used: #{seconds} sec."
334 else
334 else
335 seconds = nil
335 seconds = nil
336 time_stat = "Time used: n/a sec."
336 time_stat = "Time used: n/a sec."
337 end
337 end
338
338
339 # extract memory usage
339 # extract memory usage
340 if res = /s(.*)m/.match(running_stat_line)
340 if res = /s(.*)m/.match(running_stat_line)
341 memory_used = res[1].to_i
341 memory_used = res[1].to_i
342 else
342 else
343 memory_used = -1
343 memory_used = -1
344 end
344 end
345
345
346 return {
346 return {
347 :msg => "#{run_stat}\n#{time_stat}",
347 :msg => "#{run_stat}\n#{time_stat}",
348 :running_time => seconds,
348 :running_time => seconds,
349 :exit_status => run_stat,
349 :exit_status => run_stat,
350 :memory_usage => memory_used
350 :memory_usage => memory_used
351 }
351 }
352 end
352 end
353
353
354 def confirm_and_update_start_time
354 def confirm_and_update_start_time
355 user = User.find(session[:user_id])
355 user = User.find(session[:user_id])
356 if (Configuration.indv_contest_mode? and
356 if (Configuration.indv_contest_mode? and
357 Configuration['contest.confirm_indv_contest_start'] and
357 Configuration['contest.confirm_indv_contest_start'] and
358 !user.contest_started?)
358 !user.contest_started?)
359 redirect_to :action => 'confirm_contest_start' and return
359 redirect_to :action => 'confirm_contest_start' and return
360 end
360 end
361 + if not Configuration.analysis_mode?
361 user.update_start_time
362 user.update_start_time
362 end
363 end
364 + end
363
365
364 def reject_announcement_refresh_when_logged_out
366 def reject_announcement_refresh_when_logged_out
365 if not session[:user_id]
367 if not session[:user_id]
366 render :text => 'Access forbidden', :status => 403
368 render :text => 'Access forbidden', :status => 403
367 end
369 end
368
370
369 if Configuration.multicontests?
371 if Configuration.multicontests?
370 user = User.find(session[:user_id])
372 user = User.find(session[:user_id])
371 if user.contest_stat.forced_logout
373 if user.contest_stat.forced_logout
372 render :text => 'Access forbidden', :status => 403
374 render :text => 'Access forbidden', :status => 403
373 end
375 end
374 end
376 end
375 end
377 end
376
378
377 end
379 end
378
380
You need to be logged in to leave comments. Login now