Description:
fix allow admin to submit to any problem
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r682:405106fcdb33 - - 7 files changed: 17 inserted, 5 deleted

@@ -41,97 +41,97
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 - if @submission.valid?
89 + if @submission.valid?(@current_user)
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 127 def result
128 128 if !GraderConfiguration.show_grading_result
129 129 redirect_to :action => 'list' and return
130 130 end
131 131 @user = User.find(session[:user_id])
132 132 @submission = Submission.find(params[:id])
133 133 if @submission.user!=@user
134 134 flash[:notice] = 'You are not allowed to view result of other users.'
135 135 redirect_to :action => 'list' and return
136 136 end
137 137 prepare_grading_result(@submission)
@@ -7,96 +7,101
7 7 # GET /submissions.json
8 8 # Show problem selection and user's submission of that problem
9 9 def index
10 10 @user = @current_user
11 11 @problems = @user.available_problems
12 12
13 13 if params[:problem_id]==nil
14 14 @problem = nil
15 15 @submissions = nil
16 16 else
17 17 @problem = Problem.find_by_id(params[:problem_id])
18 18 if (@problem == nil) or (not @problem.available)
19 19 redirect_to main_list_path
20 20 flash[:notice] = 'Error: submissions for that problem are not viewable.'
21 21 return
22 22 end
23 23 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id).order(id: :desc)
24 24 end
25 25 end
26 26
27 27 # GET /submissions/1
28 28 # GET /submissions/1.json
29 29 def show
30 30 @submission = Submission.find(params[:id])
31 31
32 32 #log the viewing
33 33 user = User.find(session[:user_id])
34 34 SubmissionViewLog.create(user_id: session[:user_id],submission_id: @submission.id) unless user.admin?
35 35
36 36 @task = @submission.task
37 37 end
38 38
39 39 def download
40 40 @submission = Submission.find(params[:id])
41 41 send_data(@submission.source, {:filename => @submission.download_filename, :type => 'text/plain'})
42 42 end
43 43
44 44 def compiler_msg
45 45 @submission = Submission.find(params[:id])
46 46 respond_to do |format|
47 47 format.js
48 48 end
49 49 end
50 50
51 51 #on-site new submission on specific problem
52 52 def direct_edit_problem
53 53 @problem = Problem.find(params[:problem_id])
54 54 @source = ''
55 + if (params[:user_id])
56 + u = User.find(params[:user_id])
57 + @submission = Submission.find_last_by_user_and_problem(u.id,@problem.id)
58 + @source = @submission.source.to_s if @submission and @submission.source
59 + end
55 60 render 'edit'
56 61 end
57 62
58 63 # GET /submissions/1/edit
59 64 def edit
60 65 @submission = Submission.find(params[:id])
61 66 @source = @submission.source.to_s
62 67 @problem = @submission.problem
63 68 @lang_id = @submission.language.id
64 69 end
65 70
66 71
67 72 def get_latest_submission_status
68 73 @problem = Problem.find(params[:pid])
69 74 @submission = Submission.find_last_by_user_and_problem(params[:uid],params[:pid])
70 75 puts User.find(params[:uid]).login
71 76 puts Problem.find(params[:pid]).name
72 77 puts 'nil' unless @submission
73 78 respond_to do |format|
74 79 format.js
75 80 end
76 81 end
77 82
78 83 # GET /submissions/:id/rejudge
79 84 def rejudge
80 85 @submission = Submission.find(params[:id])
81 86 @task = @submission.task
82 87 @task.status_inqueue! if @task
83 88 respond_to do |format|
84 89 format.js
85 90 end
86 91 end
87 92
88 93 protected
89 94
90 95 def submission_authorization
91 96 #admin always has privileged
92 97 if @current_user.admin?
93 98 return true
94 99 end
95 100
96 101 sub = Submission.find(params[:id])
97 102 if sub.problem.available?
98 103 puts "sub = #{sub.user.id}, current = #{@current_user.id}"
99 104 return true if GraderConfiguration["right.user_view_submission"] or sub.user == @current_user
100 105 end
101 106
102 107 #default to NO
@@ -102,61 +102,65
102 102
103 103 def self.find_problem_in_source(source, source_filename="")
104 104 prob_opt = find_option_in_source(/^TASK:/,source)
105 105 if problem = Problem.find_by_name(prob_opt)
106 106 return problem
107 107 else
108 108 if source_filename
109 109 return Problem.find_by_name(source_filename.split('.').first)
110 110 else
111 111 return nil
112 112 end
113 113 end
114 114 end
115 115
116 116 def assign_problem
117 117 if self.problem_id!=-1
118 118 begin
119 119 self.problem = Problem.find(self.problem_id)
120 120 rescue ActiveRecord::RecordNotFound
121 121 self.problem = nil
122 122 end
123 123 else
124 124 self.problem = Submission.find_problem_in_source(self.source,
125 125 self.source_filename)
126 126 end
127 127 end
128 128
129 129 def assign_language
130 130 self.language = Submission.find_language_in_source(self.source,
131 131 self.source_filename)
132 132 end
133 133
134 134 # validation codes
135 135 def must_specify_language
136 136 return if self.source==nil
137 137
138 138 # for output_only tasks
139 139 return if self.problem!=nil and self.problem.output_only
140 140
141 141 if self.language==nil
142 142 errors.add('source',"Cannot detect language. Did you submit a correct source file?") unless self.language!=nil
143 143 end
144 144 end
145 145
146 146 def must_have_valid_problem
147 147 return if self.source==nil
148 148 if self.problem==nil
149 149 errors.add('problem',"must be specified.")
150 - elsif (!self.problem.available) and (self.new_record?)
151 - errors.add('problem',"must be valid.")
150 + else
151 + #admin always have right
152 + return if self.user.admin?
153 +
154 + #check if user has the right to submit the problem
155 + errors.add('problem',"must be valid.") if (!self.user.available_problem.include?(self.problem)) and (self.new_record?)
152 156 end
153 157 end
154 158
155 159 # callbacks
156 160 def assign_latest_number_if_new_recond
157 161 return if !self.new_record?
158 162 latest = Submission.find_last_by_user_and_problem(self.user_id, self.problem_id)
159 163 self.number = (latest==nil) ? 1 : latest.number + 1;
160 164 end
161 165
162 166 end
@@ -247,96 +247,97
247 247 stat.started_at = Time.now.gmtime
248 248 stat.save
249 249 end
250 250 end
251 251
252 252 def problem_in_user_contests?(problem)
253 253 problem_contests = problem.contests.all
254 254
255 255 if problem_contests.length == 0 # this is public contest
256 256 return true
257 257 end
258 258
259 259 contests.each do |contest|
260 260 if problem_contests.find {|c| c.id == contest.id }
261 261 return true
262 262 end
263 263 end
264 264 return false
265 265 end
266 266
267 267 def available_problems_group_by_contests
268 268 contest_problems = []
269 269 pin = {}
270 270 contests.enabled.each do |contest|
271 271 available_problems = contest.problems.available
272 272 contest_problems << {
273 273 :contest => contest,
274 274 :problems => available_problems
275 275 }
276 276 available_problems.each {|p| pin[p.id] = true}
277 277 end
278 278 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
279 279 contest_problems << {
280 280 :contest => nil,
281 281 :problems => other_avaiable_problems
282 282 }
283 283 return contest_problems
284 284 end
285 285
286 286 def solve_all_available_problems?
287 287 available_problems.each do |p|
288 288 u = self
289 289 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
290 290 return false if !p or !sub or sub.points < p.full_score
291 291 end
292 292 return true
293 293 end
294 294
295 + #get a list of available problem
295 296 def available_problems
296 297 if not GraderConfiguration.multicontests?
297 298 if GraderConfiguration.use_problem_group?
298 299 return available_problems_in_group
299 300 else
300 301 return Problem.available_problems
301 302 end
302 303 else
303 304 contest_problems = []
304 305 pin = {}
305 306 contests.enabled.each do |contest|
306 307 contest.problems.available.each do |problem|
307 308 if not pin.has_key? problem.id
308 309 contest_problems << problem
309 310 end
310 311 pin[problem.id] = true
311 312 end
312 313 end
313 314 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
314 315 return contest_problems + other_avaiable_problems
315 316 end
316 317 end
317 318
318 319 def available_problems_in_group
319 320 problem = []
320 321 self.groups.each do |group|
321 322 group.problems.where(available: true).each { |p| problem << p }
322 323 end
323 324 problem.uniq!
324 325 if problem
325 326 problem.sort! do |a,b|
326 327 case
327 328 when a.date_added < b.date_added
328 329 1
329 330 when a.date_added > b.date_added
330 331 -1
331 332 else
332 333 a.name <=> b.name
333 334 end
334 335 end
335 336 return problem
336 337 else
337 338 return []
338 339 end
339 340 end
340 341
341 342 def can_view_problem?(problem)
342 343 return true if admin?
@@ -1,60 +1,60
1 1 - content_for :head do
2 2 = stylesheet_link_tag 'problems'
3 3 %h1 Problems
4 4 %p
5 5 = link_to 'Import problems', {:action => 'import'}, class: 'btn btn-success btn-sm'
6 6 = link_to 'New problem', new_problem_path, class: 'btn btn-success btn-sm'
7 7 = link_to 'Bulk Manage', { action: 'manage'}, class: 'btn btn-info btn-sm'
8 8 = link_to 'Turn off all problems', {:action => 'turn_all_off'}, class: 'btn btn-default btn-sm'
9 9 = link_to 'Turn on all problems', {:action => 'turn_all_on'}, class: 'btn btn-default btn-sm'
10 10 .submitbox
11 11 = form_tag :action => 'quick_create' do
12 12 %b Quick New:
13 13 %label{:for => "problem_name"} Name
14 14 = text_field 'problem', 'name'
15 15 |
16 16 %label{:for => "problem_full_name"} Full name
17 17 = text_field 'problem', 'full_name'
18 18 = submit_tag "Create"
19 19 %table.table.table-condense.table-hover
20 20 %thead
21 21 %th Name
22 22 %th Full name
23 23 %th.text-right Full score
24 24 %th
25 25 Submit
26 26 %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Admin can always submit to any problem' } [?]
27 27 %th Date added
28 28 %th.text-center
29 29 Avail?
30 30 %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Let user submits to this problem?' } [?]
31 31 %th.text-center
32 32 View Data?
33 33 %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Let user view the testcase of this problem?' } [?]
34 34 %th.text-center
35 35 Test?
36 36 %sup{class: 'text-primary',data: {toggle: 'tooltip'}, title: 'Let user uses test interface on this problem?' } [?]
37 37 - if GraderConfiguration.multicontests?
38 38 %th Contests
39 39 - for problem in @problems
40 40 %tr{:class => "#{(problem.available) ? "success" : "danger"}", :id => "prob-#{problem.id}", :name => "prob-#{problem.id}"}
41 41 - @problem=problem
42 42 %td= problem.name #in_place_editor_field :problem, :name, {}, :rows=>1
43 43 %td
44 44 = problem.full_name #in_place_editor_field :problem, :full_name, {}, :rows=>1
45 45 = link_to_description_if_any "[#{t 'main.problem_desc'}] <span class='glyphicon glyphicon-file'></span>".html_safe, problem
46 46 %td.text-right= problem.full_score #in_place_editor_field :problem, :full_score, {}, :rows=>1
47 - %td= link_to "Submit", direct_edit_problem_submissions_path(problem), class: 'btn btn-xs btn-primary'
47 + %td= link_to "Submit", direct_edit_problem_submissions_path(problem,@current_user.id), class: 'btn btn-xs btn-primary'
48 48 %td= problem.date_added
49 49 %td= toggle_button(@problem.available?, toggle_problem_path(@problem), "problem-avail-#{@problem.id}")
50 50 %td= toggle_button(@problem.view_testcase?, toggle_view_testcase_problem_path(@problem), "problem-view-testcase-#{@problem.id}")
51 51 %td= toggle_button(@problem.test_allowed?, toggle_test_problem_path(@problem), "problem-test-#{@problem.id}")
52 52 - if GraderConfiguration.multicontests?
53 53 %td
54 54 = problem.contests.collect { |c| c.name }.join(', ')
55 55 %td= link_to 'Stat', {:action => 'stat', :id => problem.id}, class: 'btn btn-info btn-xs btn-block'
56 56 %td= link_to 'Show', {:action => 'show', :id => problem}, class: 'btn btn-info btn-xs btn-block'
57 57 %td= link_to 'Edit', {:action => 'edit', :id => problem}, class: 'btn btn-info btn-xs btn-block'
58 58 %td= link_to 'Destroy', { :action => 'destroy', :id => problem }, :confirm => 'Are you sure?', :method => :delete, class: 'btn btn-danger btn-xs btn-block'
59 59 %br/
60 60 = link_to '[New problem]', :action => 'new'
@@ -1,75 +1,77
1 1 %h2 Live submit
2 2 %br
3 3
4 4 %textarea#text_sourcecode{style: "display:none"}~ @source
5 5 .container
6 6 .row
7 7 .col-md-12
8 8 .alert.alert-info
9 9 Write your code in the following box, choose language, and click submit button when finished
10 10 .row
11 11 .col-md-8
12 12 %div#editor{style: 'height: 500px; border-radius: 7px; font-size: 14px;'}
13 13 .col-md-4
14 + - # submission form
14 15 = form_tag({controller: :main, :action => 'submit'}, :multipart => true, class: 'form') do
15 16
16 17 = hidden_field_tag 'editor_text', @source
17 18 = hidden_field_tag 'submission[problem_id]', @problem.id
18 19 .form-group
19 20 = label_tag "Task:"
20 21 = text_field_tag 'asdf', "#{@problem.long_name}", class: 'form-control', disabled: true
21 22
22 23 .form-group
23 24 = label_tag 'Language'
24 25 = select_tag 'language_id', options_from_collection_for_select(Language.all, 'id', 'pretty_name', @lang_id || Language.find_by_pretty_name("Python").id || Language.first.id), class: 'form-control select', style: "width: 100px"
25 26 .form-group
26 27 = submit_tag 'Submit', class: 'btn btn-success', id: 'live_submit',
27 28 data: {confirm: "Submitting this source code for task #{@problem.long_name}?"}
29 + - # latest submission status
28 30 .panel.panel-info
29 31 .panel-heading
30 32 Latest Submission Status
31 33 = link_to "Refresh",get_latest_submission_status_submissions_path(@submission.user,@problem), class: "btn btn-default btn-sm", remote: true if @submission
32 34 .panel-body
33 35 - if @submission
34 36 = render :partial => 'submission_short',
35 37 :locals => {submission: @submission, problem_name: @problem.name, problem_id: @problem.id }
36 38 .row
37 39 .col-md-12
38 40 %h2 Console
39 41 %textarea#console{style: 'height: 100%; width: 100%;background-color:#000;color:#fff;font-family: consolas, monaco, "Droid Sans Mono";',rows: 20}
40 42
41 43 :javascript
42 44 $(document).ready(function() {
43 45 e = ace.edit("editor")
44 46 e.setValue($("#text_sourcecode").val());
45 47 e.gotoLine(1);
46 48 $("#language_id").trigger('change');
47 49 brython();
48 50 });
49 51
50 52
51 53 %script#__main__{type:'text/python3'}
52 54 :plain
53 55 import sys
54 56 import traceback
55 57
56 58 from browser import document as doc
57 59 from browser import window, alert, console
58 60
59 61 _credits = """ Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
60 62 for supporting Python development. See www.python.org for more information."""
61 63
62 64 _copyright = """Copyright (c) 2012, Pierre Quentel pierre.quentel@gmail.com
63 65 All Rights Reserved.
64 66
65 67 Copyright (c) 2001-2013 Python Software Foundation.
66 68 All Rights Reserved.
67 69
68 70 Copyright (c) 2000 BeOpen.com.
69 71 All Rights Reserved.
70 72
71 73 Copyright (c) 1995-2001 Corporation for National Research Initiatives.
72 74 All Rights Reserved.
73 75
74 76 Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.
75 77 All Rights Reserved."""
@@ -28,87 +28,87
28 28 get 'turn_all_off'
29 29 get 'turn_all_on'
30 30 get 'import'
31 31 get 'manage'
32 32 end
33 33 end
34 34
35 35 resources :groups do
36 36 member do
37 37 post 'add_user', to: 'groups#add_user', as: 'add_user'
38 38 delete 'remove_user/:user_id', to: 'groups#remove_user', as: 'remove_user'
39 39 delete 'remove_all_user', to: 'groups#remove_all_user', as: 'remove_all_user'
40 40 post 'add_problem', to: 'groups#add_problem', as: 'add_problem'
41 41 delete 'remove_problem/:problem_id', to: 'groups#remove_problem', as: 'remove_problem'
42 42 delete 'remove_all_problem', to: 'groups#remove_all_problem', as: 'remove_all_problem'
43 43 end
44 44 collection do
45 45
46 46 end
47 47 end
48 48
49 49 resources :testcases, only: [] do
50 50 member do
51 51 get 'download_input'
52 52 get 'download_sol'
53 53 end
54 54 collection do
55 55 get 'show_problem/:problem_id(/:test_num)' => 'testcases#show_problem', as: 'show_problem'
56 56 end
57 57 end
58 58
59 59 resources :grader_configuration, controller: 'configurations'
60 60
61 61 resources :users do
62 62 member do
63 63 get 'toggle_activate', 'toggle_enable'
64 64 get 'stat'
65 65 end
66 66 end
67 67
68 68 resources :submissions do
69 69 member do
70 70 get 'download'
71 71 get 'compiler_msg'
72 72 get 'rejudge'
73 73 end
74 74 collection do
75 75 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
76 - get 'direct_edit_problem/:problem_id', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
76 + get 'direct_edit_problem/:problem_id(/:user_id)', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
77 77 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
78 78 end
79 79 end
80 80
81 81
82 82
83 83 #main
84 84 get "main/list"
85 85 get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
86 86
87 87 #user admin
88 88 get 'user_admin/bulk_manage', to: 'user_admin#bulk_manage', as: 'bulk_manage_user_admin'
89 89 post 'user_admin', to: 'user_admin#create'
90 90 delete 'user_admin/:id', to: 'user_admin#destroy', as: 'user_admin_destroy'
91 91
92 92 #report
93 93 get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
94 94 get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
95 95 get "report/login"
96 96 get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
97 97 post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
98 98
99 99
100 100 #
101 101 get 'tasks/view/:file.:ext' => 'tasks#view'
102 102 get 'tasks/download/:id/:file.:ext' => 'tasks#download'
103 103 get 'heartbeat/:id/edit' => 'heartbeat#edit'
104 104
105 105 #grader
106 106 get 'graders/list', to: 'graders#list', as: 'grader_list'
107 107
108 108
109 109 # See how all your routes lay out with "rake routes"
110 110
111 111 # This is a legacy wild controller route that's not recommended for RESTful applications.
112 112 # Note: This route will make all actions in every controller accessible via GET requests.
113 113 match ':controller(/:action(/:id))(.:format)', via: [:get, :post]
114 114 end
You need to be logged in to leave comments. Login now