Description:
fixed error when submitted file is nil git-svn-id: http://theory.cpe.ku.ac.th/grader/web/trunk@366 6386c4cd-e34a-4fa8-8920-d93eb39b512e
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r169:6eb47384a88d - - 1 file changed: 1 inserted, 1 deleted

@@ -1,295 +1,295
1 class MainController < ApplicationController
1 class MainController < ApplicationController
2
2
3 SYSTEM_MODE_CONF_KEY = 'system.mode'
3 SYSTEM_MODE_CONF_KEY = 'system.mode'
4
4
5 before_filter :authenticate, :except => [:index, :login]
5 before_filter :authenticate, :except => [:index, :login]
6 before_filter :check_viewability, :except => [:index, :login]
6 before_filter :check_viewability, :except => [:index, :login]
7
7
8 # COMMENTED OUT: filter in each action instead
8 # COMMENTED OUT: filter in each action instead
9 # before_filter :verify_time_limit, :only => [:submit]
9 # before_filter :verify_time_limit, :only => [:submit]
10
10
11 verify :method => :post, :only => [:submit],
11 verify :method => :post, :only => [:submit],
12 :redirect_to => { :action => :index }
12 :redirect_to => { :action => :index }
13
13
14 # COMMENT OUT: only need when having high load
14 # COMMENT OUT: only need when having high load
15 # caches_action :index, :login
15 # caches_action :index, :login
16
16
17 # NOTE: This method is not actually needed, 'config/routes.rb' has
17 # NOTE: This method is not actually needed, 'config/routes.rb' has
18 # assigned action login as a default action.
18 # assigned action login as a default action.
19 def index
19 def index
20 redirect_to :action => 'login'
20 redirect_to :action => 'login'
21 end
21 end
22
22
23 def login
23 def login
24 saved_notice = flash[:notice]
24 saved_notice = flash[:notice]
25 reset_session
25 reset_session
26 flash[:notice] = saved_notice
26 flash[:notice] = saved_notice
27
27
28 # EXPERIMENT:
28 # EXPERIMENT:
29 # Hide login if in single user mode and the url does not
29 # Hide login if in single user mode and the url does not
30 # explicitly specify /login
30 # explicitly specify /login
31 #
31 #
32 # logger.info "PATH: #{request.path}"
32 # logger.info "PATH: #{request.path}"
33 # if Configuration['system.single_user_mode'] and
33 # if Configuration['system.single_user_mode'] and
34 # request.path!='/main/login'
34 # request.path!='/main/login'
35 # @hidelogin = true
35 # @hidelogin = true
36 # end
36 # end
37
37
38 @announcements = Announcement.find_for_frontpage
38 @announcements = Announcement.find_for_frontpage
39 render :action => 'login', :layout => 'empty'
39 render :action => 'login', :layout => 'empty'
40 end
40 end
41
41
42 def list
42 def list
43 prepare_list_information
43 prepare_list_information
44 end
44 end
45
45
46 def help
46 def help
47 @user = User.find(session[:user_id])
47 @user = User.find(session[:user_id])
48 end
48 end
49
49
50 def submit
50 def submit
51 user = User.find(session[:user_id])
51 user = User.find(session[:user_id])
52
52
53 @submission = Submission.new(params[:submission])
53 @submission = Submission.new(params[:submission])
54 @submission.user = user
54 @submission.user = user
55 @submission.language_id = 0
55 @submission.language_id = 0
56 - if params['file']!=''
56 + if (params['file']) and (params['file']!='')
57 @submission.source = params['file'].read
57 @submission.source = params['file'].read
58 @submission.source_filename = params['file'].original_filename
58 @submission.source_filename = params['file'].original_filename
59 end
59 end
60 @submission.submitted_at = Time.new.gmtime
60 @submission.submitted_at = Time.new.gmtime
61
61
62 if Configuration[SYSTEM_MODE_CONF_KEY]=='contest' and
62 if Configuration[SYSTEM_MODE_CONF_KEY]=='contest' and
63 user.site!=nil and user.site.finished?
63 user.site!=nil and user.site.finished?
64 @submission.errors.add_to_base "The contest is over."
64 @submission.errors.add_to_base "The contest is over."
65 prepare_list_information
65 prepare_list_information
66 render :action => 'list' and return
66 render :action => 'list' and return
67 end
67 end
68
68
69 if @submission.valid?
69 if @submission.valid?
70 if @submission.save == false
70 if @submission.save == false
71 flash[:notice] = 'Error saving your submission'
71 flash[:notice] = 'Error saving your submission'
72 elsif Task.create(:submission_id => @submission.id,
72 elsif Task.create(:submission_id => @submission.id,
73 :status => Task::STATUS_INQUEUE) == false
73 :status => Task::STATUS_INQUEUE) == false
74 flash[:notice] = 'Error adding your submission to task queue'
74 flash[:notice] = 'Error adding your submission to task queue'
75 end
75 end
76 else
76 else
77 prepare_list_information
77 prepare_list_information
78 render :action => 'list' and return
78 render :action => 'list' and return
79 end
79 end
80 redirect_to :action => 'list'
80 redirect_to :action => 'list'
81 end
81 end
82
82
83 def source
83 def source
84 submission = Submission.find(params[:id])
84 submission = Submission.find(params[:id])
85 if submission.user_id == session[:user_id]
85 if submission.user_id == session[:user_id]
86 send_data(submission.source,
86 send_data(submission.source,
87 {:filename => submission.download_filename,
87 {:filename => submission.download_filename,
88 :type => 'text/plain'})
88 :type => 'text/plain'})
89 else
89 else
90 flash[:notice] = 'Error viewing source'
90 flash[:notice] = 'Error viewing source'
91 redirect_to :action => 'list'
91 redirect_to :action => 'list'
92 end
92 end
93 end
93 end
94
94
95 def compiler_msg
95 def compiler_msg
96 @submission = Submission.find(params[:id])
96 @submission = Submission.find(params[:id])
97 if @submission.user_id == session[:user_id]
97 if @submission.user_id == session[:user_id]
98 render :action => 'compiler_msg', :layout => 'empty'
98 render :action => 'compiler_msg', :layout => 'empty'
99 else
99 else
100 flash[:notice] = 'Error viewing source'
100 flash[:notice] = 'Error viewing source'
101 redirect_to :action => 'list'
101 redirect_to :action => 'list'
102 end
102 end
103 end
103 end
104
104
105 def submission
105 def submission
106 @user = User.find(session[:user_id])
106 @user = User.find(session[:user_id])
107 @problems = Problem.find_available_problems
107 @problems = Problem.find_available_problems
108 if params[:id]==nil
108 if params[:id]==nil
109 @problem = nil
109 @problem = nil
110 @submissions = nil
110 @submissions = nil
111 else
111 else
112 @problem = Problem.find_by_name(params[:id])
112 @problem = Problem.find_by_name(params[:id])
113 if not @problem.available
113 if not @problem.available
114 redirect_to :action => 'list'
114 redirect_to :action => 'list'
115 flash[:notice] = 'Error: submissions for that problem are not viewable.'
115 flash[:notice] = 'Error: submissions for that problem are not viewable.'
116 return
116 return
117 end
117 end
118 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
118 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
119 end
119 end
120 end
120 end
121
121
122 def result
122 def result
123 if !Configuration.show_grading_result
123 if !Configuration.show_grading_result
124 redirect_to :action => 'list' and return
124 redirect_to :action => 'list' and return
125 end
125 end
126 @user = User.find(session[:user_id])
126 @user = User.find(session[:user_id])
127 @submission = Submission.find(params[:id])
127 @submission = Submission.find(params[:id])
128 if @submission.user!=@user
128 if @submission.user!=@user
129 flash[:notice] = 'You are not allowed to view result of other users.'
129 flash[:notice] = 'You are not allowed to view result of other users.'
130 redirect_to :action => 'list' and return
130 redirect_to :action => 'list' and return
131 end
131 end
132 prepare_grading_result(@submission)
132 prepare_grading_result(@submission)
133 end
133 end
134
134
135 def load_output
135 def load_output
136 if !Configuration.show_grading_result or params[:num]==nil
136 if !Configuration.show_grading_result or params[:num]==nil
137 redirect_to :action => 'list' and return
137 redirect_to :action => 'list' and return
138 end
138 end
139 @user = User.find(session[:user_id])
139 @user = User.find(session[:user_id])
140 @submission = Submission.find(params[:id])
140 @submission = Submission.find(params[:id])
141 if @submission.user!=@user
141 if @submission.user!=@user
142 flash[:notice] = 'You are not allowed to view result of other users.'
142 flash[:notice] = 'You are not allowed to view result of other users.'
143 redirect_to :action => 'list' and return
143 redirect_to :action => 'list' and return
144 end
144 end
145 case_num = params[:num].to_i
145 case_num = params[:num].to_i
146 out_filename = output_filename(@user.login,
146 out_filename = output_filename(@user.login,
147 @submission.problem.name,
147 @submission.problem.name,
148 @submission.id,
148 @submission.id,
149 case_num)
149 case_num)
150 if !FileTest.exists?(out_filename)
150 if !FileTest.exists?(out_filename)
151 flash[:notice] = 'Output not found.'
151 flash[:notice] = 'Output not found.'
152 redirect_to :action => 'list' and return
152 redirect_to :action => 'list' and return
153 end
153 end
154
154
155 response.headers['Content-Type'] = "application/force-download"
155 response.headers['Content-Type'] = "application/force-download"
156 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
156 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
157 response.headers["X-Sendfile"] = out_filename
157 response.headers["X-Sendfile"] = out_filename
158 response.headers['Content-length'] = File.size(out_filename)
158 response.headers['Content-length'] = File.size(out_filename)
159 render :nothing => true
159 render :nothing => true
160 end
160 end
161
161
162 def error
162 def error
163 @user = User.find(session[:user_id])
163 @user = User.find(session[:user_id])
164 end
164 end
165
165
166 protected
166 protected
167 def prepare_list_information
167 def prepare_list_information
168 @problems = Problem.find_available_problems
168 @problems = Problem.find_available_problems
169 @prob_submissions = Array.new
169 @prob_submissions = Array.new
170 @user = User.find(session[:user_id])
170 @user = User.find(session[:user_id])
171 @problems.each do |p|
171 @problems.each do |p|
172 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
172 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
173 if sub!=nil
173 if sub!=nil
174 @prob_submissions << { :count => sub.number, :submission => sub }
174 @prob_submissions << { :count => sub.number, :submission => sub }
175 else
175 else
176 @prob_submissions << { :count => 0, :submission => nil }
176 @prob_submissions << { :count => 0, :submission => nil }
177 end
177 end
178 end
178 end
179 if Configuration.show_tasks_to?(@user)
179 if Configuration.show_tasks_to?(@user)
180 @announcements = Announcement.find_published(true)
180 @announcements = Announcement.find_published(true)
181 else
181 else
182 @announcements = Announcement.find_published
182 @announcements = Announcement.find_published
183 end
183 end
184 end
184 end
185
185
186 def check_viewability
186 def check_viewability
187 @user = User.find(session[:user_id])
187 @user = User.find(session[:user_id])
188 if (!Configuration.show_tasks_to?(@user)) and
188 if (!Configuration.show_tasks_to?(@user)) and
189 ((action_name=='submission') or (action_name=='submit'))
189 ((action_name=='submission') or (action_name=='submit'))
190 redirect_to :action => 'list' and return
190 redirect_to :action => 'list' and return
191 end
191 end
192 end
192 end
193
193
194 def prepare_grading_result(submission)
194 def prepare_grading_result(submission)
195 grading_info = Configuration.task_grading_info[submission.problem.name]
195 grading_info = Configuration.task_grading_info[submission.problem.name]
196 @test_runs = []
196 @test_runs = []
197 if grading_info['testruns'].is_a? Integer
197 if grading_info['testruns'].is_a? Integer
198 trun_count = grading_info['testruns']
198 trun_count = grading_info['testruns']
199 trun_count.times do |i|
199 trun_count.times do |i|
200 @test_runs << [ read_grading_result(@user.login,
200 @test_runs << [ read_grading_result(@user.login,
201 submission.problem.name,
201 submission.problem.name,
202 submission.id,
202 submission.id,
203 i+1) ]
203 i+1) ]
204 end
204 end
205 else
205 else
206 grading_info['testruns'].keys.sort.each do |num|
206 grading_info['testruns'].keys.sort.each do |num|
207 run = []
207 run = []
208 testrun = grading_info['testruns'][num]
208 testrun = grading_info['testruns'][num]
209 testrun.each do |c|
209 testrun.each do |c|
210 run << read_grading_result(@user.login,
210 run << read_grading_result(@user.login,
211 submission.problem.name,
211 submission.problem.name,
212 submission.id,
212 submission.id,
213 c)
213 c)
214 end
214 end
215 @test_runs << run
215 @test_runs << run
216 end
216 end
217 end
217 end
218 end
218 end
219
219
220 def grading_result_dir(user_name, problem_name, submission_id, case_num)
220 def grading_result_dir(user_name, problem_name, submission_id, case_num)
221 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
221 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
222 end
222 end
223
223
224 def output_filename(user_name, problem_name, submission_id, case_num)
224 def output_filename(user_name, problem_name, submission_id, case_num)
225 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
225 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
226 return "#{dir}/output.txt"
226 return "#{dir}/output.txt"
227 end
227 end
228
228
229 def read_grading_result(user_name, problem_name, submission_id, case_num)
229 def read_grading_result(user_name, problem_name, submission_id, case_num)
230 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
230 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
231 result_file_name = "#{dir}/result"
231 result_file_name = "#{dir}/result"
232 if !FileTest.exists?(result_file_name)
232 if !FileTest.exists?(result_file_name)
233 return {:num => case_num, :msg => 'program did not run'}
233 return {:num => case_num, :msg => 'program did not run'}
234 else
234 else
235 results = File.open(result_file_name).readlines
235 results = File.open(result_file_name).readlines
236 run_stat = extract_running_stat(results)
236 run_stat = extract_running_stat(results)
237 output_filename = "#{dir}/output.txt"
237 output_filename = "#{dir}/output.txt"
238 if FileTest.exists?(output_filename)
238 if FileTest.exists?(output_filename)
239 output_file = true
239 output_file = true
240 output_size = File.size(output_filename)
240 output_size = File.size(output_filename)
241 else
241 else
242 output_file = false
242 output_file = false
243 output_size = 0
243 output_size = 0
244 end
244 end
245
245
246 return {
246 return {
247 :num => case_num,
247 :num => case_num,
248 :msg => results[0],
248 :msg => results[0],
249 :run_stat => run_stat,
249 :run_stat => run_stat,
250 :output => output_file,
250 :output => output_file,
251 :output_size => output_size
251 :output_size => output_size
252 }
252 }
253 end
253 end
254 end
254 end
255
255
256 # copied from grader/script/lib/test_request_helper.rb
256 # copied from grader/script/lib/test_request_helper.rb
257 def extract_running_stat(results)
257 def extract_running_stat(results)
258 running_stat_line = results[-1]
258 running_stat_line = results[-1]
259
259
260 # extract exit status line
260 # extract exit status line
261 run_stat = ""
261 run_stat = ""
262 if !(/[Cc]orrect/.match(results[0]))
262 if !(/[Cc]orrect/.match(results[0]))
263 run_stat = results[0].chomp
263 run_stat = results[0].chomp
264 else
264 else
265 run_stat = 'Program exited normally'
265 run_stat = 'Program exited normally'
266 end
266 end
267
267
268 logger.info "Stat line: #{running_stat_line}"
268 logger.info "Stat line: #{running_stat_line}"
269
269
270 # extract running time
270 # extract running time
271 if res = /r(.*)u(.*)s/.match(running_stat_line)
271 if res = /r(.*)u(.*)s/.match(running_stat_line)
272 seconds = (res[1].to_f + res[2].to_f)
272 seconds = (res[1].to_f + res[2].to_f)
273 time_stat = "Time used: #{seconds} sec."
273 time_stat = "Time used: #{seconds} sec."
274 else
274 else
275 seconds = nil
275 seconds = nil
276 time_stat = "Time used: n/a sec."
276 time_stat = "Time used: n/a sec."
277 end
277 end
278
278
279 # extract memory usage
279 # extract memory usage
280 if res = /s(.*)m/.match(running_stat_line)
280 if res = /s(.*)m/.match(running_stat_line)
281 memory_used = res[1].to_i
281 memory_used = res[1].to_i
282 else
282 else
283 memory_used = -1
283 memory_used = -1
284 end
284 end
285
285
286 return {
286 return {
287 :msg => "#{run_stat}\n#{time_stat}",
287 :msg => "#{run_stat}\n#{time_stat}",
288 :running_time => seconds,
288 :running_time => seconds,
289 :exit_status => run_stat,
289 :exit_status => run_stat,
290 :memory_usage => memory_used
290 :memory_usage => memory_used
291 }
291 }
292 end
292 end
293
293
294 end
294 end
295
295
You need to be logged in to leave comments. Login now