Description:
added problem list auto update
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r257:76846842a151 - - 3 files changed: 14 inserted, 2 deleted

@@ -1,476 +1,485
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 :update_user_start_time, :except => [:index, :login]
7
7
8 # to prevent log in box to be shown when user logged out of the
8 # to prevent log in box to be shown when user logged out of the
9 # system only in some tab
9 # system only in some tab
10 prepend_before_filter :reject_announcement_refresh_when_logged_out, :only => [:announcements]
10 prepend_before_filter :reject_announcement_refresh_when_logged_out, :only => [:announcements]
11
11
12 # COMMENTED OUT: filter in each action instead
12 # COMMENTED OUT: filter in each action instead
13 # before_filter :verify_time_limit, :only => [:submit]
13 # before_filter :verify_time_limit, :only => [:submit]
14
14
15 verify :method => :post, :only => [:submit, :download_input, :submit_solution],
15 verify :method => :post, :only => [:submit, :download_input, :submit_solution],
16 :redirect_to => { :action => :index }
16 :redirect_to => { :action => :index }
17
17
18 # COMMENT OUT: only need when having high load
18 # COMMENT OUT: only need when having high load
19 # caches_action :index, :login
19 # caches_action :index, :login
20
20
21 # NOTE: This method is not actually needed, 'config/routes.rb' has
21 # NOTE: This method is not actually needed, 'config/routes.rb' has
22 # assigned action login as a default action.
22 # assigned action login as a default action.
23 def index
23 def index
24 redirect_to :action => 'login'
24 redirect_to :action => 'login'
25 end
25 end
26
26
27 def login
27 def login
28 saved_notice = flash[:notice]
28 saved_notice = flash[:notice]
29 reset_session
29 reset_session
30 flash.now[:notice] = saved_notice
30 flash.now[:notice] = saved_notice
31
31
32 # EXPERIMENT:
32 # EXPERIMENT:
33 # Hide login if in single user mode and the url does not
33 # Hide login if in single user mode and the url does not
34 # explicitly specify /login
34 # explicitly specify /login
35 #
35 #
36 # logger.info "PATH: #{request.path}"
36 # logger.info "PATH: #{request.path}"
37 # if Configuration['system.single_user_mode'] and
37 # if Configuration['system.single_user_mode'] and
38 # request.path!='/main/login'
38 # request.path!='/main/login'
39 # @hidelogin = true
39 # @hidelogin = true
40 # end
40 # end
41
41
42 @announcements = Announcement.find_for_frontpage
42 @announcements = Announcement.find_for_frontpage
43 render :action => 'login', :layout => 'empty'
43 render :action => 'login', :layout => 'empty'
44 end
44 end
45
45
46 def list
46 def list
47 prepare_list_information
47 prepare_list_information
48 end
48 end
49
49
50 def help
50 def help
51 @user = User.find(session[:user_id])
51 @user = User.find(session[:user_id])
52 end
52 end
53
53
54 def submit
54 def submit
55 user = User.find(session[:user_id])
55 user = User.find(session[:user_id])
56
56
57 @submission = Submission.new(params[:submission])
57 @submission = Submission.new(params[:submission])
58 @submission.user = user
58 @submission.user = user
59 @submission.language_id = 0
59 @submission.language_id = 0
60 if (params['file']) and (params['file']!='')
60 if (params['file']) and (params['file']!='')
61 @submission.source = params['file'].read
61 @submission.source = params['file'].read
62 @submission.source_filename = params['file'].original_filename
62 @submission.source_filename = params['file'].original_filename
63 end
63 end
64 @submission.submitted_at = Time.new.gmtime
64 @submission.submitted_at = Time.new.gmtime
65
65
66 if Configuration.time_limit_mode? and user.contest_finished?
66 if Configuration.time_limit_mode? and user.contest_finished?
67 @submission.errors.add_to_base "The contest is over."
67 @submission.errors.add_to_base "The contest is over."
68 prepare_list_information
68 prepare_list_information
69 render :action => 'list' and return
69 render :action => 'list' and return
70 end
70 end
71
71
72 if @submission.valid?
72 if @submission.valid?
73 if @submission.save == false
73 if @submission.save == false
74 flash[:notice] = 'Error saving your submission'
74 flash[:notice] = 'Error saving your submission'
75 elsif Task.create(:submission_id => @submission.id,
75 elsif Task.create(:submission_id => @submission.id,
76 :status => Task::STATUS_INQUEUE) == false
76 :status => Task::STATUS_INQUEUE) == false
77 flash[:notice] = 'Error adding your submission to task queue'
77 flash[:notice] = 'Error adding your submission to task queue'
78 end
78 end
79 else
79 else
80 prepare_list_information
80 prepare_list_information
81 render :action => 'list' and return
81 render :action => 'list' and return
82 end
82 end
83 redirect_to :action => 'list'
83 redirect_to :action => 'list'
84 end
84 end
85
85
86 def source
86 def source
87 submission = Submission.find(params[:id])
87 submission = Submission.find(params[:id])
88 if submission.user_id == session[:user_id]
88 if submission.user_id == session[:user_id]
89 send_data(submission.source,
89 send_data(submission.source,
90 {:filename => submission.download_filename,
90 {:filename => submission.download_filename,
91 :type => 'text/plain'})
91 :type => 'text/plain'})
92 else
92 else
93 flash[:notice] = 'Error viewing source'
93 flash[:notice] = 'Error viewing source'
94 redirect_to :action => 'list'
94 redirect_to :action => 'list'
95 end
95 end
96 end
96 end
97
97
98 def compiler_msg
98 def compiler_msg
99 @submission = Submission.find(params[:id])
99 @submission = Submission.find(params[:id])
100 if @submission.user_id == session[:user_id]
100 if @submission.user_id == session[:user_id]
101 render :action => 'compiler_msg', :layout => 'empty'
101 render :action => 'compiler_msg', :layout => 'empty'
102 else
102 else
103 flash[:notice] = 'Error viewing source'
103 flash[:notice] = 'Error viewing source'
104 redirect_to :action => 'list'
104 redirect_to :action => 'list'
105 end
105 end
106 end
106 end
107
107
108 def submission
108 def submission
109 # protect the action for Code Jom
109 # protect the action for Code Jom
110 redirect_to :action => 'list'
110 redirect_to :action => 'list'
111
111
112 @user = User.find(session[:user_id])
112 @user = User.find(session[:user_id])
113 @problems = Problem.find_available_problems
113 @problems = Problem.find_available_problems
114 if params[:id]==nil
114 if params[:id]==nil
115 @problem = nil
115 @problem = nil
116 @submissions = nil
116 @submissions = nil
117 else
117 else
118 @problem = Problem.find_by_name(params[:id])
118 @problem = Problem.find_by_name(params[:id])
119 if not @problem.available
119 if not @problem.available
120 redirect_to :action => 'list'
120 redirect_to :action => 'list'
121 flash[:notice] = 'Error: submissions for that problem are not viewable.'
121 flash[:notice] = 'Error: submissions for that problem are not viewable.'
122 return
122 return
123 end
123 end
124 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
124 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
125 end
125 end
126 end
126 end
127
127
128 def result
128 def result
129 if !Configuration.show_grading_result
129 if !Configuration.show_grading_result
130 redirect_to :action => 'list' and return
130 redirect_to :action => 'list' and return
131 end
131 end
132 @user = User.find(session[:user_id])
132 @user = User.find(session[:user_id])
133 @submission = Submission.find(params[:id])
133 @submission = Submission.find(params[:id])
134 if @submission.user!=@user
134 if @submission.user!=@user
135 flash[:notice] = 'You are not allowed to view result of other users.'
135 flash[:notice] = 'You are not allowed to view result of other users.'
136 redirect_to :action => 'list' and return
136 redirect_to :action => 'list' and return
137 end
137 end
138 prepare_grading_result(@submission)
138 prepare_grading_result(@submission)
139 end
139 end
140
140
141 def load_output
141 def load_output
142 if !Configuration.show_grading_result or params[:num]==nil
142 if !Configuration.show_grading_result or params[:num]==nil
143 redirect_to :action => 'list' and return
143 redirect_to :action => 'list' and return
144 end
144 end
145 @user = User.find(session[:user_id])
145 @user = User.find(session[:user_id])
146 @submission = Submission.find(params[:id])
146 @submission = Submission.find(params[:id])
147 if @submission.user!=@user
147 if @submission.user!=@user
148 flash[:notice] = 'You are not allowed to view result of other users.'
148 flash[:notice] = 'You are not allowed to view result of other users.'
149 redirect_to :action => 'list' and return
149 redirect_to :action => 'list' and return
150 end
150 end
151 case_num = params[:num].to_i
151 case_num = params[:num].to_i
152 out_filename = output_filename(@user.login,
152 out_filename = output_filename(@user.login,
153 @submission.problem.name,
153 @submission.problem.name,
154 @submission.id,
154 @submission.id,
155 case_num)
155 case_num)
156 if !FileTest.exists?(out_filename)
156 if !FileTest.exists?(out_filename)
157 flash[:notice] = 'Output not found.'
157 flash[:notice] = 'Output not found.'
158 redirect_to :action => 'list' and return
158 redirect_to :action => 'list' and return
159 end
159 end
160
160
161 response.headers['Content-Type'] = "application/force-download"
161 response.headers['Content-Type'] = "application/force-download"
162 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
162 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
163 response.headers["X-Sendfile"] = out_filename
163 response.headers["X-Sendfile"] = out_filename
164 response.headers['Content-length'] = File.size(out_filename)
164 response.headers['Content-length'] = File.size(out_filename)
165 render :nothing => true
165 render :nothing => true
166 end
166 end
167
167
168 def error
168 def error
169 @user = User.find(session[:user_id])
169 @user = User.find(session[:user_id])
170 end
170 end
171
171
172 # announcement refreshing and hiding methods
172 # announcement refreshing and hiding methods
173
173
174 def announcements
174 def announcements
175 if params.has_key? 'recent'
175 if params.has_key? 'recent'
176 prepare_announcements(params[:recent])
176 prepare_announcements(params[:recent])
177 else
177 else
178 prepare_announcements
178 prepare_announcements
179 end
179 end
180 render(:partial => 'announcement',
180 render(:partial => 'announcement',
181 :collection => @announcements,
181 :collection => @announcements,
182 :locals => {:announcement_effect => true})
182 :locals => {:announcement_effect => true})
183 end
183 end
184
184
185 #
185 #
186 # actions for Code Jom
186 # actions for Code Jom
187 #
187 #
188 def download_input
188 def download_input
189 user = User.find(session[:user_id])
189 user = User.find(session[:user_id])
190
190
191 if Configuration.time_limit_mode? and user.contest_finished?
191 if Configuration.time_limit_mode? and user.contest_finished?
192 redirect_to :action => 'list' and return
192 redirect_to :action => 'list' and return
193 end
193 end
194
194
195 problem = Problem.find(params[:id])
195 problem = Problem.find(params[:id])
196 if user.can_request_new_test_pair_for? problem
196 if user.can_request_new_test_pair_for? problem
197 assignment = user.get_new_test_pair_assignment_for problem
197 assignment = user.get_new_test_pair_assignment_for problem
198 assignment.save
198 assignment.save
199
199
200 send_data(assignment.test_pair.input,
200 send_data(assignment.test_pair.input,
201 { :filename => "#{problem.name}-#{assignment.request_number}.in",
201 { :filename => "#{problem.name}-#{assignment.request_number}.in",
202 :type => 'text/plain' })
202 :type => 'text/plain' })
203 else
203 else
204 recent_assignment = user.get_recent_test_pair_assignment_for problem
204 recent_assignment = user.get_recent_test_pair_assignment_for problem
205 send_data(recent_assignment.test_pair.input,
205 send_data(recent_assignment.test_pair.input,
206 { :filename => "#{problem.name}-#{recent_assignment.request_number}.in",
206 { :filename => "#{problem.name}-#{recent_assignment.request_number}.in",
207 :type => 'text/plain' })
207 :type => 'text/plain' })
208 end
208 end
209 end
209 end
210
210
211 def submit_solution
211 def submit_solution
212 problem = Problem.find(params[:id])
212 problem = Problem.find(params[:id])
213 user = User.find(session[:user_id])
213 user = User.find(session[:user_id])
214 recent_assignment = user.get_recent_test_pair_assignment_for problem
214 recent_assignment = user.get_recent_test_pair_assignment_for problem
215
215
216 if Configuration.time_limit_mode? and user.contest_finished?
216 if Configuration.time_limit_mode? and user.contest_finished?
217 redirect_to :action => 'list' and return
217 redirect_to :action => 'list' and return
218 end
218 end
219
219
220 if recent_assignment == nil
220 if recent_assignment == nil
221 flash[:notice] = 'You have not requested for any input data for this problem. Please download an input first.'
221 flash[:notice] = 'You have not requested for any input data for this problem. Please download an input first.'
222 session[:current_problem_id] = problem.id
222 session[:current_problem_id] = problem.id
223 redirect_to :action => 'list' and return
223 redirect_to :action => 'list' and return
224 end
224 end
225
225
226 if recent_assignment.expired?
226 if recent_assignment.expired?
227 flash[:notice] = 'The current input is expired. Please download a new input data.'
227 flash[:notice] = 'The current input is expired. Please download a new input data.'
228 session[:current_problem_id] = problem.id
228 session[:current_problem_id] = problem.id
229 redirect_to :action => 'list' and return
229 redirect_to :action => 'list' and return
230 end
230 end
231
231
232 if recent_assignment.submitted
232 if recent_assignment.submitted
233 flash[:notice] = 'You have already submitted an incorrect solution for this input. Please download a new input data.'
233 flash[:notice] = 'You have already submitted an incorrect solution for this input. Please download a new input data.'
234 session[:current_problem_id] = problem.id
234 session[:current_problem_id] = problem.id
235 redirect_to :action => 'list' and return
235 redirect_to :action => 'list' and return
236 end
236 end
237
237
238 if params[:file] == nil
238 if params[:file] == nil
239 flash[:notice] = 'You have not submitted any output.'
239 flash[:notice] = 'You have not submitted any output.'
240 session[:current_problem_id] = problem.id
240 session[:current_problem_id] = problem.id
241 redirect_to :action => 'list' and return
241 redirect_to :action => 'list' and return
242 end
242 end
243
243
244 submitted_solution = params[:file].read
244 submitted_solution = params[:file].read
245 test_pair = recent_assignment.test_pair
245 test_pair = recent_assignment.test_pair
246 passed = test_pair.grade(submitted_solution)
246 passed = test_pair.grade(submitted_solution)
247 points = passed ? 100 : 0
247 points = passed ? 100 : 0
248 submission = Submission.new(:user => user,
248 submission = Submission.new(:user => user,
249 :problem => problem,
249 :problem => problem,
250 :source => submitted_solution,
250 :source => submitted_solution,
251 :source_filename => params['file'].original_filename,
251 :source_filename => params['file'].original_filename,
252 :language_id => 0,
252 :language_id => 0,
253 :submitted_at => Time.new.gmtime,
253 :submitted_at => Time.new.gmtime,
254 :graded_at => Time.new.gmtime,
254 :graded_at => Time.new.gmtime,
255 :points => points)
255 :points => points)
256 submission.save
256 submission.save
257 recent_assignment.submitted = true
257 recent_assignment.submitted = true
258 recent_assignment.save
258 recent_assignment.save
259
259
260 status = user.get_submission_status_for(problem)
260 status = user.get_submission_status_for(problem)
261 if status == nil
261 if status == nil
262 status = SubmissionStatus.new :user => user, :problem => problem, :submission_count => 0
262 status = SubmissionStatus.new :user => user, :problem => problem, :submission_count => 0
263 end
263 end
264
264
265 status.submission_count += 1
265 status.submission_count += 1
266 status.passed = passed
266 status.passed = passed
267 status.save
267 status.save
268
268
269 if passed
269 if passed
270 flash[:notice] = 'Correct solution.'
270 flash[:notice] = 'Correct solution.'
271 user.update_codejom_status
271 user.update_codejom_status
272 else
272 else
273 session[:current_problem_id] = problem.id
273 session[:current_problem_id] = problem.id
274 flash[:notice] = 'Incorrect solution.'
274 flash[:notice] = 'Incorrect solution.'
275 end
275 end
276 redirect_to :action => 'list'
276 redirect_to :action => 'list'
277 end
277 end
278
278
279 + def problems
280 + prepare_list_information
281 + render :partial => 'problem_title', :collection => @problems, :as => :problem
282 + end
283 +
284 + def splash
285 + render :text => '<div class="notice">Most recent task:</span>'
286 + end
287 +
279 protected
288 protected
280
289
281 def prepare_announcements(recent=nil)
290 def prepare_announcements(recent=nil)
282 if Configuration.show_tasks_to?(@user)
291 if Configuration.show_tasks_to?(@user)
283 @announcements = Announcement.find_published(true)
292 @announcements = Announcement.find_published(true)
284 else
293 else
285 @announcements = Announcement.find_published
294 @announcements = Announcement.find_published
286 end
295 end
287 if recent!=nil
296 if recent!=nil
288 recent_id = recent.to_i
297 recent_id = recent.to_i
289 @announcements = @announcements.find_all { |a| a.id > recent_id }
298 @announcements = @announcements.find_all { |a| a.id > recent_id }
290 end
299 end
291 end
300 end
292
301
293 def prepare_timeout_information(problems)
302 def prepare_timeout_information(problems)
294 @submission_timeouts = {}
303 @submission_timeouts = {}
295 problems.each do |problem|
304 problems.each do |problem|
296 assignment = @user.get_recent_test_pair_assignment_for(problem)
305 assignment = @user.get_recent_test_pair_assignment_for(problem)
297 if assignment == nil
306 if assignment == nil
298 timeout = nil
307 timeout = nil
299 else
308 else
300 if (assignment.expired?) or (assignment.submitted)
309 if (assignment.expired?) or (assignment.submitted)
301 timeout = 0
310 timeout = 0
302 else
311 else
303 timeout = assignment.created_at + TEST_ASSIGNMENT_EXPIRATION_DURATION - Time.new.gmtime
312 timeout = assignment.created_at + TEST_ASSIGNMENT_EXPIRATION_DURATION - Time.new.gmtime
304 end
313 end
305 end
314 end
306 @submission_timeouts[problem.id] = timeout
315 @submission_timeouts[problem.id] = timeout
307 end
316 end
308 @submission_timeouts.each_pair {|k,v| puts "#{k} => #{v}"}
317 @submission_timeouts.each_pair {|k,v| puts "#{k} => #{v}"}
309 end
318 end
310
319
311 def prepare_list_information
320 def prepare_list_information
312 @user = User.find(session[:user_id])
321 @user = User.find(session[:user_id])
313
322
314 all_problems = Problem.find_available_problems
323 all_problems = Problem.find_available_problems
315
324
316 passed = {}
325 passed = {}
317 sub_count = {}
326 sub_count = {}
318 @user.submission_statuses.each do |status|
327 @user.submission_statuses.each do |status|
319 if status.passed
328 if status.passed
320 passed[status.problem_id] = true
329 passed[status.problem_id] = true
321 end
330 end
322 sub_count[status.problem_id] = status.submission_count
331 sub_count[status.problem_id] = status.submission_count
323 end
332 end
324
333
325 if session.has_key? :current_problem_id
334 if session.has_key? :current_problem_id
326 @current_problem_id = session[:current_problem_id]
335 @current_problem_id = session[:current_problem_id]
327 session.delete(:current_problem_id)
336 session.delete(:current_problem_id)
328 else
337 else
329 @current_problem_id = nil
338 @current_problem_id = nil
330 end
339 end
331
340
332 @problems = all_problems.reject { |problem| passed.has_key? problem.id }
341 @problems = all_problems.reject { |problem| passed.has_key? problem.id }
333
342
334 prepare_timeout_information(@problems)
343 prepare_timeout_information(@problems)
335
344
336 @prob_submissions = Array.new
345 @prob_submissions = Array.new
337 @problems.each do |p|
346 @problems.each do |p|
338 if sub_count.has_key? p.id
347 if sub_count.has_key? p.id
339 @prob_submissions << { :count => sub_count[p.id] }
348 @prob_submissions << { :count => sub_count[p.id] }
340 else
349 else
341 @prob_submissions << { :count => 0 }
350 @prob_submissions << { :count => 0 }
342 end
351 end
343 end
352 end
344 prepare_announcements
353 prepare_announcements
345 end
354 end
346
355
347 def check_viewability
356 def check_viewability
348 @user = User.find(session[:user_id])
357 @user = User.find(session[:user_id])
349 if (!Configuration.show_tasks_to?(@user)) and
358 if (!Configuration.show_tasks_to?(@user)) and
350 ((action_name=='submission') or (action_name=='submit'))
359 ((action_name=='submission') or (action_name=='submit'))
351 redirect_to :action => 'list' and return
360 redirect_to :action => 'list' and return
352 end
361 end
353 end
362 end
354
363
355 def prepare_grading_result(submission)
364 def prepare_grading_result(submission)
356 if Configuration.task_grading_info.has_key? submission.problem.name
365 if Configuration.task_grading_info.has_key? submission.problem.name
357 grading_info = Configuration.task_grading_info[submission.problem.name]
366 grading_info = Configuration.task_grading_info[submission.problem.name]
358 else
367 else
359 # guess task info from problem.full_score
368 # guess task info from problem.full_score
360 cases = submission.problem.full_score / 10
369 cases = submission.problem.full_score / 10
361 grading_info = {
370 grading_info = {
362 'testruns' => cases,
371 'testruns' => cases,
363 'testcases' => cases
372 'testcases' => cases
364 }
373 }
365 end
374 end
366 @test_runs = []
375 @test_runs = []
367 if grading_info['testruns'].is_a? Integer
376 if grading_info['testruns'].is_a? Integer
368 trun_count = grading_info['testruns']
377 trun_count = grading_info['testruns']
369 trun_count.times do |i|
378 trun_count.times do |i|
370 @test_runs << [ read_grading_result(@user.login,
379 @test_runs << [ read_grading_result(@user.login,
371 submission.problem.name,
380 submission.problem.name,
372 submission.id,
381 submission.id,
373 i+1) ]
382 i+1) ]
374 end
383 end
375 else
384 else
376 grading_info['testruns'].keys.sort.each do |num|
385 grading_info['testruns'].keys.sort.each do |num|
377 run = []
386 run = []
378 testrun = grading_info['testruns'][num]
387 testrun = grading_info['testruns'][num]
379 testrun.each do |c|
388 testrun.each do |c|
380 run << read_grading_result(@user.login,
389 run << read_grading_result(@user.login,
381 submission.problem.name,
390 submission.problem.name,
382 submission.id,
391 submission.id,
383 c)
392 c)
384 end
393 end
385 @test_runs << run
394 @test_runs << run
386 end
395 end
387 end
396 end
388 end
397 end
389
398
390 def grading_result_dir(user_name, problem_name, submission_id, case_num)
399 def grading_result_dir(user_name, problem_name, submission_id, case_num)
391 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
400 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
392 end
401 end
393
402
394 def output_filename(user_name, problem_name, submission_id, case_num)
403 def output_filename(user_name, problem_name, submission_id, case_num)
395 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
404 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
396 return "#{dir}/output.txt"
405 return "#{dir}/output.txt"
397 end
406 end
398
407
399 def read_grading_result(user_name, problem_name, submission_id, case_num)
408 def read_grading_result(user_name, problem_name, submission_id, case_num)
400 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
409 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
401 result_file_name = "#{dir}/result"
410 result_file_name = "#{dir}/result"
402 if !FileTest.exists?(result_file_name)
411 if !FileTest.exists?(result_file_name)
403 return {:num => case_num, :msg => 'program did not run'}
412 return {:num => case_num, :msg => 'program did not run'}
404 else
413 else
405 results = File.open(result_file_name).readlines
414 results = File.open(result_file_name).readlines
406 run_stat = extract_running_stat(results)
415 run_stat = extract_running_stat(results)
407 output_filename = "#{dir}/output.txt"
416 output_filename = "#{dir}/output.txt"
408 if FileTest.exists?(output_filename)
417 if FileTest.exists?(output_filename)
409 output_file = true
418 output_file = true
410 output_size = File.size(output_filename)
419 output_size = File.size(output_filename)
411 else
420 else
412 output_file = false
421 output_file = false
413 output_size = 0
422 output_size = 0
414 end
423 end
415
424
416 return {
425 return {
417 :num => case_num,
426 :num => case_num,
418 :msg => results[0],
427 :msg => results[0],
419 :run_stat => run_stat,
428 :run_stat => run_stat,
420 :output => output_file,
429 :output => output_file,
421 :output_size => output_size
430 :output_size => output_size
422 }
431 }
423 end
432 end
424 end
433 end
425
434
426 # copied from grader/script/lib/test_request_helper.rb
435 # copied from grader/script/lib/test_request_helper.rb
427 def extract_running_stat(results)
436 def extract_running_stat(results)
428 running_stat_line = results[-1]
437 running_stat_line = results[-1]
429
438
430 # extract exit status line
439 # extract exit status line
431 run_stat = ""
440 run_stat = ""
432 if !(/[Cc]orrect/.match(results[0]))
441 if !(/[Cc]orrect/.match(results[0]))
433 run_stat = results[0].chomp
442 run_stat = results[0].chomp
434 else
443 else
435 run_stat = 'Program exited normally'
444 run_stat = 'Program exited normally'
436 end
445 end
437
446
438 logger.info "Stat line: #{running_stat_line}"
447 logger.info "Stat line: #{running_stat_line}"
439
448
440 # extract running time
449 # extract running time
441 if res = /r(.*)u(.*)s/.match(running_stat_line)
450 if res = /r(.*)u(.*)s/.match(running_stat_line)
442 seconds = (res[1].to_f + res[2].to_f)
451 seconds = (res[1].to_f + res[2].to_f)
443 time_stat = "Time used: #{seconds} sec."
452 time_stat = "Time used: #{seconds} sec."
444 else
453 else
445 seconds = nil
454 seconds = nil
446 time_stat = "Time used: n/a sec."
455 time_stat = "Time used: n/a sec."
447 end
456 end
448
457
449 # extract memory usage
458 # extract memory usage
450 if res = /s(.*)m/.match(running_stat_line)
459 if res = /s(.*)m/.match(running_stat_line)
451 memory_used = res[1].to_i
460 memory_used = res[1].to_i
452 else
461 else
453 memory_used = -1
462 memory_used = -1
454 end
463 end
455
464
456 return {
465 return {
457 :msg => "#{run_stat}\n#{time_stat}",
466 :msg => "#{run_stat}\n#{time_stat}",
458 :running_time => seconds,
467 :running_time => seconds,
459 :exit_status => run_stat,
468 :exit_status => run_stat,
460 :memory_usage => memory_used
469 :memory_usage => memory_used
461 }
470 }
462 end
471 end
463
472
464 def update_user_start_time
473 def update_user_start_time
465 user = User.find(session[:user_id])
474 user = User.find(session[:user_id])
466 UserContestStat.update_user_start_time(user)
475 UserContestStat.update_user_start_time(user)
467 end
476 end
468
477
469 def reject_announcement_refresh_when_logged_out
478 def reject_announcement_refresh_when_logged_out
470 if not session[:user_id]
479 if not session[:user_id]
471 render :text => 'Access forbidden', :status => 403
480 render :text => 'Access forbidden', :status => 403
472 end
481 end
473 end
482 end
474
483
475 end
484 end
476
485
@@ -1,39 +1,42
1 - content_for :head do
1 - content_for :head do
2 = javascript_include_tag :defaults
2 = javascript_include_tag :defaults
3 = javascript_include_tag 'announcement_refresh.js'
3 = javascript_include_tag 'announcement_refresh.js'
4 = javascript_include_tag 'codejom_timeout.js'
4 = javascript_include_tag 'codejom_timeout.js'
5
5
6 = user_title_bar(@user)
6 = user_title_bar(@user)
7
7
8 .announcementbox{:style => (@announcements.length==0 ? "display:none" : "")}
8 .announcementbox{:style => (@announcements.length==0 ? "display:none" : "")}
9 %span{:class => 'title'}
9 %span{:class => 'title'}
10 Announcements
10 Announcements
11 #announcementbox-body
11 #announcementbox-body
12 = render :partial => 'announcement', :collection => @announcements
12 = render :partial => 'announcement', :collection => @announcements
13
13
14 %hr/
14 %hr/
15
15
16 - if (Configuration.contest_mode?) and (@user.site!=nil) and (@user.site.started!=true)
16 - if (Configuration.contest_mode?) and (@user.site!=nil) and (@user.site.started!=true)
17 %p=t 'main.start_soon'
17 %p=t 'main.start_soon'
18
18
19 - if Configuration.show_tasks_to?(@user)
19 - if Configuration.show_tasks_to?(@user)
20 - .problem-list
20 + .problem-list{:id => 'problem-list'}
21 = render :partial => 'problem_title', :collection => @problems, :as => :problem
21 = render :partial => 'problem_title', :collection => @problems, :as => :problem
22 .problem-content
22 .problem-content
23 %span{:id => "problem-panel-filler", :style => (@current_problem_id!=nil) ? "display:none" : ""}
23 %span{:id => "problem-panel-filler", :style => (@current_problem_id!=nil) ? "display:none" : ""}
24 %h2
24 %h2
25 Welcome to Code Jom
25 Welcome to Code Jom
26 %br/
26 %br/
27 Choose problems from the list on the right.
27 Choose problems from the list on the right.
28 = render :partial => 'problem', :collection => @problems
28 = render :partial => 'problem', :collection => @problems
29
29
30 %br{:clear=>'both'}/
30 %br{:clear=>'both'}/
31 %hr/
31 %hr/
32
32
33 %script{:type => 'text/javascript'}
33 %script{:type => 'text/javascript'}
34 = "Announcement.refreshUrl = '#{url_for :controller => 'main', :action => 'announcements'}';"
34 = "Announcement.refreshUrl = '#{url_for :controller => 'main', :action => 'announcements'}';"
35 Announcement.registerRefreshEventTimer();
35 Announcement.registerRefreshEventTimer();
36 = render :partial => 'submission_timeouts'
36 = render :partial => 'submission_timeouts'
37 CodejomTimeout.updateProblemMessages();
37 CodejomTimeout.updateProblemMessages();
38 CodejomTimeout.registerRefreshEvent();
38 CodejomTimeout.registerRefreshEvent();
39
39
40 + = periodically_call_remote(:url => { :action => 'problems' }, :update => 'problem-list')
41 +
42 +
@@ -1,338 +1,338
1 body
1 body
2 background: white url(../images/topbg.jpg) repeat-x top center
2 background: white url(../images/topbg.jpg) repeat-x top center
3 font-size: 13px
3 font-size: 13px
4 font-family: Tahoma, "sans-serif"
4 font-family: Tahoma, "sans-serif"
5 margin: 10px
5 margin: 10px
6 padding: 10px
6 padding: 10px
7
7
8
8
9 input
9 input
10 font-family: Tahoma, "sans-serif"
10 font-family: Tahoma, "sans-serif"
11
11
12
12
13 h1
13 h1
14 font-size: 24px
14 font-size: 24px
15 color: #334488
15 color: #334488
16 line-height: 2em
16 line-height: 2em
17
17
18
18
19 h2
19 h2
20 font-size: 18px
20 font-size: 18px
21 color: #5566bb
21 color: #5566bb
22 line-height: 1.5em
22 line-height: 1.5em
23
23
24
24
25 hr
25 hr
26 border-top: 1px solid #dddddd
26 border-top: 1px solid #dddddd
27 border-bottom: 1px solid #eeeeee
27 border-bottom: 1px solid #eeeeee
28
28
29
29
30 a
30 a
31 color: #6666cc
31 color: #6666cc
32 text-decoration: none
32 text-decoration: none
33
33
34 &:link, &:visited
34 &:link, &:visited
35 color: #6666cc
35 color: #6666cc
36 text-decoration: none
36 text-decoration: none
37
37
38 &:hover, &:focus
38 &:hover, &:focus
39 color: #111166
39 color: #111166
40 text-decoration: none
40 text-decoration: none
41
41
42
42
43 .userbar
43 .userbar
44 line-height: 1.5em
44 line-height: 1.5em
45 text-align: right
45 text-align: right
46 font-size: 12px
46 font-size: 12px
47
47
48 .title
48 .title
49 padding: 10px 0px
49 padding: 10px 0px
50 line-height: 1.5em
50 line-height: 1.5em
51 font-size: 13px
51 font-size: 13px
52
52
53 span.contest-over-msg
53 span.contest-over-msg
54 font-size: 15px
54 font-size: 15px
55 color: red
55 color: red
56
56
57 table
57 table
58 width: 100%
58 width: 100%
59 font-weight: bold
59 font-weight: bold
60
60
61 td
61 td
62 &.left-col
62 &.left-col
63 text-align: left
63 text-align: left
64 vertical-align: top
64 vertical-align: top
65 color: #444444
65 color: #444444
66
66
67 &.right-col
67 &.right-col
68 text-align: right
68 text-align: right
69 vertical-align: top
69 vertical-align: top
70 font-size: 18px
70 font-size: 18px
71 color: #116699
71 color: #116699
72
72
73
73
74 table.info
74 table.info
75 margin: 10px 0
75 margin: 10px 0
76 border: 1px solid #666666
76 border: 1px solid #666666
77 border-collapse: collapse
77 border-collapse: collapse
78 font-size: 12px
78 font-size: 12px
79
79
80 th
80 th
81 border: 1px solid #666666
81 border: 1px solid #666666
82 line-height: 1.5em
82 line-height: 1.5em
83 padding: 0 0.5em
83 padding: 0 0.5em
84
84
85 td
85 td
86 border-left: 1px solid #666666
86 border-left: 1px solid #666666
87 border-right: 1px solid #666666
87 border-right: 1px solid #666666
88 line-height: 1.5em
88 line-height: 1.5em
89 padding: 0 0.5em
89 padding: 0 0.5em
90
90
91
91
92 tr.info-head
92 tr.info-head
93 background: #777777
93 background: #777777
94 color: white
94 color: white
95
95
96 tr.info-odd
96 tr.info-odd
97 background: #eeeeee
97 background: #eeeeee
98
98
99 tr.info-even
99 tr.info-even
100 background: #f9f9f9
100 background: #f9f9f9
101
101
102
102
103 .submitbox
103 .submitbox
104 background: #eeeeff
104 background: #eeeeff
105 border: 1px dotted #99aaee
105 border: 1px dotted #99aaee
106 padding: 5px
106 padding: 5px
107 margin: 10px 0px
107 margin: 10px 0px
108 color: black
108 color: black
109 font-size: 13px
109 font-size: 13px
110
110
111 .errorExplanation
111 .errorExplanation
112 border: 1px dotted gray
112 border: 1px dotted gray
113 color: #bb2222
113 color: #bb2222
114 padding: 5px 15px 5px 15px
114 padding: 5px 15px 5px 15px
115 margin-bottom: 5px
115 margin-bottom: 5px
116 background-color: white
116 background-color: white
117 font-weight: normal
117 font-weight: normal
118
118
119 h2
119 h2
120 color: #cc1111
120 color: #cc1111
121 font-weight: bold
121 font-weight: bold
122
122
123
123
124 table.uinfo
124 table.uinfo
125 border-collapse: collapse
125 border-collapse: collapse
126 border: 1px solid black
126 border: 1px solid black
127 font-size: 13px
127 font-size: 13px
128
128
129
129
130 td.uinfo
130 td.uinfo
131 vertical-align: top
131 vertical-align: top
132 border: 1px solid black
132 border: 1px solid black
133 padding: 5px
133 padding: 5px
134
134
135
135
136 th.uinfo
136 th.uinfo
137 background: lightgreen
137 background: lightgreen
138 vertical-align: top
138 vertical-align: top
139 text-align: right
139 text-align: right
140 border: 1px solid black
140 border: 1px solid black
141 padding: 5px
141 padding: 5px
142
142
143
143
144 .compilermsgbody
144 .compilermsgbody
145 font-family: monospace
145 font-family: monospace
146
146
147 .task-menu
147 .task-menu
148 text-align: center
148 text-align: center
149 font-size: 13px
149 font-size: 13px
150 line-height: 1.75em
150 line-height: 1.75em
151 font-weight: bold
151 font-weight: bold
152 border-top: 1px dashed gray
152 border-top: 1px dashed gray
153 border-bottom: 1px dashed gray
153 border-bottom: 1px dashed gray
154 margin-top: 2px
154 margin-top: 2px
155 margin-bottom: 4px
155 margin-bottom: 4px
156
156
157
157
158 table.taskdesc
158 table.taskdesc
159 border: 2px solid #dddddd
159 border: 2px solid #dddddd
160 border-collapse: collapse
160 border-collapse: collapse
161 margin: 10px auto
161 margin: 10px auto
162 width: 90%
162 width: 90%
163 font-size: 13px
163 font-size: 13px
164
164
165 p
165 p
166 font-size: 13px
166 font-size: 13px
167
167
168 tr.name
168 tr.name
169 border: 2px solid #dddddd
169 border: 2px solid #dddddd
170 background: #dddddd
170 background: #dddddd
171 color: #333333
171 color: #333333
172 font-weight: bold
172 font-weight: bold
173 font-size: 14px
173 font-size: 14px
174 line-height: 1.5em
174 line-height: 1.5em
175 text-align: center
175 text-align: center
176
176
177 td
177 td
178 &.desc-odd
178 &.desc-odd
179 padding: 5px
179 padding: 5px
180 padding-left: 20px
180 padding-left: 20px
181 background: #fefeee
181 background: #fefeee
182
182
183 &.desc-even
183 &.desc-even
184 padding: 5px
184 padding: 5px
185 padding-left: 20px
185 padding-left: 20px
186 background: #feeefe
186 background: #feeefe
187
187
188
188
189 .announcementbox
189 .announcementbox
190 margin: 10px 0px
190 margin: 10px 0px
191 background: #bbddee
191 background: #bbddee
192 padding: 1px
192 padding: 1px
193
193
194 span.title
194 span.title
195 font-weight: bold
195 font-weight: bold
196 color: #224455
196 color: #224455
197 padding-left: 10px
197 padding-left: 10px
198 line-height: 1.6em
198 line-height: 1.6em
199
199
200 .announcement
200 .announcement
201 margin: 2px
201 margin: 2px
202 background: white
202 background: white
203 padding: 1px
203 padding: 1px
204 padding-left: 10px
204 padding-left: 10px
205 padding-right: 10px
205 padding-right: 10px
206 padding-top: 5px
206 padding-top: 5px
207 padding-bottom: 5px
207 padding-bottom: 5px
208
208
209 p
209 p
210 font-size: 12px
210 font-size: 12px
211 margin: 2px
211 margin: 2px
212
212
213
213
214 .pub-info
214 .pub-info
215 text-align: right
215 text-align: right
216 font-style: italic
216 font-style: italic
217 font-size: 9px
217 font-size: 9px
218
218
219 p
219 p
220 text-align: right
220 text-align: right
221 font-style: italic
221 font-style: italic
222 font-size: 9px
222 font-size: 9px
223
223
224
224
225 .announcement
225 .announcement
226 .toggles
226 .toggles
227 font-weight: normal
227 font-weight: normal
228 float: right
228 float: right
229 font-size: 80%
229 font-size: 80%
230
230
231 .announcement-title
231 .announcement-title
232 font-weight: bold
232 font-weight: bold
233
233
234
234
235 .message
235 .message
236 margin: 10px 0 0
236 margin: 10px 0 0
237
237
238 .message
238 .message
239 margin: 0 0 0 30px
239 margin: 0 0 0 30px
240
240
241 .stat
241 .stat
242 font-size: 10px
242 font-size: 10px
243 line-height: 1.75em
243 line-height: 1.75em
244 padding: 0 5px
244 padding: 0 5px
245 color: #444444
245 color: #444444
246 background: #bbbbbb
246 background: #bbbbbb
247 font-weight: bold
247 font-weight: bold
248
248
249 .body
249 .body
250 border: 2px solid #dddddd
250 border: 2px solid #dddddd
251 background: #fff8f8
251 background: #fff8f8
252 padding-left: 5px
252 padding-left: 5px
253
253
254 .reply-body
254 .reply-body
255 border: 2px solid #bbbbbb
255 border: 2px solid #bbbbbb
256 background: #fffff8
256 background: #fffff8
257 padding-left: 5px
257 padding-left: 5px
258
258
259 .stat
259 .stat
260 font-size: 10px
260 font-size: 10px
261 line-height: 1.75em
261 line-height: 1.75em
262 padding: 0 5px
262 padding: 0 5px
263 color: #333333
263 color: #333333
264 background: #dddddd
264 background: #dddddd
265 font-weight: bold
265 font-weight: bold
266
266
267 .contest-title
267 .contest-title
268 color: white
268 color: white
269 text-align: center
269 text-align: center
270 line-height: 2em
270 line-height: 2em
271
271
272 .registration-desc
272 .registration-desc
273 border: 1px dotted gray
273 border: 1px dotted gray
274 background: #f5f5f5
274 background: #f5f5f5
275 padding: 5px
275 padding: 5px
276 margin: 10px 0
276 margin: 10px 0
277 font-size: 12px
277 font-size: 12px
278 line-height: 1.5em
278 line-height: 1.5em
279
279
280 .test-desc
280 .test-desc
281 border: 1px dotted gray
281 border: 1px dotted gray
282 background: #f5f5f5
282 background: #f5f5f5
283 padding: 5px
283 padding: 5px
284 margin: 10px 0
284 margin: 10px 0
285 font-size: 12px
285 font-size: 12px
286 line-height: 1.5em
286 line-height: 1.5em
287
287
288 .problem-list
288 .problem-list
289 width: 200px
289 width: 200px
290 float: left
290 float: left
291
291
292 .problem-bar
292 .problem-bar
293 margin-top: 5px
293 margin-top: 5px
294 padding: 5px
294 padding: 5px
295 background: #e0e0e0
295 background: #e0e0e0
296
296
297 span.problem-title
297 span.problem-title
298 font-weight: bold
298 font-weight: bold
299 font-size: 110%
299 font-size: 110%
300
300
301 .problem-content
301 .problem-content
302 float: left
302 float: left
303 margin-left: 10px
303 margin-left: 10px
304 width: 700px
304 width: 700px
305
305
306 .problem-panel
306 .problem-panel
307 border: 1px black solid
307 border: 1px black solid
308 padding: 5px
308 padding: 5px
309
309
310 .problem-form
310 .problem-form
311 border: 1px dotted #99aaee
311 border: 1px dotted #99aaee
312 background: #eeeeff
312 background: #eeeeff
313
313
314 .notice-bar
314 .notice-bar
315 margin-top: 3px
315 margin-top: 3px
316 margin-bottom: 3px
316 margin-bottom: 3px
317 text-align: center
317 text-align: center
318
318
319 span.notice
319 span.notice
320 color: white
320 color: white
321 font-weight: bold
321 font-weight: bold
322 background: #000070
322 background: #000070
323 padding: 3px 20px 3px 20px
323 padding: 3px 20px 3px 20px
324 -moz-border-radius: 2px
324 -moz-border-radius: 2px
325 -webkit-border-radius: 5px
325 -webkit-border-radius: 5px
326 border-radius: 5px
326 border-radius: 5px
327
327
328 table.codejom-problems
328 table.codejom-problems
329 th
329 th
330 background: #000070
330 background: #000070
331 color: white
331 color: white
332 td
332 td
333 width: 200px
333 width: 200px
334 vertical-align: top
334 vertical-align: top
335 text-align: center
335 text-align: center
336
336
337 &.random-button
337 &.random-button
338 - background: lightgrey No newline at end of file
338 + background: lightgrey
You need to be logged in to leave comments. Login now