Description:
added solution submission with grading
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r214:cdf8c2c3dce8 - - 3 files changed: 52 inserted, 7 deleted

@@ -1,357 +1,389
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, :new_input, :download_input, :submit_solution],
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']) and (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 # announcement refreshing and hiding methods
166 # announcement refreshing and hiding methods
167
167
168 def announcements
168 def announcements
169 if params.has_key? 'recent'
169 if params.has_key? 'recent'
170 prepare_announcements(params[:recent])
170 prepare_announcements(params[:recent])
171 else
171 else
172 prepare_announcements
172 prepare_announcements
173 end
173 end
174 render(:partial => 'announcement',
174 render(:partial => 'announcement',
175 :collection => @announcements,
175 :collection => @announcements,
176 :locals => {:announcement_effect => true})
176 :locals => {:announcement_effect => true})
177 end
177 end
178
178
179 # actions for Code Jom
179 # actions for Code Jom
180 def new_input
180 def new_input
181 problem = Problem.find(params[:id])
181 problem = Problem.find(params[:id])
182 user = User.find(session[:user_id])
182 user = User.find(session[:user_id])
183 if user.can_request_new_test_pair_for? problem
183 if user.can_request_new_test_pair_for? problem
184 assignment = user.get_new_test_pair_assignment_for problem
184 assignment = user.get_new_test_pair_assignment_for problem
185 assignment.save
185 assignment.save
186
186
187 send_data(assignment.test_pair.input,
187 send_data(assignment.test_pair.input,
188 { :filename => "#{problem.name}-#{assignment.request_number}.in",
188 { :filename => "#{problem.name}-#{assignment.request_number}.in",
189 :type => 'text/plain' })
189 :type => 'text/plain' })
190 else
190 else
191 flash[:notice] = 'You cannot request new input now.'
191 flash[:notice] = 'You cannot request new input now.'
192 redirect_to :action => 'list'
192 redirect_to :action => 'list'
193 end
193 end
194 end
194 end
195
195
196 - def download
196 + def download_input
197 problem = Problem.find(params[:id])
197 problem = Problem.find(params[:id])
198 user = User.find(session[:user_id])
198 user = User.find(session[:user_id])
199 recent_assignment = user.get_recent_test_pair_assignment_for problem
199 recent_assignment = user.get_recent_test_pair_assignment_for problem
200 if recent_assignment != nil
200 if recent_assignment != nil
201 send_data(recent_assignment.test_pair.input,
201 send_data(recent_assignment.test_pair.input,
202 { :filename => "#{problem.name}-#{recent_assignment.request_number}.in",
202 { :filename => "#{problem.name}-#{recent_assignment.request_number}.in",
203 :type => 'text/plain' })
203 :type => 'text/plain' })
204 else
204 else
205 - flash[:notice] = 'You have not request for any input data for this problem.'
205 + flash[:notice] = 'You have not requested for any input data for this problem.'
206 + redirect_to :action => 'list'
207 + end
208 + end
209 +
210 + def submit_solution
211 + problem = Problem.find(params[:id])
212 + user = User.find(session[:user_id])
213 + recent_assignment = user.get_recent_test_pair_assignment_for problem
214 + if recent_assignment != nil
215 + submitted_solution = params[:file].read
216 + test_pair = recent_assignment.test_pair
217 + passed = test_pair.grade(submitted_solution)
218 + points = passed ? 100 : 0
219 + submission = Submission.new(:user => user,
220 + :problem => problem,
221 + :source => params[:file].read,
222 + :source_filename => params['file'].original_filename,
223 + :language_id => 0,
224 + :submitted_at => Time.new.gmtime,
225 + :graded_at => Time.new.gmtime,
226 + :points => points)
227 + submission.save
228 + recent_assignment.submitted = true
229 + recent_assignment.save
230 + if passed
231 + flash[:notice] = 'Correct solution'
232 + else
233 + flash[:notice] = 'Incorrect solution'
234 + end
235 + redirect_to :action => 'list'
236 + else
237 + flash[:notice] = 'You have not requested for any input data for this problem.'
206 redirect_to :action => 'list'
238 redirect_to :action => 'list'
207 end
239 end
208 end
240 end
209
241
210 protected
242 protected
211
243
212 def prepare_announcements(recent=nil)
244 def prepare_announcements(recent=nil)
213 if Configuration.show_tasks_to?(@user)
245 if Configuration.show_tasks_to?(@user)
214 @announcements = Announcement.find_published(true)
246 @announcements = Announcement.find_published(true)
215 else
247 else
216 @announcements = Announcement.find_published
248 @announcements = Announcement.find_published
217 end
249 end
218 if recent!=nil
250 if recent!=nil
219 recent_id = recent.to_i
251 recent_id = recent.to_i
220 @announcements = @announcements.find_all { |a| a.id > recent_id }
252 @announcements = @announcements.find_all { |a| a.id > recent_id }
221 end
253 end
222 end
254 end
223
255
224 def prepare_list_information
256 def prepare_list_information
225 @problems = Problem.find_available_problems
257 @problems = Problem.find_available_problems
226 @prob_submissions = Array.new
258 @prob_submissions = Array.new
227 @user = User.find(session[:user_id])
259 @user = User.find(session[:user_id])
228 @problems.each do |p|
260 @problems.each do |p|
229 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
261 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
230 if sub!=nil
262 if sub!=nil
231 @prob_submissions << { :count => sub.number, :submission => sub }
263 @prob_submissions << { :count => sub.number, :submission => sub }
232 else
264 else
233 @prob_submissions << { :count => 0, :submission => nil }
265 @prob_submissions << { :count => 0, :submission => nil }
234 end
266 end
235 end
267 end
236 prepare_announcements
268 prepare_announcements
237 end
269 end
238
270
239 def check_viewability
271 def check_viewability
240 @user = User.find(session[:user_id])
272 @user = User.find(session[:user_id])
241 if (!Configuration.show_tasks_to?(@user)) and
273 if (!Configuration.show_tasks_to?(@user)) and
242 ((action_name=='submission') or (action_name=='submit'))
274 ((action_name=='submission') or (action_name=='submit'))
243 redirect_to :action => 'list' and return
275 redirect_to :action => 'list' and return
244 end
276 end
245 end
277 end
246
278
247 def prepare_grading_result(submission)
279 def prepare_grading_result(submission)
248 if Configuration.task_grading_info.has_key? submission.problem.name
280 if Configuration.task_grading_info.has_key? submission.problem.name
249 grading_info = Configuration.task_grading_info[submission.problem.name]
281 grading_info = Configuration.task_grading_info[submission.problem.name]
250 else
282 else
251 # guess task info from problem.full_score
283 # guess task info from problem.full_score
252 cases = submission.problem.full_score / 10
284 cases = submission.problem.full_score / 10
253 grading_info = {
285 grading_info = {
254 'testruns' => cases,
286 'testruns' => cases,
255 'testcases' => cases
287 'testcases' => cases
256 }
288 }
257 end
289 end
258 @test_runs = []
290 @test_runs = []
259 if grading_info['testruns'].is_a? Integer
291 if grading_info['testruns'].is_a? Integer
260 trun_count = grading_info['testruns']
292 trun_count = grading_info['testruns']
261 trun_count.times do |i|
293 trun_count.times do |i|
262 @test_runs << [ read_grading_result(@user.login,
294 @test_runs << [ read_grading_result(@user.login,
263 submission.problem.name,
295 submission.problem.name,
264 submission.id,
296 submission.id,
265 i+1) ]
297 i+1) ]
266 end
298 end
267 else
299 else
268 grading_info['testruns'].keys.sort.each do |num|
300 grading_info['testruns'].keys.sort.each do |num|
269 run = []
301 run = []
270 testrun = grading_info['testruns'][num]
302 testrun = grading_info['testruns'][num]
271 testrun.each do |c|
303 testrun.each do |c|
272 run << read_grading_result(@user.login,
304 run << read_grading_result(@user.login,
273 submission.problem.name,
305 submission.problem.name,
274 submission.id,
306 submission.id,
275 c)
307 c)
276 end
308 end
277 @test_runs << run
309 @test_runs << run
278 end
310 end
279 end
311 end
280 end
312 end
281
313
282 def grading_result_dir(user_name, problem_name, submission_id, case_num)
314 def grading_result_dir(user_name, problem_name, submission_id, case_num)
283 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
315 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
284 end
316 end
285
317
286 def output_filename(user_name, problem_name, submission_id, case_num)
318 def output_filename(user_name, problem_name, submission_id, case_num)
287 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
319 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
288 return "#{dir}/output.txt"
320 return "#{dir}/output.txt"
289 end
321 end
290
322
291 def read_grading_result(user_name, problem_name, submission_id, case_num)
323 def read_grading_result(user_name, problem_name, submission_id, case_num)
292 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
324 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
293 result_file_name = "#{dir}/result"
325 result_file_name = "#{dir}/result"
294 if !FileTest.exists?(result_file_name)
326 if !FileTest.exists?(result_file_name)
295 return {:num => case_num, :msg => 'program did not run'}
327 return {:num => case_num, :msg => 'program did not run'}
296 else
328 else
297 results = File.open(result_file_name).readlines
329 results = File.open(result_file_name).readlines
298 run_stat = extract_running_stat(results)
330 run_stat = extract_running_stat(results)
299 output_filename = "#{dir}/output.txt"
331 output_filename = "#{dir}/output.txt"
300 if FileTest.exists?(output_filename)
332 if FileTest.exists?(output_filename)
301 output_file = true
333 output_file = true
302 output_size = File.size(output_filename)
334 output_size = File.size(output_filename)
303 else
335 else
304 output_file = false
336 output_file = false
305 output_size = 0
337 output_size = 0
306 end
338 end
307
339
308 return {
340 return {
309 :num => case_num,
341 :num => case_num,
310 :msg => results[0],
342 :msg => results[0],
311 :run_stat => run_stat,
343 :run_stat => run_stat,
312 :output => output_file,
344 :output => output_file,
313 :output_size => output_size
345 :output_size => output_size
314 }
346 }
315 end
347 end
316 end
348 end
317
349
318 # copied from grader/script/lib/test_request_helper.rb
350 # copied from grader/script/lib/test_request_helper.rb
319 def extract_running_stat(results)
351 def extract_running_stat(results)
320 running_stat_line = results[-1]
352 running_stat_line = results[-1]
321
353
322 # extract exit status line
354 # extract exit status line
323 run_stat = ""
355 run_stat = ""
324 if !(/[Cc]orrect/.match(results[0]))
356 if !(/[Cc]orrect/.match(results[0]))
325 run_stat = results[0].chomp
357 run_stat = results[0].chomp
326 else
358 else
327 run_stat = 'Program exited normally'
359 run_stat = 'Program exited normally'
328 end
360 end
329
361
330 logger.info "Stat line: #{running_stat_line}"
362 logger.info "Stat line: #{running_stat_line}"
331
363
332 # extract running time
364 # extract running time
333 if res = /r(.*)u(.*)s/.match(running_stat_line)
365 if res = /r(.*)u(.*)s/.match(running_stat_line)
334 seconds = (res[1].to_f + res[2].to_f)
366 seconds = (res[1].to_f + res[2].to_f)
335 time_stat = "Time used: #{seconds} sec."
367 time_stat = "Time used: #{seconds} sec."
336 else
368 else
337 seconds = nil
369 seconds = nil
338 time_stat = "Time used: n/a sec."
370 time_stat = "Time used: n/a sec."
339 end
371 end
340
372
341 # extract memory usage
373 # extract memory usage
342 if res = /s(.*)m/.match(running_stat_line)
374 if res = /s(.*)m/.match(running_stat_line)
343 memory_used = res[1].to_i
375 memory_used = res[1].to_i
344 else
376 else
345 memory_used = -1
377 memory_used = -1
346 end
378 end
347
379
348 return {
380 return {
349 :msg => "#{run_stat}\n#{time_stat}",
381 :msg => "#{run_stat}\n#{time_stat}",
350 :running_time => seconds,
382 :running_time => seconds,
351 :exit_status => run_stat,
383 :exit_status => run_stat,
352 :memory_usage => memory_used
384 :memory_usage => memory_used
353 }
385 }
354 end
386 end
355
387
356 end
388 end
357
389
@@ -1,9 +1,22
1 # TestPair stores an input-solution pair for a problem. This is used
1 # TestPair stores an input-solution pair for a problem. This is used
2 # in a certain "test-pair"-type problem for the CodeJom competition
2 # in a certain "test-pair"-type problem for the CodeJom competition
3 # which follows the Google Code Jam format, i.e., a participant only
3 # which follows the Google Code Jam format, i.e., a participant only
4 # submits a solution to a single random input that the participant
4 # submits a solution to a single random input that the participant
5 # requested. This input-solution pair is a TestPair.
5 # requested. This input-solution pair is a TestPair.
6
6
7 class TestPair < ActiveRecord::Base
7 class TestPair < ActiveRecord::Base
8 belongs_to :problem
8 belongs_to :problem
9 +
10 + def grade(submitted_solution)
11 + sols = solution.split
12 + subs = submitted_solution.split
13 + if sols.length == subs.length
14 + subs.length.times do |i|
15 + return false if subs[i]!=sols[i]
9 end
16 end
17 + return true
18 + else
19 + return false
20 + end
21 + end
22 + end
@@ -1,26 +1,26
1 <tr class="info-<%= (problem_counter%2==0) ? "even" : "odd" %>">
1 <tr class="info-<%= (problem_counter%2==0) ? "even" : "odd" %>">
2 <td>
2 <td>
3 <%= "#{problem_counter+1}" %>
3 <%= "#{problem_counter+1}" %>
4 </td>
4 </td>
5 <td>
5 <td>
6 <%= "#{problem.full_name} (#{problem.name})" %>
6 <%= "#{problem.full_name} (#{problem.name})" %>
7 <%= link_to "[#{t 'main.problem_desc'}]", problem.url, :popup => true if (problem.url!=nil) and (problem.url!='') %>
7 <%= link_to "[#{t 'main.problem_desc'}]", problem.url, :popup => true if (problem.url!=nil) and (problem.url!='') %>
8 </td>
8 </td>
9 <td align="center">
9 <td align="center">
10 <%= @prob_submissions[problem_counter][:count] %>
10 <%= @prob_submissions[problem_counter][:count] %>
11 </td>
11 </td>
12 <td>
12 <td>
13 <span id="problem-form-<%= problem.id %>">
13 <span id="problem-form-<%= problem.id %>">
14 - <% form_tag "new_input/#{problem.id}", :method => :post do -%>
14 + <% form_tag({:action => 'new_input', :id => problem.id}, :method => :post) do -%>
15 <input type="submit" value="New input"/>
15 <input type="submit" value="New input"/>
16 <% end -%>
16 <% end -%>
17 - <% form_tag "download/#{problem.id}", :method => :post do -%>
17 + <% form_tag({ :action => 'download_input', :id => problem.id }, :method => :post) do -%>
18 <input type="submit" value="Download input"/>
18 <input type="submit" value="Download input"/>
19 <% end -%>
19 <% end -%>
20 - <% form_tag "submit_solution/#{problem.id}", :method => :post do -%>
20 + <% form_tag({ :action => 'submit_solution', :id => problem.id }, :method => :post, :multipart => true) do -%>
21 - <input type="file">
21 + <input type="file" name="file">
22 <input type="submit" value="Submit solution"/>
22 <input type="submit" value="Submit solution"/>
23 <% end -%>
23 <% end -%>
24 </span>
24 </span>
25 </td>
25 </td>
26 </tr>
26 </tr>
You need to be logged in to leave comments. Login now