Description:
add ip to submission
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r446:d9ae0ff1e3ea - - 5 files changed: 31 inserted, 12 deleted

@@ -0,0 +1,5
1 + class AddIpToSubmissions < ActiveRecord::Migration
2 + def change
3 + add_column :submissions, :ip_address, :string
4 + end
5 + end
@@ -1,381 +1,382
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 GraderConfiguration['system.single_user_mode'] and
41 # if GraderConfiguration['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
61 @submission = Submission.new
62 @submission.problem_id = params[:submission][:problem_id]
62 @submission.problem_id = params[:submission][:problem_id]
63 @submission.user = user
63 @submission.user = user
64 @submission.language_id = 0
64 @submission.language_id = 0
65 if (params['file']) and (params['file']!='')
65 if (params['file']) and (params['file']!='')
66 @submission.source = params['file'].read
66 @submission.source = params['file'].read
67 @submission.source_filename = params['file'].original_filename
67 @submission.source_filename = params['file'].original_filename
68 end
68 end
69 @submission.submitted_at = Time.new.gmtime
69 @submission.submitted_at = Time.new.gmtime
70 + @submission.ip_address = request.remote_ip
70
71
71 if GraderConfiguration.time_limit_mode? and user.contest_finished?
72 if GraderConfiguration.time_limit_mode? and user.contest_finished?
72 @submission.errors.add_to_base "The contest is over."
73 @submission.errors.add_to_base "The contest is over."
73 prepare_list_information
74 prepare_list_information
74 render :action => 'list' and return
75 render :action => 'list' and return
75 end
76 end
76
77
77 if @submission.valid?
78 if @submission.valid?
78 if @submission.save == false
79 if @submission.save == false
79 flash[:notice] = 'Error saving your submission'
80 flash[:notice] = 'Error saving your submission'
80 elsif Task.create(:submission_id => @submission.id,
81 elsif Task.create(:submission_id => @submission.id,
81 :status => Task::STATUS_INQUEUE) == false
82 :status => Task::STATUS_INQUEUE) == false
82 flash[:notice] = 'Error adding your submission to task queue'
83 flash[:notice] = 'Error adding your submission to task queue'
83 end
84 end
84 else
85 else
85 prepare_list_information
86 prepare_list_information
86 render :action => 'list' and return
87 render :action => 'list' and return
87 end
88 end
88 redirect_to :action => 'list'
89 redirect_to :action => 'list'
89 end
90 end
90
91
91 def source
92 def source
92 submission = Submission.find(params[:id])
93 submission = Submission.find(params[:id])
93 if ((submission.user_id == session[:user_id]) and
94 if ((submission.user_id == session[:user_id]) and
94 (submission.problem != nil) and
95 (submission.problem != nil) and
95 (submission.problem.available))
96 (submission.problem.available))
96 send_data(submission.source,
97 send_data(submission.source,
97 {:filename => submission.download_filename,
98 {:filename => submission.download_filename,
98 :type => 'text/plain'})
99 :type => 'text/plain'})
99 else
100 else
100 flash[:notice] = 'Error viewing source'
101 flash[:notice] = 'Error viewing source'
101 redirect_to :action => 'list'
102 redirect_to :action => 'list'
102 end
103 end
103 end
104 end
104
105
105 def compiler_msg
106 def compiler_msg
106 @submission = Submission.find(params[:id])
107 @submission = Submission.find(params[:id])
107 if @submission.user_id == session[:user_id]
108 if @submission.user_id == session[:user_id]
108 render :action => 'compiler_msg', :layout => 'empty'
109 render :action => 'compiler_msg', :layout => 'empty'
109 else
110 else
110 flash[:notice] = 'Error viewing source'
111 flash[:notice] = 'Error viewing source'
111 redirect_to :action => 'list'
112 redirect_to :action => 'list'
112 end
113 end
113 end
114 end
114
115
115 def submission
116 def submission
116 @user = User.find(session[:user_id])
117 @user = User.find(session[:user_id])
117 @problems = @user.available_problems
118 @problems = @user.available_problems
118 if params[:id]==nil
119 if params[:id]==nil
119 @problem = nil
120 @problem = nil
120 @submissions = nil
121 @submissions = nil
121 else
122 else
122 @problem = Problem.find_by_name(params[:id])
123 @problem = Problem.find_by_name(params[:id])
123 if not @problem.available
124 if not @problem.available
124 redirect_to :action => 'list'
125 redirect_to :action => 'list'
125 flash[:notice] = 'Error: submissions for that problem are not viewable.'
126 flash[:notice] = 'Error: submissions for that problem are not viewable.'
126 return
127 return
127 end
128 end
128 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
129 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
129 end
130 end
130 end
131 end
131
132
132 def result
133 def result
133 if !GraderConfiguration.show_grading_result
134 if !GraderConfiguration.show_grading_result
134 redirect_to :action => 'list' and return
135 redirect_to :action => 'list' and return
135 end
136 end
136 @user = User.find(session[:user_id])
137 @user = User.find(session[:user_id])
137 @submission = Submission.find(params[:id])
138 @submission = Submission.find(params[:id])
138 if @submission.user!=@user
139 if @submission.user!=@user
139 flash[:notice] = 'You are not allowed to view result of other users.'
140 flash[:notice] = 'You are not allowed to view result of other users.'
140 redirect_to :action => 'list' and return
141 redirect_to :action => 'list' and return
141 end
142 end
142 prepare_grading_result(@submission)
143 prepare_grading_result(@submission)
143 end
144 end
144
145
145 def load_output
146 def load_output
146 if !GraderConfiguration.show_grading_result or params[:num]==nil
147 if !GraderConfiguration.show_grading_result or params[:num]==nil
147 redirect_to :action => 'list' and return
148 redirect_to :action => 'list' and return
148 end
149 end
149 @user = User.find(session[:user_id])
150 @user = User.find(session[:user_id])
150 @submission = Submission.find(params[:id])
151 @submission = Submission.find(params[:id])
151 if @submission.user!=@user
152 if @submission.user!=@user
152 flash[:notice] = 'You are not allowed to view result of other users.'
153 flash[:notice] = 'You are not allowed to view result of other users.'
153 redirect_to :action => 'list' and return
154 redirect_to :action => 'list' and return
154 end
155 end
155 case_num = params[:num].to_i
156 case_num = params[:num].to_i
156 out_filename = output_filename(@user.login,
157 out_filename = output_filename(@user.login,
157 @submission.problem.name,
158 @submission.problem.name,
158 @submission.id,
159 @submission.id,
159 case_num)
160 case_num)
160 if !FileTest.exists?(out_filename)
161 if !FileTest.exists?(out_filename)
161 flash[:notice] = 'Output not found.'
162 flash[:notice] = 'Output not found.'
162 redirect_to :action => 'list' and return
163 redirect_to :action => 'list' and return
163 end
164 end
164
165
165 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
166 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
166 response.headers['Content-Type'] = "application/force-download"
167 response.headers['Content-Type'] = "application/force-download"
167 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
168 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
168 response.headers["X-Sendfile"] = out_filename
169 response.headers["X-Sendfile"] = out_filename
169 response.headers['Content-length'] = File.size(out_filename)
170 response.headers['Content-length'] = File.size(out_filename)
170 render :nothing => true
171 render :nothing => true
171 else
172 else
172 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
173 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
173 end
174 end
174 end
175 end
175
176
176 def error
177 def error
177 @user = User.find(session[:user_id])
178 @user = User.find(session[:user_id])
178 end
179 end
179
180
180 # announcement refreshing and hiding methods
181 # announcement refreshing and hiding methods
181
182
182 def announcements
183 def announcements
183 if params.has_key? 'recent'
184 if params.has_key? 'recent'
184 prepare_announcements(params[:recent])
185 prepare_announcements(params[:recent])
185 else
186 else
186 prepare_announcements
187 prepare_announcements
187 end
188 end
188 render(:partial => 'announcement',
189 render(:partial => 'announcement',
189 :collection => @announcements,
190 :collection => @announcements,
190 :locals => {:announcement_effect => true})
191 :locals => {:announcement_effect => true})
191 end
192 end
192
193
193 def confirm_contest_start
194 def confirm_contest_start
194 user = User.find(session[:user_id])
195 user = User.find(session[:user_id])
195 if request.method == :post
196 if request.method == :post
196 user.update_start_time
197 user.update_start_time
197 redirect_to :action => 'list'
198 redirect_to :action => 'list'
198 else
199 else
199 @contests = user.contests
200 @contests = user.contests
200 @user = user
201 @user = user
201 end
202 end
202 end
203 end
203
204
204 protected
205 protected
205
206
206 def prepare_announcements(recent=nil)
207 def prepare_announcements(recent=nil)
207 if GraderConfiguration.show_tasks_to?(@user)
208 if GraderConfiguration.show_tasks_to?(@user)
208 @announcements = Announcement.find_published(true)
209 @announcements = Announcement.find_published(true)
209 else
210 else
210 @announcements = Announcement.find_published
211 @announcements = Announcement.find_published
211 end
212 end
212 if recent!=nil
213 if recent!=nil
213 recent_id = recent.to_i
214 recent_id = recent.to_i
214 @announcements = @announcements.find_all { |a| a.id > recent_id }
215 @announcements = @announcements.find_all { |a| a.id > recent_id }
215 end
216 end
216 end
217 end
217
218
218 def prepare_list_information
219 def prepare_list_information
219 @user = User.find(session[:user_id])
220 @user = User.find(session[:user_id])
220 if not GraderConfiguration.multicontests?
221 if not GraderConfiguration.multicontests?
221 @problems = @user.available_problems
222 @problems = @user.available_problems
222 else
223 else
223 @contest_problems = @user.available_problems_group_by_contests
224 @contest_problems = @user.available_problems_group_by_contests
224 @problems = @user.available_problems
225 @problems = @user.available_problems
225 end
226 end
226 @prob_submissions = {}
227 @prob_submissions = {}
227 @problems.each do |p|
228 @problems.each do |p|
228 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
229 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
229 if sub!=nil
230 if sub!=nil
230 @prob_submissions[p.id] = { :count => sub.number, :submission => sub }
231 @prob_submissions[p.id] = { :count => sub.number, :submission => sub }
231 else
232 else
232 @prob_submissions[p.id] = { :count => 0, :submission => nil }
233 @prob_submissions[p.id] = { :count => 0, :submission => nil }
233 end
234 end
234 end
235 end
235 prepare_announcements
236 prepare_announcements
236 end
237 end
237
238
238 def check_viewability
239 def check_viewability
239 @user = User.find(session[:user_id])
240 @user = User.find(session[:user_id])
240 if (!GraderConfiguration.show_tasks_to?(@user)) and
241 if (!GraderConfiguration.show_tasks_to?(@user)) and
241 ((action_name=='submission') or (action_name=='submit'))
242 ((action_name=='submission') or (action_name=='submit'))
242 redirect_to :action => 'list' and return
243 redirect_to :action => 'list' and return
243 end
244 end
244 end
245 end
245
246
246 def prepare_grading_result(submission)
247 def prepare_grading_result(submission)
247 if GraderConfiguration.task_grading_info.has_key? submission.problem.name
248 if GraderConfiguration.task_grading_info.has_key? submission.problem.name
248 grading_info = GraderConfiguration.task_grading_info[submission.problem.name]
249 grading_info = GraderConfiguration.task_grading_info[submission.problem.name]
249 else
250 else
250 # guess task info from problem.full_score
251 # guess task info from problem.full_score
251 cases = submission.problem.full_score / 10
252 cases = submission.problem.full_score / 10
252 grading_info = {
253 grading_info = {
253 'testruns' => cases,
254 'testruns' => cases,
254 'testcases' => cases
255 'testcases' => cases
255 }
256 }
256 end
257 end
257 @test_runs = []
258 @test_runs = []
258 if grading_info['testruns'].is_a? Integer
259 if grading_info['testruns'].is_a? Integer
259 trun_count = grading_info['testruns']
260 trun_count = grading_info['testruns']
260 trun_count.times do |i|
261 trun_count.times do |i|
261 @test_runs << [ read_grading_result(@user.login,
262 @test_runs << [ read_grading_result(@user.login,
262 submission.problem.name,
263 submission.problem.name,
263 submission.id,
264 submission.id,
264 i+1) ]
265 i+1) ]
265 end
266 end
266 else
267 else
267 grading_info['testruns'].keys.sort.each do |num|
268 grading_info['testruns'].keys.sort.each do |num|
268 run = []
269 run = []
269 testrun = grading_info['testruns'][num]
270 testrun = grading_info['testruns'][num]
270 testrun.each do |c|
271 testrun.each do |c|
271 run << read_grading_result(@user.login,
272 run << read_grading_result(@user.login,
272 submission.problem.name,
273 submission.problem.name,
273 submission.id,
274 submission.id,
274 c)
275 c)
275 end
276 end
276 @test_runs << run
277 @test_runs << run
277 end
278 end
278 end
279 end
279 end
280 end
280
281
281 def grading_result_dir(user_name, problem_name, submission_id, case_num)
282 def grading_result_dir(user_name, problem_name, submission_id, case_num)
282 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
283 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
283 end
284 end
284
285
285 def output_filename(user_name, problem_name, submission_id, case_num)
286 def output_filename(user_name, problem_name, submission_id, case_num)
286 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
287 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
287 return "#{dir}/output.txt"
288 return "#{dir}/output.txt"
288 end
289 end
289
290
290 def read_grading_result(user_name, problem_name, submission_id, case_num)
291 def read_grading_result(user_name, problem_name, submission_id, case_num)
291 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
292 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
292 result_file_name = "#{dir}/result"
293 result_file_name = "#{dir}/result"
293 if !FileTest.exists?(result_file_name)
294 if !FileTest.exists?(result_file_name)
294 return {:num => case_num, :msg => 'program did not run'}
295 return {:num => case_num, :msg => 'program did not run'}
295 else
296 else
296 results = File.open(result_file_name).readlines
297 results = File.open(result_file_name).readlines
297 run_stat = extract_running_stat(results)
298 run_stat = extract_running_stat(results)
298 output_filename = "#{dir}/output.txt"
299 output_filename = "#{dir}/output.txt"
299 if FileTest.exists?(output_filename)
300 if FileTest.exists?(output_filename)
300 output_file = true
301 output_file = true
301 output_size = File.size(output_filename)
302 output_size = File.size(output_filename)
302 else
303 else
303 output_file = false
304 output_file = false
304 output_size = 0
305 output_size = 0
305 end
306 end
306
307
307 return {
308 return {
308 :num => case_num,
309 :num => case_num,
309 :msg => results[0],
310 :msg => results[0],
310 :run_stat => run_stat,
311 :run_stat => run_stat,
311 :output => output_file,
312 :output => output_file,
312 :output_size => output_size
313 :output_size => output_size
313 }
314 }
314 end
315 end
315 end
316 end
316
317
317 # copied from grader/script/lib/test_request_helper.rb
318 # copied from grader/script/lib/test_request_helper.rb
318 def extract_running_stat(results)
319 def extract_running_stat(results)
319 running_stat_line = results[-1]
320 running_stat_line = results[-1]
320
321
321 # extract exit status line
322 # extract exit status line
322 run_stat = ""
323 run_stat = ""
323 if !(/[Cc]orrect/.match(results[0]))
324 if !(/[Cc]orrect/.match(results[0]))
324 run_stat = results[0].chomp
325 run_stat = results[0].chomp
325 else
326 else
326 run_stat = 'Program exited normally'
327 run_stat = 'Program exited normally'
327 end
328 end
328
329
329 logger.info "Stat line: #{running_stat_line}"
330 logger.info "Stat line: #{running_stat_line}"
330
331
331 # extract running time
332 # extract running time
332 if res = /r(.*)u(.*)s/.match(running_stat_line)
333 if res = /r(.*)u(.*)s/.match(running_stat_line)
333 seconds = (res[1].to_f + res[2].to_f)
334 seconds = (res[1].to_f + res[2].to_f)
334 time_stat = "Time used: #{seconds} sec."
335 time_stat = "Time used: #{seconds} sec."
335 else
336 else
336 seconds = nil
337 seconds = nil
337 time_stat = "Time used: n/a sec."
338 time_stat = "Time used: n/a sec."
338 end
339 end
339
340
340 # extract memory usage
341 # extract memory usage
341 if res = /s(.*)m/.match(running_stat_line)
342 if res = /s(.*)m/.match(running_stat_line)
342 memory_used = res[1].to_i
343 memory_used = res[1].to_i
343 else
344 else
344 memory_used = -1
345 memory_used = -1
345 end
346 end
346
347
347 return {
348 return {
348 :msg => "#{run_stat}\n#{time_stat}",
349 :msg => "#{run_stat}\n#{time_stat}",
349 :running_time => seconds,
350 :running_time => seconds,
350 :exit_status => run_stat,
351 :exit_status => run_stat,
351 :memory_usage => memory_used
352 :memory_usage => memory_used
352 }
353 }
353 end
354 end
354
355
355 def confirm_and_update_start_time
356 def confirm_and_update_start_time
356 user = User.find(session[:user_id])
357 user = User.find(session[:user_id])
357 if (GraderConfiguration.indv_contest_mode? and
358 if (GraderConfiguration.indv_contest_mode? and
358 GraderConfiguration['contest.confirm_indv_contest_start'] and
359 GraderConfiguration['contest.confirm_indv_contest_start'] and
359 !user.contest_started?)
360 !user.contest_started?)
360 redirect_to :action => 'confirm_contest_start' and return
361 redirect_to :action => 'confirm_contest_start' and return
361 end
362 end
362 if not GraderConfiguration.analysis_mode?
363 if not GraderConfiguration.analysis_mode?
363 user.update_start_time
364 user.update_start_time
364 end
365 end
365 end
366 end
366
367
367 def reject_announcement_refresh_when_logged_out
368 def reject_announcement_refresh_when_logged_out
368 if not session[:user_id]
369 if not session[:user_id]
369 render :text => 'Access forbidden', :status => 403
370 render :text => 'Access forbidden', :status => 403
370 end
371 end
371
372
372 if GraderConfiguration.multicontests?
373 if GraderConfiguration.multicontests?
373 user = User.find(session[:user_id])
374 user = User.find(session[:user_id])
374 if user.contest_stat.forced_logout
375 if user.contest_stat.forced_logout
375 render :text => 'Access forbidden', :status => 403
376 render :text => 'Access forbidden', :status => 403
376 end
377 end
377 end
378 end
378 end
379 end
379
380
380 end
381 end
381
382
@@ -1,57 +1,61
1 %style{type: "text/css"}
1 %style{type: "text/css"}
2 = @css_style
2 = @css_style
3 :css
3 :css
4 .field {
4 .field {
5 font-weight: bold;
5 font-weight: bold;
6 text-align: right;
6 text-align: right;
7 padding: 3px;
7 padding: 3px;
8 }
8 }
9
9
10
10
11 %h1= "Submission: #{@submission.id}"
11 %h1= "Submission: #{@submission.id}"
12
12
13
13
14 %h2 Stat
14 %h2 Stat
15
15
16 %table.info
16 %table.info
17 %thead
17 %thead
18 %tr.info-head
18 %tr.info-head
19 %th Field
19 %th Field
20 %th Value
20 %th Value
21 %tbody
21 %tbody
22 %tr{class: cycle('info-even','info-odd')}
22 %tr{class: cycle('info-even','info-odd')}
23 %td.field User:
23 %td.field User:
24 %td.value= "(#{@submission.user.login}) #{@submission.user.full_name}"
24 %td.value= "(#{@submission.user.login}) #{@submission.user.full_name}"
25 %tr{class: cycle('info-even','info-odd')}
25 %tr{class: cycle('info-even','info-odd')}
26 %td.field Problem:
26 %td.field Problem:
27 %td.value
27 %td.value
28 - if @submission.problem!=nil
28 - if @submission.problem!=nil
29 = "(#{@submission.problem.name}) #{@submission.problem.full_name}"
29 = "(#{@submission.problem.name}) #{@submission.problem.full_name}"
30 - else
30 - else
31 = "(n/a)"
31 = "(n/a)"
32 %tr{class: cycle('info-even','info-odd')}
32 %tr{class: cycle('info-even','info-odd')}
33 %td.field Tries:
33 %td.field Tries:
34 %td.value= @submission.number
34 %td.value= @submission.number
35 %tr{class: cycle('info-even','info-odd')}
35 %tr{class: cycle('info-even','info-odd')}
36 %td.field Submitted:
36 %td.field Submitted:
37 %td.value #{time_ago_in_words(@submission.submitted_at)} ago (at #{@submission.submitted_at.to_formatted_s(:long)})
37 %td.value #{time_ago_in_words(@submission.submitted_at)} ago (at #{@submission.submitted_at.to_formatted_s(:long)})
38 %tr{class: cycle('info-even','info-odd')}
38 %tr{class: cycle('info-even','info-odd')}
39 %td.field Graded:
39 %td.field Graded:
40 %td.value #{time_ago_in_words(@submission.graded_at)} ago (at #{@submission.graded_at.to_formatted_s(:long)})
40 %td.value #{time_ago_in_words(@submission.graded_at)} ago (at #{@submission.graded_at.to_formatted_s(:long)})
41 %tr{class: cycle('info-even','info-odd')}
41 %tr{class: cycle('info-even','info-odd')}
42 %td.field Points:
42 %td.field Points:
43 %td.value #{@submission.points}/#{@submission.problem.full_score}
43 %td.value #{@submission.points}/#{@submission.problem.full_score}
44 %tr{class: cycle('info-even','info-odd')}
44 %tr{class: cycle('info-even','info-odd')}
45 %td.field Comment:
45 %td.field Comment:
46 %td.value #{@submission.grader_comment}
46 %td.value #{@submission.grader_comment}
47 %tr{class: cycle('info-even','info-odd')}
47 %tr{class: cycle('info-even','info-odd')}
48 %td.field Runtime (s):
48 %td.field Runtime (s):
49 %td.value #{@submission.max_runtime}
49 %td.value #{@submission.max_runtime}
50 %tr{class: cycle('info-even','info-odd')}
50 %tr{class: cycle('info-even','info-odd')}
51 %td.field Memory (kb):
51 %td.field Memory (kb):
52 %td.value #{@submission.peak_memory}
52 %td.value #{@submission.peak_memory}
53 + - if session[:admin]
54 + %tr{class: cycle('info-even','info-odd')}
55 + %td.field IP:
56 + %td.value #{@submission.ip_address}
53
57
54 %h2 Source code
58 %h2 Source code
55 //%div.highlight{:style => "border: 1px solid black;"}
59 //%div.highlight{:style => "border: 1px solid black;"}
56 =@formatted_code.html_safe
60 =@formatted_code.html_safe
57
61
@@ -1,46 +1,50
1 - content_for :header do
1 - content_for :header do
2 = javascript_include_tag 'new'
2 = javascript_include_tag 'new'
3
3
4 %script{:type=>"text/javascript"}
4 %script{:type=>"text/javascript"}
5 $(function () {
5 $(function () {
6 $('#submission_table').tablesorter({widgets: ['zebra','filter']});
6 $('#submission_table').tablesorter({widgets: ['zebra','filter']});
7 });
7 });
8
8
9 :css
9 :css
10 .fix-width {
10 .fix-width {
11 font-family: Droid Sans Mono,Consolas, monospace, mono, Courier New, Courier;
11 font-family: Droid Sans Mono,Consolas, monospace, mono, Courier New, Courier;
12 }
12 }
13
13
14 %h1= @user.full_name + ' Profile'
14 %h1= @user.full_name + ' Profile'
15
15
16 %h2 Basic info
16 %h2 Basic info
17 <b>Login:</b> #{@user.login} <br/>
17 <b>Login:</b> #{@user.login} <br/>
18 <b>Full name:</b> #{@user.full_name} <br />
18 <b>Full name:</b> #{@user.full_name} <br />
19
19
20
20
21 %h2 Problem Stat
21 %h2 Problem Stat
22
22
23 %h2 Submissions
23 %h2 Submissions
24
24
25 %table.tablesorter-cafe#submission_table
25 %table.tablesorter-cafe#submission_table
26 %thead
26 %thead
27 %tr
27 %tr
28 %th ID
28 %th ID
29 %th Problem code
29 %th Problem code
30 %th Problem name
30 %th Problem name
31 %th Language
31 %th Language
32 %th Result
32 %th Result
33 %th Score
33 %th Score
34 + - if session[:admin]
35 + %th IP
34 %tbody
36 %tbody
35 - @submission.each do |s|
37 - @submission.each do |s|
36 - next unless s.problem
38 - next unless s.problem
37 %tr
39 %tr
38 %td= link_to "#{s.id}", controller: "graders", action: "submission", id: s.id
40 %td= link_to "#{s.id}", controller: "graders", action: "submission", id: s.id
39 %td= s.problem.name
41 %td= s.problem.name
40 %td= s.problem.full_name
42 %td= s.problem.full_name
41 %td= s.language.pretty_name
43 %td= s.language.pretty_name
42 %td.fix-width= s.grader_comment
44 %td.fix-width= s.grader_comment
43 %td= (s.points*100)/s.problem.full_score
45 %td= (s.points*100)/s.problem.full_score
46 + - if session[:admin]
47 + %td= s.ip_address
44
48
45
49
46
50
@@ -1,242 +1,247
1 # encoding: UTF-8
1 # encoding: UTF-8
2 # This file is auto-generated from the current state of the database. Instead
2 # This file is auto-generated from the current state of the database. Instead
3 # of editing this file, please use the migrations feature of Active Record to
3 # of editing this file, please use the migrations feature of Active Record to
4 # incrementally modify your database, and then regenerate this schema definition.
4 # incrementally modify your database, and then regenerate this schema definition.
5 #
5 #
6 # Note that this schema.rb definition is the authoritative source for your
6 # Note that this schema.rb definition is the authoritative source for your
7 # database schema. If you need to create the application database on another
7 # database schema. If you need to create the application database on another
8 # system, you should be using db:schema:load, not running all the migrations
8 # system, you should be using db:schema:load, not running all the migrations
9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10 # you'll amass, the slower it'll run and the greater likelihood for issues).
10 # you'll amass, the slower it'll run and the greater likelihood for issues).
11 #
11 #
12 # It's strongly recommended to check this file into your version control system.
12 # It's strongly recommended to check this file into your version control system.
13
13
14 - ActiveRecord::Schema.define(:version => 20140826095949) do
14 + ActiveRecord::Schema.define(:version => 20140917150629) do
15
15
16 create_table "announcements", :force => true do |t|
16 create_table "announcements", :force => true do |t|
17 t.string "author"
17 t.string "author"
18 - t.text "body", :limit => 16777215
18 + t.text "body"
19 t.boolean "published"
19 t.boolean "published"
20 t.datetime "created_at", :null => false
20 t.datetime "created_at", :null => false
21 t.datetime "updated_at", :null => false
21 t.datetime "updated_at", :null => false
22 t.boolean "frontpage", :default => false
22 t.boolean "frontpage", :default => false
23 t.boolean "contest_only", :default => false
23 t.boolean "contest_only", :default => false
24 t.string "title"
24 t.string "title"
25 t.string "notes"
25 t.string "notes"
26 end
26 end
27
27
28 create_table "contests", :force => true do |t|
28 create_table "contests", :force => true do |t|
29 t.string "title"
29 t.string "title"
30 t.boolean "enabled"
30 t.boolean "enabled"
31 t.datetime "created_at", :null => false
31 t.datetime "created_at", :null => false
32 t.datetime "updated_at", :null => false
32 t.datetime "updated_at", :null => false
33 t.string "name"
33 t.string "name"
34 end
34 end
35
35
36 create_table "contests_problems", :id => false, :force => true do |t|
36 create_table "contests_problems", :id => false, :force => true do |t|
37 t.integer "contest_id"
37 t.integer "contest_id"
38 t.integer "problem_id"
38 t.integer "problem_id"
39 end
39 end
40
40
41 create_table "contests_users", :id => false, :force => true do |t|
41 create_table "contests_users", :id => false, :force => true do |t|
42 t.integer "contest_id"
42 t.integer "contest_id"
43 t.integer "user_id"
43 t.integer "user_id"
44 end
44 end
45
45
46 create_table "countries", :force => true do |t|
46 create_table "countries", :force => true do |t|
47 t.string "name"
47 t.string "name"
48 t.datetime "created_at", :null => false
48 t.datetime "created_at", :null => false
49 t.datetime "updated_at", :null => false
49 t.datetime "updated_at", :null => false
50 end
50 end
51
51
52 create_table "descriptions", :force => true do |t|
52 create_table "descriptions", :force => true do |t|
53 - t.text "body", :limit => 16777215
53 + t.text "body"
54 t.boolean "markdowned"
54 t.boolean "markdowned"
55 t.datetime "created_at", :null => false
55 t.datetime "created_at", :null => false
56 t.datetime "updated_at", :null => false
56 t.datetime "updated_at", :null => false
57 end
57 end
58
58
59 create_table "grader_configurations", :force => true do |t|
59 create_table "grader_configurations", :force => true do |t|
60 t.string "key"
60 t.string "key"
61 t.string "value_type"
61 t.string "value_type"
62 t.string "value"
62 t.string "value"
63 t.datetime "created_at", :null => false
63 t.datetime "created_at", :null => false
64 t.datetime "updated_at", :null => false
64 t.datetime "updated_at", :null => false
65 - t.text "description", :limit => 16777215
65 + t.text "description"
66 end
66 end
67
67
68 create_table "grader_processes", :force => true do |t|
68 create_table "grader_processes", :force => true do |t|
69 t.string "host", :limit => 20
69 t.string "host", :limit => 20
70 t.integer "pid"
70 t.integer "pid"
71 t.string "mode"
71 t.string "mode"
72 t.boolean "active"
72 t.boolean "active"
73 t.datetime "created_at", :null => false
73 t.datetime "created_at", :null => false
74 t.datetime "updated_at", :null => false
74 t.datetime "updated_at", :null => false
75 t.integer "task_id"
75 t.integer "task_id"
76 t.string "task_type"
76 t.string "task_type"
77 t.boolean "terminated"
77 t.boolean "terminated"
78 end
78 end
79
79
80 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
80 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
81
81
82 create_table "languages", :force => true do |t|
82 create_table "languages", :force => true do |t|
83 t.string "name", :limit => 10
83 t.string "name", :limit => 10
84 t.string "pretty_name"
84 t.string "pretty_name"
85 t.string "ext", :limit => 10
85 t.string "ext", :limit => 10
86 t.string "common_ext"
86 t.string "common_ext"
87 end
87 end
88
88
89 create_table "logins", :force => true do |t|
89 create_table "logins", :force => true do |t|
90 t.string "user_id"
90 t.string "user_id"
91 t.string "ip_address"
91 t.string "ip_address"
92 t.datetime "created_at", :null => false
92 t.datetime "created_at", :null => false
93 t.datetime "updated_at", :null => false
93 t.datetime "updated_at", :null => false
94 end
94 end
95
95
96 create_table "messages", :force => true do |t|
96 create_table "messages", :force => true do |t|
97 t.integer "sender_id"
97 t.integer "sender_id"
98 t.integer "receiver_id"
98 t.integer "receiver_id"
99 t.integer "replying_message_id"
99 t.integer "replying_message_id"
100 - t.text "body", :limit => 16777215
100 + t.text "body"
101 t.boolean "replied"
101 t.boolean "replied"
102 t.datetime "created_at", :null => false
102 t.datetime "created_at", :null => false
103 t.datetime "updated_at", :null => false
103 t.datetime "updated_at", :null => false
104 end
104 end
105
105
106 create_table "problems", :force => true do |t|
106 create_table "problems", :force => true do |t|
107 t.string "name", :limit => 30
107 t.string "name", :limit => 30
108 t.string "full_name"
108 t.string "full_name"
109 t.integer "full_score"
109 t.integer "full_score"
110 t.date "date_added"
110 t.date "date_added"
111 t.boolean "available"
111 t.boolean "available"
112 t.string "url"
112 t.string "url"
113 t.integer "description_id"
113 t.integer "description_id"
114 t.boolean "test_allowed"
114 t.boolean "test_allowed"
115 t.boolean "output_only"
115 t.boolean "output_only"
116 t.string "description_filename"
116 t.string "description_filename"
117 end
117 end
118
118
119 create_table "rights", :force => true do |t|
119 create_table "rights", :force => true do |t|
120 t.string "name"
120 t.string "name"
121 t.string "controller"
121 t.string "controller"
122 t.string "action"
122 t.string "action"
123 end
123 end
124
124
125 create_table "rights_roles", :id => false, :force => true do |t|
125 create_table "rights_roles", :id => false, :force => true do |t|
126 t.integer "right_id"
126 t.integer "right_id"
127 t.integer "role_id"
127 t.integer "role_id"
128 end
128 end
129
129
130 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
130 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
131
131
132 create_table "roles", :force => true do |t|
132 create_table "roles", :force => true do |t|
133 t.string "name"
133 t.string "name"
134 end
134 end
135
135
136 create_table "roles_users", :id => false, :force => true do |t|
136 create_table "roles_users", :id => false, :force => true do |t|
137 t.integer "role_id"
137 t.integer "role_id"
138 t.integer "user_id"
138 t.integer "user_id"
139 end
139 end
140
140
141 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
141 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
142
142
143 create_table "sessions", :force => true do |t|
143 create_table "sessions", :force => true do |t|
144 t.string "session_id"
144 t.string "session_id"
145 - t.text "data", :limit => 16777215
145 + t.text "data"
146 t.datetime "updated_at"
146 t.datetime "updated_at"
147 end
147 end
148
148
149 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
149 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
150 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
150 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
151
151
152 create_table "sites", :force => true do |t|
152 create_table "sites", :force => true do |t|
153 t.string "name"
153 t.string "name"
154 t.boolean "started"
154 t.boolean "started"
155 t.datetime "start_time"
155 t.datetime "start_time"
156 t.datetime "created_at", :null => false
156 t.datetime "created_at", :null => false
157 t.datetime "updated_at", :null => false
157 t.datetime "updated_at", :null => false
158 t.integer "country_id"
158 t.integer "country_id"
159 t.string "password"
159 t.string "password"
160 end
160 end
161
161
162 create_table "submissions", :force => true do |t|
162 create_table "submissions", :force => true do |t|
163 t.integer "user_id"
163 t.integer "user_id"
164 t.integer "problem_id"
164 t.integer "problem_id"
165 t.integer "language_id"
165 t.integer "language_id"
166 - t.text "source", :limit => 16777215
166 + t.text "source"
167 t.binary "binary"
167 t.binary "binary"
168 t.datetime "submitted_at"
168 t.datetime "submitted_at"
169 t.datetime "compiled_at"
169 t.datetime "compiled_at"
170 - t.text "compiler_message", :limit => 16777215
170 + t.text "compiler_message"
171 t.datetime "graded_at"
171 t.datetime "graded_at"
172 t.integer "points"
172 t.integer "points"
173 - t.text "grader_comment", :limit => 16777215
173 + t.text "grader_comment"
174 t.integer "number"
174 t.integer "number"
175 t.string "source_filename"
175 t.string "source_filename"
176 + t.float "max_runtime"
177 + t.integer "peak_memory"
178 + t.integer "effective_code_length"
179 + t.string "ip_address"
176 end
180 end
177
181
178 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
182 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
179 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
183 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
180
184
181 create_table "tasks", :force => true do |t|
185 create_table "tasks", :force => true do |t|
182 t.integer "submission_id"
186 t.integer "submission_id"
183 t.datetime "created_at"
187 t.datetime "created_at"
184 t.integer "status"
188 t.integer "status"
185 t.datetime "updated_at"
189 t.datetime "updated_at"
186 end
190 end
187
191
188 create_table "test_pairs", :force => true do |t|
192 create_table "test_pairs", :force => true do |t|
189 t.integer "problem_id"
193 t.integer "problem_id"
190 - t.text "input", :limit => 2147483647
194 + t.text "input", :limit => 16777215
191 - t.text "solution", :limit => 2147483647
195 + t.text "solution", :limit => 16777215
192 t.datetime "created_at", :null => false
196 t.datetime "created_at", :null => false
193 t.datetime "updated_at", :null => false
197 t.datetime "updated_at", :null => false
194 end
198 end
195
199
196 create_table "test_requests", :force => true do |t|
200 create_table "test_requests", :force => true do |t|
197 t.integer "user_id"
201 t.integer "user_id"
198 t.integer "problem_id"
202 t.integer "problem_id"
199 t.integer "submission_id"
203 t.integer "submission_id"
200 t.string "input_file_name"
204 t.string "input_file_name"
201 t.string "output_file_name"
205 t.string "output_file_name"
202 t.string "running_stat"
206 t.string "running_stat"
203 t.integer "status"
207 t.integer "status"
204 t.datetime "updated_at", :null => false
208 t.datetime "updated_at", :null => false
205 t.datetime "submitted_at"
209 t.datetime "submitted_at"
206 t.datetime "compiled_at"
210 t.datetime "compiled_at"
207 - t.text "compiler_message", :limit => 16777215
211 + t.text "compiler_message"
208 t.datetime "graded_at"
212 t.datetime "graded_at"
209 t.string "grader_comment"
213 t.string "grader_comment"
210 t.datetime "created_at", :null => false
214 t.datetime "created_at", :null => false
211 t.float "running_time"
215 t.float "running_time"
212 t.string "exit_status"
216 t.string "exit_status"
213 t.integer "memory_usage"
217 t.integer "memory_usage"
214 end
218 end
215
219
216 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
220 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
217
221
218 create_table "user_contest_stats", :force => true do |t|
222 create_table "user_contest_stats", :force => true do |t|
219 t.integer "user_id"
223 t.integer "user_id"
220 t.datetime "started_at"
224 t.datetime "started_at"
221 t.datetime "created_at", :null => false
225 t.datetime "created_at", :null => false
222 t.datetime "updated_at", :null => false
226 t.datetime "updated_at", :null => false
223 t.boolean "forced_logout"
227 t.boolean "forced_logout"
224 end
228 end
225
229
226 create_table "users", :force => true do |t|
230 create_table "users", :force => true do |t|
227 t.string "login", :limit => 50
231 t.string "login", :limit => 50
228 t.string "full_name"
232 t.string "full_name"
229 t.string "hashed_password"
233 t.string "hashed_password"
230 t.string "salt", :limit => 5
234 t.string "salt", :limit => 5
231 t.string "alias"
235 t.string "alias"
232 t.string "email"
236 t.string "email"
233 t.integer "site_id"
237 t.integer "site_id"
234 t.integer "country_id"
238 t.integer "country_id"
235 t.boolean "activated", :default => false
239 t.boolean "activated", :default => false
236 t.datetime "created_at"
240 t.datetime "created_at"
237 t.datetime "updated_at"
241 t.datetime "updated_at"
242 + t.string "section"
238 end
243 end
239
244
240 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
245 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
241
246
242 end
247 end
You need to be logged in to leave comments. Login now