Description:
reorder submission and remove duplicate code for submission
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r644:6431e2ef4265 - - 6 files changed: 7 inserted, 54 deleted

@@ -1,335 +1,318
1 1 class MainController < ApplicationController
2 2
3 3 before_filter :authenticate, :except => [:index, :login]
4 4 before_filter :check_viewability, :except => [:index, :login]
5 5
6 6 append_before_filter :confirm_and_update_start_time,
7 7 :except => [:index,
8 8 :login,
9 9 :confirm_contest_start]
10 10
11 11 # to prevent log in box to be shown when user logged out of the
12 12 # system only in some tab
13 13 prepend_before_filter :reject_announcement_refresh_when_logged_out,
14 14 :only => [:announcements]
15 15
16 16 before_filter :authenticate_by_ip_address, :only => [:list]
17 17
18 18 # COMMENTED OUT: filter in each action instead
19 19 # before_filter :verify_time_limit, :only => [:submit]
20 20
21 21 verify :method => :post, :only => [:submit],
22 22 :redirect_to => { :action => :index }
23 23
24 24 # COMMENT OUT: only need when having high load
25 25 # caches_action :index, :login
26 26
27 27 # NOTE: This method is not actually needed, 'config/routes.rb' has
28 28 # assigned action login as a default action.
29 29 def index
30 30 redirect_to :action => 'login'
31 31 end
32 32
33 33 def login
34 34 saved_notice = flash[:notice]
35 35 reset_session
36 36 flash.now[:notice] = saved_notice
37 37
38 38 # EXPERIMENT:
39 39 # Hide login if in single user mode and the url does not
40 40 # explicitly specify /login
41 41 #
42 42 # logger.info "PATH: #{request.path}"
43 43 # if GraderConfiguration['system.single_user_mode'] and
44 44 # request.path!='/main/login'
45 45 # @hidelogin = true
46 46 # end
47 47
48 48 @announcements = Announcement.frontpage
49 49 render :action => 'login', :layout => 'empty'
50 50 end
51 51
52 52 def list
53 53 prepare_list_information
54 54 end
55 55
56 56 def help
57 57 @user = User.find(session[:user_id])
58 58 end
59 59
60 60 def submit
61 61 user = User.find(session[:user_id])
62 62
63 63 @submission = Submission.new
64 64 @submission.problem_id = params[:submission][:problem_id]
65 65 @submission.user = user
66 66 @submission.language_id = 0
67 67 if (params['file']) and (params['file']!='')
68 68 @submission.source = File.open(params['file'].path,'r:UTF-8',&:read)
69 69 @submission.source.encode!('UTF-8','UTF-8',invalid: :replace, replace: '')
70 70 @submission.source_filename = params['file'].original_filename
71 71 end
72 72
73 73 if (params[:editor_text])
74 74 language = Language.find_by_id(params[:language_id])
75 75 @submission.source = params[:editor_text]
76 76 @submission.source_filename = "live_edit.#{language.ext}"
77 77 @submission.language = language
78 78 end
79 79
80 80 @submission.submitted_at = Time.new.gmtime
81 81 @submission.ip_address = request.remote_ip
82 82
83 83 if GraderConfiguration.time_limit_mode? and user.contest_finished?
84 84 @submission.errors.add(:base,"The contest is over.")
85 85 prepare_list_information
86 86 render :action => 'list' and return
87 87 end
88 88
89 89 if @submission.valid?
90 90 if @submission.save == false
91 91 flash[:notice] = 'Error saving your submission'
92 92 elsif Task.create(:submission_id => @submission.id,
93 93 :status => Task::STATUS_INQUEUE) == false
94 94 flash[:notice] = 'Error adding your submission to task queue'
95 95 end
96 96 else
97 97 prepare_list_information
98 98 render :action => 'list' and return
99 99 end
100 100 redirect_to :action => 'list'
101 101 end
102 102
103 103 def source
104 104 submission = Submission.find(params[:id])
105 105 if ((submission.user_id == session[:user_id]) and
106 106 (submission.problem != nil) and
107 107 (submission.problem.available))
108 108 send_data(submission.source,
109 109 {:filename => submission.download_filename,
110 110 :type => 'text/plain'})
111 111 else
112 112 flash[:notice] = 'Error viewing source'
113 113 redirect_to :action => 'list'
114 114 end
115 115 end
116 116
117 117 def compiler_msg
118 118 @submission = Submission.find(params[:id])
119 119 if @submission.user_id == session[:user_id]
120 120 render :action => 'compiler_msg', :layout => 'empty'
121 121 else
122 122 flash[:notice] = 'Error viewing source'
123 123 redirect_to :action => 'list'
124 124 end
125 125 end
126 126
127 - def submission
128 - @user = User.find(session[:user_id])
129 - @problems = @user.available_problems
130 - if params[:id]==nil
131 - @problem = nil
132 - @submissions = nil
133 - else
134 - @problem = Problem.find_by_id(params[:id])
135 - if (@problem == nil) or (not @problem.available)
136 - redirect_to :action => 'list'
137 - flash[:notice] = 'Error: submissions for that problem are not viewable.'
138 - return
139 - end
140 - @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
141 - end
142 - end
143 -
144 127 def result
145 128 if !GraderConfiguration.show_grading_result
146 129 redirect_to :action => 'list' and return
147 130 end
148 131 @user = User.find(session[:user_id])
149 132 @submission = Submission.find(params[:id])
150 133 if @submission.user!=@user
151 134 flash[:notice] = 'You are not allowed to view result of other users.'
152 135 redirect_to :action => 'list' and return
153 136 end
154 137 prepare_grading_result(@submission)
155 138 end
156 139
157 140 def load_output
158 141 if !GraderConfiguration.show_grading_result or params[:num]==nil
159 142 redirect_to :action => 'list' and return
160 143 end
161 144 @user = User.find(session[:user_id])
162 145 @submission = Submission.find(params[:id])
163 146 if @submission.user!=@user
164 147 flash[:notice] = 'You are not allowed to view result of other users.'
165 148 redirect_to :action => 'list' and return
166 149 end
167 150 case_num = params[:num].to_i
168 151 out_filename = output_filename(@user.login,
169 152 @submission.problem.name,
170 153 @submission.id,
171 154 case_num)
172 155 if !FileTest.exists?(out_filename)
173 156 flash[:notice] = 'Output not found.'
174 157 redirect_to :action => 'list' and return
175 158 end
176 159
177 160 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
178 161 response.headers['Content-Type'] = "application/force-download"
179 162 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
180 163 response.headers["X-Sendfile"] = out_filename
181 164 response.headers['Content-length'] = File.size(out_filename)
182 165 render :nothing => true
183 166 else
184 167 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
185 168 end
186 169 end
187 170
188 171 def error
189 172 @user = User.find(session[:user_id])
190 173 end
191 174
192 175 # announcement refreshing and hiding methods
193 176
194 177 def announcements
195 178 if params.has_key? 'recent'
196 179 prepare_announcements(params[:recent])
197 180 else
198 181 prepare_announcements
199 182 end
200 183 render(:partial => 'announcement',
201 184 :collection => @announcements,
202 185 :locals => {:announcement_effect => true})
203 186 end
204 187
205 188 def confirm_contest_start
206 189 user = User.find(session[:user_id])
207 190 if request.method == 'POST'
208 191 user.update_start_time
209 192 redirect_to :action => 'list'
210 193 else
211 194 @contests = user.contests
212 195 @user = user
213 196 end
214 197 end
215 198
216 199 protected
217 200
218 201 def prepare_announcements(recent=nil)
219 202 if GraderConfiguration.show_tasks_to?(@user)
220 203 @announcements = Announcement.published(true)
221 204 else
222 205 @announcements = Announcement.published
223 206 end
224 207 if recent!=nil
225 208 recent_id = recent.to_i
226 209 @announcements = @announcements.find_all { |a| a.id > recent_id }
227 210 end
228 211 end
229 212
230 213 def prepare_list_information
231 214 @user = User.find(session[:user_id])
232 215 if not GraderConfiguration.multicontests?
233 216 @problems = @user.available_problems
234 217 else
235 218 @contest_problems = @user.available_problems_group_by_contests
236 219 @problems = @user.available_problems
237 220 end
238 221 @prob_submissions = {}
239 222 @problems.each do |p|
240 223 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
241 224 if sub!=nil
242 225 @prob_submissions[p.id] = { :count => sub.number, :submission => sub }
243 226 else
244 227 @prob_submissions[p.id] = { :count => 0, :submission => nil }
245 228 end
246 229 end
247 230 prepare_announcements
248 231 end
249 232
250 233 def check_viewability
251 234 @user = User.find(session[:user_id])
252 235 if (!GraderConfiguration.show_tasks_to?(@user)) and
253 236 ((action_name=='submission') or (action_name=='submit'))
254 237 redirect_to :action => 'list' and return
255 238 end
256 239 end
257 240
258 241 def prepare_grading_result(submission)
259 242 if GraderConfiguration.task_grading_info.has_key? submission.problem.name
260 243 grading_info = GraderConfiguration.task_grading_info[submission.problem.name]
261 244 else
262 245 # guess task info from problem.full_score
263 246 cases = submission.problem.full_score / 10
264 247 grading_info = {
265 248 'testruns' => cases,
266 249 'testcases' => cases
267 250 }
268 251 end
269 252 @test_runs = []
270 253 if grading_info['testruns'].is_a? Integer
271 254 trun_count = grading_info['testruns']
272 255 trun_count.times do |i|
273 256 @test_runs << [ read_grading_result(@user.login,
274 257 submission.problem.name,
275 258 submission.id,
276 259 i+1) ]
277 260 end
278 261 else
279 262 grading_info['testruns'].keys.sort.each do |num|
280 263 run = []
281 264 testrun = grading_info['testruns'][num]
282 265 testrun.each do |c|
283 266 run << read_grading_result(@user.login,
284 267 submission.problem.name,
285 268 submission.id,
286 269 c)
287 270 end
288 271 @test_runs << run
289 272 end
290 273 end
291 274 end
292 275
293 276 def grading_result_dir(user_name, problem_name, submission_id, case_num)
294 277 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
295 278 end
296 279
297 280 def output_filename(user_name, problem_name, submission_id, case_num)
298 281 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
299 282 return "#{dir}/output.txt"
300 283 end
301 284
302 285 def read_grading_result(user_name, problem_name, submission_id, case_num)
303 286 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
304 287 result_file_name = "#{dir}/result"
305 288 if !FileTest.exists?(result_file_name)
306 289 return {:num => case_num, :msg => 'program did not run'}
307 290 else
308 291 results = File.open(result_file_name).readlines
309 292 run_stat = extract_running_stat(results)
310 293 output_filename = "#{dir}/output.txt"
311 294 if FileTest.exists?(output_filename)
312 295 output_file = true
313 296 output_size = File.size(output_filename)
314 297 else
315 298 output_file = false
316 299 output_size = 0
317 300 end
318 301
319 302 return {
320 303 :num => case_num,
321 304 :msg => results[0],
322 305 :run_stat => run_stat,
323 306 :output => output_file,
324 307 :output_size => output_size
325 308 }
326 309 end
327 310 end
328 311
329 312 # copied from grader/script/lib/test_request_helper.rb
330 313 def extract_running_stat(results)
331 314 running_stat_line = results[-1]
332 315
333 316 # extract exit status line
334 317 run_stat = ""
335 318 if !(/[Cc]orrect/.match(results[0]))
@@ -1,96 +1,96
1 1 class SubmissionsController < ApplicationController
2 2 before_filter :authenticate
3 3 before_filter :submission_authorization, only: [:show, :direct_edit_submission, :download, :edit]
4 4
5 5 # GET /submissions
6 6 # GET /submissions.json
7 7 # Show problem selection and user's submission of that problem
8 8 def index
9 9 @user = @current_user
10 10 @problems = @user.available_problems
11 11
12 12 if params[:problem_id]==nil
13 13 @problem = nil
14 14 @submissions = nil
15 15 else
16 16 @problem = Problem.find_by_id(params[:problem_id])
17 17 if (@problem == nil) or (not @problem.available)
18 18 redirect_to main_list_path
19 19 flash[:notice] = 'Error: submissions for that problem are not viewable.'
20 20 return
21 21 end
22 - @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
22 + @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id).order(id: :desc)
23 23 end
24 24 end
25 25
26 26 # GET /submissions/1
27 27 # GET /submissions/1.json
28 28 def show
29 29 @submission = Submission.find(params[:id])
30 30
31 31 #log the viewing
32 32 user = User.find(session[:user_id])
33 33 SubmissionViewLog.create(user_id: session[:user_id],submission_id: @submission.id) unless user.admin?
34 34 end
35 35
36 36 def download
37 37 @submission = Submission.find(params[:id])
38 38 send_data(@submission.source, {:filename => @submission.download_filename, :type => 'text/plain'})
39 39 end
40 40
41 41 def compiler_msg
42 42 @submission = Submission.find(params[:id])
43 43 respond_to do |format|
44 44 format.js
45 45 end
46 46 end
47 47
48 48 #on-site new submission on specific problem
49 49 def direct_edit_problem
50 50 @problem = Problem.find(params[:problem_id])
51 51 @source = ''
52 52 render 'edit'
53 53 end
54 54
55 55 # GET /submissions/1/edit
56 56 def edit
57 57 @submission = Submission.find(params[:id])
58 58 @source = @submission.source.to_s
59 59 @problem = @submission.problem
60 60 @lang_id = @submission.language.id
61 61 end
62 62
63 63
64 64 def get_latest_submission_status
65 65 @problem = Problem.find(params[:pid])
66 66 @submission = Submission.find_last_by_user_and_problem(params[:uid],params[:pid])
67 67 puts User.find(params[:uid]).login
68 68 puts Problem.find(params[:pid]).name
69 69 puts 'nil' unless @submission
70 70 respond_to do |format|
71 71 format.js
72 72 end
73 73 end
74 74
75 75
76 76 protected
77 77
78 78 def submission_authorization
79 79 #admin always has privileged
80 80 if @current_user.admin?
81 81 return true
82 82 end
83 83
84 84 sub = Submission.find(params[:id])
85 85 if sub.problem.available?
86 86 puts "sub = #{sub.user.id}, current = #{@current_user.id}"
87 87 return true if GraderConfiguration["right.user_view_submission"] or sub.user == @current_user
88 88 end
89 89
90 90 #default to NO
91 91 unauthorized_redirect
92 92 return false
93 93 end
94 94
95 95
96 96 end
@@ -1,26 +1,26
1 1
2 2 %tr
3 3 %td{:align => "center"}
4 - = submission_counter+1
5 - %td{:align => "center"}
4 + = submission.number
5 + %td.text-right
6 6 = link_to "##{submission.id}", submission_path(submission.id)
7 7 %td
8 8 = l submission.submitted_at, format: :long
9 9 = "( #{time_ago_in_words(submission.submitted_at)} ago)"
10 10 %td
11 11 = submission.source_filename
12 12 = " (#{submission.language.pretty_name}) "
13 13 = link_to('[load]',{:action => 'source', :id => submission.id})
14 14 %td
15 15 - if submission.graded_at
16 16 = "Graded at #{format_short_time(submission.graded_at)}."
17 17 %br/
18 18 = "Score: #{(submission.points*100/submission.problem.full_score).to_i} " if GraderConfiguration['ui.show_score']
19 19 = " ["
20 20 %tt
21 21 = submission.grader_comment
22 22 = "]"
23 23 %td
24 24 = render :partial => 'compiler_message', :locals => {:compiler_message => submission.compiler_message }
25 25 %td
26 26 = link_to 'Edit', edit_submission_path(submission.id), class: 'btn btn-success'
@@ -1,92 +1,93
1 1 %header.navbar.navbar-default.navbar-fixed-top
2 2 %nav
3 3 .container-fluid
4 4 .navbar-header
5 5 %button.navbar-toggle.collapsed{ data: {toggle: 'collapse', target: '#navbar-collapse'} }
6 6 %span.sr-only Togggle Navigation
7 7 %span.icon-bar
8 8 %span.icon-bar
9 9 %span.icon-bar
10 10 %a.navbar-brand{href: main_list_path}
11 11 %span.glyphicon.glyphicon-home
12 12 MAIN
13 13 .collapse.navbar-collapse#navbar-collapse
14 14 %ul.nav.navbar-nav
15 + / submission
15 16 - if (@current_user!=nil) and (GraderConfiguration.show_tasks_to?(@current_user))
16 - //= add_menu("#{I18n.t 'menu.tasks'}", 'tasks', 'list')
17 17 %li.dropdown
18 18 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
19 19 = "#{I18n.t 'menu.submissions'}"
20 20 %span.caret
21 21 %ul.dropdown-menu
22 - = add_menu("View", 'main', 'submission')
22 + = add_menu("View", 'submissions', 'index')
23 23 = add_menu("Self Test", 'test', 'index')
24 + / hall of fame
24 25 - if GraderConfiguration['right.user_hall_of_fame']
25 26 = add_menu("#{I18n.t 'menu.hall_of_fame'}", 'report', 'problem_hof')
26 27 / display MODE button (with countdown in contest mode)
27 28 - if GraderConfiguration.analysis_mode?
28 29 %div.navbar-btn.btn.btn-success#countdown= "ANALYSIS MODE"
29 30 - elsif GraderConfiguration.time_limit_mode?
30 31 - if @current_user.contest_finished?
31 32 %div.navbar-btn.btn.btn-danger#countdown= "Contest is over"
32 33 - elsif !@current_user.contest_started?
33 34 %div.navbar-btn.btn.btn-primary#countdown= (t 'title_bar.contest_not_started')
34 35 - else
35 36 %div.navbar-btn.btn.btn-primary#countdown asdf
36 37 :javascript
37 38 $("#countdown").countdown({until: "+#{@current_user.contest_time_left.to_i}s", layout: 'Time left: {hnn}:{mnn}:{snn}'});
38 39 / admin section
39 40 - if (@current_user!=nil) and (session[:admin])
40 41 / management
41 42 %li.dropdown
42 43 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
43 44 Manage
44 45 %span.caret
45 46 %ul.dropdown-menu
46 47 = add_menu( 'Announcements', 'announcements', 'index')
47 48 = add_menu( 'Problems', 'problems', 'index')
48 49 = add_menu( 'Users', 'user_admin', 'index')
49 50 = add_menu( 'Graders', 'graders', 'list')
50 51 = add_menu( 'Message ', 'messages', 'console')
51 52 %li.divider{role: 'separator'}
52 53 = add_menu( 'System config', 'configurations', 'index')
53 54 %li.divider{role: 'separator'}
54 55 = add_menu( 'Sites', 'sites', 'index')
55 56 = add_menu( 'Contests', 'contest_management', 'index')
56 57 / report
57 58 %li.dropdown
58 59 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
59 60 Report
60 61 %span.caret
61 62 %ul.dropdown-menu
62 63 = add_menu( 'Current Score', 'report', 'current_score')
63 64 = add_menu( 'Score Report', 'report', 'max_score')
64 65 = add_menu( 'Report', 'report', 'multiple_login')
65 66 - if (ungraded = Submission.where('graded_at is null').where('submitted_at < ?', 1.minutes.ago).count) > 0
66 67 =link_to "#{ungraded} backlogs!",
67 68 grader_list_path,
68 69 class: 'navbar-btn btn btn-default btn-warning', data: {toggle: 'tooltip'},title: 'Number of ungraded submission'
69 70
70 71 %ul.nav.navbar-nav.navbar-right
71 72 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-question-sign')}".html_safe, 'main', 'help')
72 73 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-comment')}".html_safe, 'messages', 'list', {title: I18n.t('menu.messages'), data: {toggle: 'tooltip'}})
73 74 - if GraderConfiguration['system.user_setting_enabled']
74 75 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-cog')}".html_safe, 'users', 'index', {title: I18n.t('menu.settings'), data: {toggle: 'tooltip'}})
75 76 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-log-out')} #{@current_user.full_name}".html_safe, 'main', 'login', {title: I18n.t('menu.log_out'), data: {toggle: 'tooltip'}})
76 77
77 78 /
78 79 - if (@current_user!=nil) and (session[:admin])
79 80 %nav.navbar.navbar-fixed-top.navbar-inverse.secondnavbar
80 81 .container-fluid
81 82 .collapse.navbar-collapse
82 83 %ul.nav.navbar-nav
83 84 = add_menu( '[Announcements]', 'announcements', 'index')
84 85 = add_menu( '[Msg console]', 'messages', 'console')
85 86 = add_menu( '[Problems]', 'problems', 'index')
86 87 = add_menu( '[Users]', 'user_admin', 'index')
87 88 = add_menu( '[Results]', 'user_admin', 'user_stat')
88 89 = add_menu( '[Report]', 'report', 'multiple_login')
89 90 = add_menu( '[Graders]', 'graders', 'list')
90 91 = add_menu( '[Contests]', 'contest_management', 'index')
91 92 = add_menu( '[Sites]', 'sites', 'index')
92 93 = add_menu( '[System config]', 'configurations', 'index')
@@ -1,29 +1,29
1 1 .panel.panel-info
2 2 .panel-heading
3 3 Select Problems
4 4 .panel-body
5 5 .form-inline
6 6 = select 'submission',
7 7 'problem_id',
8 8 @problems.collect {|p| ["[#{p.name}] #{p.full_name}", problem_submissions_url(p.id)]},
9 9 { selected: (@problem ? problem_submissions_url(@problem) : -1) },
10 10 { class: 'select2 form-control'}
11 11 %button.btn.btn-primary.btn-sm.go-button#problem_go{data: {source: '#submission_problem_id'}} Go
12 12
13 13 - if @problem!=nil
14 14 %h2= "Task: #{@problem.full_name} (#{@problem.name})"
15 15
16 16 - if @submissions!=nil
17 17 - if @submissions.length>0
18 18 %table.table
19 19 %thead
20 20 %th No.
21 - %th #
21 + %th.text-right #
22 22 %th At
23 23 %th Source
24 24 %th Result
25 25 %th{:width => "300px"} Compiler message
26 26 %th
27 27 = render :partial => 'submission', :collection => @submissions
28 28 - else
29 29 No submission
deleted file
You need to be logged in to leave comments. Login now