Description:
merge
Commit status:
[Not Reviewed]
References:
merge java
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r515:25e5802e70aa - - 7 files changed: 69 inserted, 3 deleted

@@ -0,0 +1,17
1 + %table.info
2 + %thead
3 + %tr.info-head
4 + %th Problem
5 + %th User
6 + %th tries
7 + %tbody
8 + - @struggle.each do |s|
9 + %tr
10 + %td
11 + = link_to "(#{s[:problem].name})", controller: :problems, action: :stat, id: s[:problem]
12 + = s[:problem].full_name
13 + %td
14 + = link_to "(#{s[:user].login})", controller: :users, action: :profile, id: s[:user]
15 + = s[:user].full_name
16 + %td
17 + = s[:tries]
@@ -1,118 +1,119
1 class GradersController < ApplicationController
1 class GradersController < ApplicationController
2
2
3 before_filter :admin_authorization, except: [ :submission ]
3 before_filter :admin_authorization, except: [ :submission ]
4 before_filter(only: [:submission]) {
4 before_filter(only: [:submission]) {
5 return false unless authenticate
5 return false unless authenticate
6
6
7 if GraderConfiguration["right.user_view_submission"]
7 if GraderConfiguration["right.user_view_submission"]
8 return true;
8 return true;
9 end
9 end
10
10
11 admin_authorization
11 admin_authorization
12 }
12 }
13
13
14 verify :method => :post, :only => ['clear_all',
14 verify :method => :post, :only => ['clear_all',
15 'start_exam',
15 'start_exam',
16 'start_grading',
16 'start_grading',
17 'stop_all',
17 'stop_all',
18 'clear_terminated'],
18 'clear_terminated'],
19 :redirect_to => {:action => 'index'}
19 :redirect_to => {:action => 'index'}
20
20
21 def index
21 def index
22 redirect_to :action => 'list'
22 redirect_to :action => 'list'
23 end
23 end
24
24
25 def list
25 def list
26 @grader_processes = GraderProcess.find_running_graders
26 @grader_processes = GraderProcess.find_running_graders
27 @stalled_processes = GraderProcess.find_stalled_process
27 @stalled_processes = GraderProcess.find_stalled_process
28
28
29 @terminated_processes = GraderProcess.find_terminated_graders
29 @terminated_processes = GraderProcess.find_terminated_graders
30
30
31 @last_task = Task.find(:first,
31 @last_task = Task.find(:first,
32 :order => 'created_at DESC')
32 :order => 'created_at DESC')
33 @last_test_request = TestRequest.find(:first,
33 @last_test_request = TestRequest.find(:first,
34 :order => 'created_at DESC')
34 :order => 'created_at DESC')
35 + @submission = Submission.order("id desc").limit(20)
35 end
36 end
36
37
37 def clear
38 def clear
38 grader_proc = GraderProcess.find(params[:id])
39 grader_proc = GraderProcess.find(params[:id])
39 grader_proc.destroy if grader_proc!=nil
40 grader_proc.destroy if grader_proc!=nil
40 redirect_to :action => 'list'
41 redirect_to :action => 'list'
41 end
42 end
42
43
43 def clear_terminated
44 def clear_terminated
44 GraderProcess.find_terminated_graders.each do |p|
45 GraderProcess.find_terminated_graders.each do |p|
45 p.destroy
46 p.destroy
46 end
47 end
47 redirect_to :action => 'list'
48 redirect_to :action => 'list'
48 end
49 end
49
50
50 def clear_all
51 def clear_all
51 GraderProcess.find(:all).each do |p|
52 GraderProcess.find(:all).each do |p|
52 p.destroy
53 p.destroy
53 end
54 end
54 redirect_to :action => 'list'
55 redirect_to :action => 'list'
55 end
56 end
56
57
57 def view
58 def view
58 if params[:type]=='Task'
59 if params[:type]=='Task'
59 redirect_to :action => 'task', :id => params[:id]
60 redirect_to :action => 'task', :id => params[:id]
60 else
61 else
61 redirect_to :action => 'test_request', :id => params[:id]
62 redirect_to :action => 'test_request', :id => params[:id]
62 end
63 end
63 end
64 end
64
65
65 def test_request
66 def test_request
66 @test_request = TestRequest.find(params[:id])
67 @test_request = TestRequest.find(params[:id])
67 end
68 end
68
69
69 def task
70 def task
70 @task = Task.find(params[:id])
71 @task = Task.find(params[:id])
71 end
72 end
72
73
73 def submission
74 def submission
74 @submission = Submission.find(params[:id])
75 @submission = Submission.find(params[:id])
75 formatter = Rouge::Formatters::HTML.new(css_class: 'highlight', line_numbers: true )
76 formatter = Rouge::Formatters::HTML.new(css_class: 'highlight', line_numbers: true )
76 lexer = case @submission.language.name
77 lexer = case @submission.language.name
77 when "c" then Rouge::Lexers::C.new
78 when "c" then Rouge::Lexers::C.new
78 when "cpp" then Rouge::Lexers::Cpp.new
79 when "cpp" then Rouge::Lexers::Cpp.new
79 when "pas" then Rouge::Lexers::Pas.new
80 when "pas" then Rouge::Lexers::Pas.new
80 when "ruby" then Rouge::Lexers::Ruby.new
81 when "ruby" then Rouge::Lexers::Ruby.new
81 when "python" then Rouge::Lexers::Python.new
82 when "python" then Rouge::Lexers::Python.new
82 when "java" then Rouge::Lexers::Java.new
83 when "java" then Rouge::Lexers::Java.new
83 when "php" then Rouge::Lexers::PHP.new
84 when "php" then Rouge::Lexers::PHP.new
84 end
85 end
85 @formatted_code = formatter.format(lexer.lex(@submission.source))
86 @formatted_code = formatter.format(lexer.lex(@submission.source))
86 @css_style = Rouge::Themes::ThankfulEyes.render(scope: '.highlight')
87 @css_style = Rouge::Themes::ThankfulEyes.render(scope: '.highlight')
87
88
88 end
89 end
89
90
90 # various grader controls
91 # various grader controls
91
92
92 def stop
93 def stop
93 grader_proc = GraderProcess.find(params[:id])
94 grader_proc = GraderProcess.find(params[:id])
94 GraderScript.stop_grader(grader_proc.pid)
95 GraderScript.stop_grader(grader_proc.pid)
95 flash[:notice] = 'Grader stopped. It may not disappear now, but it should disappear shortly.'
96 flash[:notice] = 'Grader stopped. It may not disappear now, but it should disappear shortly.'
96 redirect_to :action => 'list'
97 redirect_to :action => 'list'
97 end
98 end
98
99
99 def stop_all
100 def stop_all
100 GraderScript.stop_graders(GraderProcess.find_running_graders +
101 GraderScript.stop_graders(GraderProcess.find_running_graders +
101 GraderProcess.find_stalled_process)
102 GraderProcess.find_stalled_process)
102 flash[:notice] = 'Graders stopped. They may not disappear now, but they should disappear shortly.'
103 flash[:notice] = 'Graders stopped. They may not disappear now, but they should disappear shortly.'
103 redirect_to :action => 'list'
104 redirect_to :action => 'list'
104 end
105 end
105
106
106 def start_grading
107 def start_grading
107 GraderScript.start_grader('grading')
108 GraderScript.start_grader('grading')
108 flash[:notice] = '2 graders in grading env started, one for grading queue tasks, another for grading test request'
109 flash[:notice] = '2 graders in grading env started, one for grading queue tasks, another for grading test request'
109 redirect_to :action => 'list'
110 redirect_to :action => 'list'
110 end
111 end
111
112
112 def start_exam
113 def start_exam
113 GraderScript.start_grader('exam')
114 GraderScript.start_grader('exam')
114 flash[:notice] = '2 graders in grading env started, one for grading queue tasks, another for grading test request'
115 flash[:notice] = '2 graders in grading env started, one for grading queue tasks, another for grading test request'
115 redirect_to :action => 'list'
116 redirect_to :action => 'list'
116 end
117 end
117
118
118 end
119 end
@@ -1,258 +1,259
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 = File.open(params['file'].path,'r:UTF-8',&:read)
67 + @submission.source.encode!('UTF-8','UTF-8',invalid: :replace, replace: '')
67 @submission.source_filename = params['file'].original_filename
68 @submission.source_filename = params['file'].original_filename
68 end
69 end
69 @submission.submitted_at = Time.new.gmtime
70 @submission.submitted_at = Time.new.gmtime
70 @submission.ip_address = request.remote_ip
71 @submission.ip_address = request.remote_ip
71
72
72 if GraderConfiguration.time_limit_mode? and user.contest_finished?
73 if GraderConfiguration.time_limit_mode? and user.contest_finished?
73 @submission.errors.add_to_base "The contest is over."
74 @submission.errors.add_to_base "The contest is over."
74 prepare_list_information
75 prepare_list_information
75 render :action => 'list' and return
76 render :action => 'list' and return
76 end
77 end
77
78
78 if @submission.valid?
79 if @submission.valid?
79 if @submission.save == false
80 if @submission.save == false
80 flash[:notice] = 'Error saving your submission'
81 flash[:notice] = 'Error saving your submission'
81 elsif Task.create(:submission_id => @submission.id,
82 elsif Task.create(:submission_id => @submission.id,
82 :status => Task::STATUS_INQUEUE) == false
83 :status => Task::STATUS_INQUEUE) == false
83 flash[:notice] = 'Error adding your submission to task queue'
84 flash[:notice] = 'Error adding your submission to task queue'
84 end
85 end
85 else
86 else
86 prepare_list_information
87 prepare_list_information
87 render :action => 'list' and return
88 render :action => 'list' and return
88 end
89 end
89 redirect_to :action => 'list'
90 redirect_to :action => 'list'
90 end
91 end
91
92
92 def source
93 def source
93 submission = Submission.find(params[:id])
94 submission = Submission.find(params[:id])
94 if ((submission.user_id == session[:user_id]) and
95 if ((submission.user_id == session[:user_id]) and
95 (submission.problem != nil) and
96 (submission.problem != nil) and
96 (submission.problem.available))
97 (submission.problem.available))
97 send_data(submission.source,
98 send_data(submission.source,
98 {:filename => submission.download_filename,
99 {:filename => submission.download_filename,
99 :type => 'text/plain'})
100 :type => 'text/plain'})
100 else
101 else
101 flash[:notice] = 'Error viewing source'
102 flash[:notice] = 'Error viewing source'
102 redirect_to :action => 'list'
103 redirect_to :action => 'list'
103 end
104 end
104 end
105 end
105
106
106 def compiler_msg
107 def compiler_msg
107 @submission = Submission.find(params[:id])
108 @submission = Submission.find(params[:id])
108 if @submission.user_id == session[:user_id]
109 if @submission.user_id == session[:user_id]
109 render :action => 'compiler_msg', :layout => 'empty'
110 render :action => 'compiler_msg', :layout => 'empty'
110 else
111 else
111 flash[:notice] = 'Error viewing source'
112 flash[:notice] = 'Error viewing source'
112 redirect_to :action => 'list'
113 redirect_to :action => 'list'
113 end
114 end
114 end
115 end
115
116
116 def submission
117 def submission
117 @user = User.find(session[:user_id])
118 @user = User.find(session[:user_id])
118 @problems = @user.available_problems
119 @problems = @user.available_problems
119 if params[:id]==nil
120 if params[:id]==nil
120 @problem = nil
121 @problem = nil
121 @submissions = nil
122 @submissions = nil
122 else
123 else
123 @problem = Problem.find_by_name(params[:id])
124 @problem = Problem.find_by_name(params[:id])
124 if not @problem.available
125 if not @problem.available
125 redirect_to :action => 'list'
126 redirect_to :action => 'list'
126 flash[:notice] = 'Error: submissions for that problem are not viewable.'
127 flash[:notice] = 'Error: submissions for that problem are not viewable.'
127 return
128 return
128 end
129 end
129 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
130 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
130 end
131 end
131 end
132 end
132
133
133 def result
134 def result
134 if !GraderConfiguration.show_grading_result
135 if !GraderConfiguration.show_grading_result
135 redirect_to :action => 'list' and return
136 redirect_to :action => 'list' and return
136 end
137 end
137 @user = User.find(session[:user_id])
138 @user = User.find(session[:user_id])
138 @submission = Submission.find(params[:id])
139 @submission = Submission.find(params[:id])
139 if @submission.user!=@user
140 if @submission.user!=@user
140 flash[:notice] = 'You are not allowed to view result of other users.'
141 flash[:notice] = 'You are not allowed to view result of other users.'
141 redirect_to :action => 'list' and return
142 redirect_to :action => 'list' and return
142 end
143 end
143 prepare_grading_result(@submission)
144 prepare_grading_result(@submission)
144 end
145 end
145
146
146 def load_output
147 def load_output
147 if !GraderConfiguration.show_grading_result or params[:num]==nil
148 if !GraderConfiguration.show_grading_result or params[:num]==nil
148 redirect_to :action => 'list' and return
149 redirect_to :action => 'list' and return
149 end
150 end
150 @user = User.find(session[:user_id])
151 @user = User.find(session[:user_id])
151 @submission = Submission.find(params[:id])
152 @submission = Submission.find(params[:id])
152 if @submission.user!=@user
153 if @submission.user!=@user
153 flash[:notice] = 'You are not allowed to view result of other users.'
154 flash[:notice] = 'You are not allowed to view result of other users.'
154 redirect_to :action => 'list' and return
155 redirect_to :action => 'list' and return
155 end
156 end
156 case_num = params[:num].to_i
157 case_num = params[:num].to_i
157 out_filename = output_filename(@user.login,
158 out_filename = output_filename(@user.login,
158 @submission.problem.name,
159 @submission.problem.name,
159 @submission.id,
160 @submission.id,
160 case_num)
161 case_num)
161 if !FileTest.exists?(out_filename)
162 if !FileTest.exists?(out_filename)
162 flash[:notice] = 'Output not found.'
163 flash[:notice] = 'Output not found.'
163 redirect_to :action => 'list' and return
164 redirect_to :action => 'list' and return
164 end
165 end
165
166
166 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
167 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
167 response.headers['Content-Type'] = "application/force-download"
168 response.headers['Content-Type'] = "application/force-download"
168 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
169 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
169 response.headers["X-Sendfile"] = out_filename
170 response.headers["X-Sendfile"] = out_filename
170 response.headers['Content-length'] = File.size(out_filename)
171 response.headers['Content-length'] = File.size(out_filename)
171 render :nothing => true
172 render :nothing => true
172 else
173 else
173 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
174 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
174 end
175 end
175 end
176 end
176
177
177 def error
178 def error
178 @user = User.find(session[:user_id])
179 @user = User.find(session[:user_id])
179 end
180 end
180
181
181 # announcement refreshing and hiding methods
182 # announcement refreshing and hiding methods
182
183
183 def announcements
184 def announcements
184 if params.has_key? 'recent'
185 if params.has_key? 'recent'
185 prepare_announcements(params[:recent])
186 prepare_announcements(params[:recent])
186 else
187 else
187 prepare_announcements
188 prepare_announcements
188 end
189 end
189 render(:partial => 'announcement',
190 render(:partial => 'announcement',
190 :collection => @announcements,
191 :collection => @announcements,
191 :locals => {:announcement_effect => true})
192 :locals => {:announcement_effect => true})
192 end
193 end
193
194
194 def confirm_contest_start
195 def confirm_contest_start
195 user = User.find(session[:user_id])
196 user = User.find(session[:user_id])
196 if request.method == :post
197 if request.method == :post
197 user.update_start_time
198 user.update_start_time
198 redirect_to :action => 'list'
199 redirect_to :action => 'list'
199 else
200 else
200 @contests = user.contests
201 @contests = user.contests
201 @user = user
202 @user = user
202 end
203 end
203 end
204 end
204
205
205 protected
206 protected
206
207
207 def prepare_announcements(recent=nil)
208 def prepare_announcements(recent=nil)
208 if GraderConfiguration.show_tasks_to?(@user)
209 if GraderConfiguration.show_tasks_to?(@user)
209 @announcements = Announcement.find_published(true)
210 @announcements = Announcement.find_published(true)
210 else
211 else
211 @announcements = Announcement.find_published
212 @announcements = Announcement.find_published
212 end
213 end
213 if recent!=nil
214 if recent!=nil
214 recent_id = recent.to_i
215 recent_id = recent.to_i
215 @announcements = @announcements.find_all { |a| a.id > recent_id }
216 @announcements = @announcements.find_all { |a| a.id > recent_id }
216 end
217 end
217 end
218 end
218
219
219 def prepare_list_information
220 def prepare_list_information
220 @user = User.find(session[:user_id])
221 @user = User.find(session[:user_id])
221 if not GraderConfiguration.multicontests?
222 if not GraderConfiguration.multicontests?
222 @problems = @user.available_problems
223 @problems = @user.available_problems
223 else
224 else
224 @contest_problems = @user.available_problems_group_by_contests
225 @contest_problems = @user.available_problems_group_by_contests
225 @problems = @user.available_problems
226 @problems = @user.available_problems
226 end
227 end
227 @prob_submissions = {}
228 @prob_submissions = {}
228 @problems.each do |p|
229 @problems.each do |p|
229 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
230 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
230 if sub!=nil
231 if sub!=nil
231 @prob_submissions[p.id] = { :count => sub.number, :submission => sub }
232 @prob_submissions[p.id] = { :count => sub.number, :submission => sub }
232 else
233 else
233 @prob_submissions[p.id] = { :count => 0, :submission => nil }
234 @prob_submissions[p.id] = { :count => 0, :submission => nil }
234 end
235 end
235 end
236 end
236 prepare_announcements
237 prepare_announcements
237 end
238 end
238
239
239 def check_viewability
240 def check_viewability
240 @user = User.find(session[:user_id])
241 @user = User.find(session[:user_id])
241 if (!GraderConfiguration.show_tasks_to?(@user)) and
242 if (!GraderConfiguration.show_tasks_to?(@user)) and
242 ((action_name=='submission') or (action_name=='submit'))
243 ((action_name=='submission') or (action_name=='submit'))
243 redirect_to :action => 'list' and return
244 redirect_to :action => 'list' and return
244 end
245 end
245 end
246 end
246
247
247 def prepare_grading_result(submission)
248 def prepare_grading_result(submission)
248 if GraderConfiguration.task_grading_info.has_key? submission.problem.name
249 if GraderConfiguration.task_grading_info.has_key? submission.problem.name
249 grading_info = GraderConfiguration.task_grading_info[submission.problem.name]
250 grading_info = GraderConfiguration.task_grading_info[submission.problem.name]
250 else
251 else
251 # guess task info from problem.full_score
252 # guess task info from problem.full_score
252 cases = submission.problem.full_score / 10
253 cases = submission.problem.full_score / 10
253 grading_info = {
254 grading_info = {
254 'testruns' => cases,
255 'testruns' => cases,
255 'testcases' => cases
256 'testcases' => cases
256 }
257 }
257 end
258 end
258 @test_runs = []
259 @test_runs = []
@@ -1,191 +1,216
1 class ReportController < ApplicationController
1 class ReportController < ApplicationController
2
2
3 before_filter :admin_authorization, only: [:login_stat,:submission_stat]
3 before_filter :admin_authorization, only: [:login_stat,:submission_stat]
4 before_filter(only: [:problem_hof]) { |c|
4 before_filter(only: [:problem_hof]) { |c|
5 return false unless authenticate
5 return false unless authenticate
6
6
7 if GraderConfiguration["right.user_view_submission"]
7 if GraderConfiguration["right.user_view_submission"]
8 return true;
8 return true;
9 end
9 end
10
10
11 admin_authorization
11 admin_authorization
12 }
12 }
13
13
14 def login_stat
14 def login_stat
15 @logins = Array.new
15 @logins = Array.new
16
16
17 date_and_time = '%Y-%m-%d %H:%M'
17 date_and_time = '%Y-%m-%d %H:%M'
18 begin
18 begin
19 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
19 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
20 @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
20 @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
21 rescue
21 rescue
22 @since_time = DateTime.new(1000,1,1)
22 @since_time = DateTime.new(1000,1,1)
23 end
23 end
24 begin
24 begin
25 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
25 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
26 @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
26 @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
27 rescue
27 rescue
28 @until_time = DateTime.new(3000,1,1)
28 @until_time = DateTime.new(3000,1,1)
29 end
29 end
30
30
31 User.all.each do |user|
31 User.all.each do |user|
32 @logins << { id: user.id,
32 @logins << { id: user.id,
33 login: user.login,
33 login: user.login,
34 full_name: user.full_name,
34 full_name: user.full_name,
35 count: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
35 count: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
36 user.id,@since_time,@until_time)
36 user.id,@since_time,@until_time)
37 .count(:id),
37 .count(:id),
38 min: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
38 min: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
39 user.id,@since_time,@until_time)
39 user.id,@since_time,@until_time)
40 .minimum(:created_at),
40 .minimum(:created_at),
41 max: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
41 max: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
42 user.id,@since_time,@until_time)
42 user.id,@since_time,@until_time)
43 .maximum(:created_at),
43 .maximum(:created_at),
44 ip: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
44 ip: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
45 user.id,@since_time,@until_time)
45 user.id,@since_time,@until_time)
46 .select(:ip_address).uniq
46 .select(:ip_address).uniq
47
47
48 }
48 }
49 end
49 end
50 end
50 end
51
51
52 def submission_stat
52 def submission_stat
53
53
54 date_and_time = '%Y-%m-%d %H:%M'
54 date_and_time = '%Y-%m-%d %H:%M'
55 begin
55 begin
56 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
56 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
57 rescue
57 rescue
58 @since_time = DateTime.new(1000,1,1)
58 @since_time = DateTime.new(1000,1,1)
59 end
59 end
60 begin
60 begin
61 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
61 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
62 rescue
62 rescue
63 @until_time = DateTime.new(3000,1,1)
63 @until_time = DateTime.new(3000,1,1)
64 end
64 end
65
65
66 @submissions = {}
66 @submissions = {}
67
67
68 User.find_each do |user|
68 User.find_each do |user|
69 @submissions[user.id] = { login: user.login, full_name: user.full_name, count: 0, sub: { } }
69 @submissions[user.id] = { login: user.login, full_name: user.full_name, count: 0, sub: { } }
70 end
70 end
71
71
72 Submission.where("submitted_at >= ? AND submitted_at <= ?",@since_time,@until_time).find_each do |s|
72 Submission.where("submitted_at >= ? AND submitted_at <= ?",@since_time,@until_time).find_each do |s|
73 if @submissions[s.user_id]
73 if @submissions[s.user_id]
74 if not @submissions[s.user_id][:sub].has_key?(s.problem_id)
74 if not @submissions[s.user_id][:sub].has_key?(s.problem_id)
75 a = nil
75 a = nil
76 begin
76 begin
77 a = Problem.find(s.problem_id)
77 a = Problem.find(s.problem_id)
78 rescue
78 rescue
79 a = nil
79 a = nil
80 end
80 end
81 @submissions[s.user_id][:sub][s.problem_id] =
81 @submissions[s.user_id][:sub][s.problem_id] =
82 { prob_name: (a ? a.full_name : '(NULL)'),
82 { prob_name: (a ? a.full_name : '(NULL)'),
83 sub_ids: [s.id] }
83 sub_ids: [s.id] }
84 else
84 else
85 @submissions[s.user_id][:sub][s.problem_id][:sub_ids] << s.id
85 @submissions[s.user_id][:sub][s.problem_id][:sub_ids] << s.id
86 end
86 end
87 @submissions[s.user_id][:count] += 1
87 @submissions[s.user_id][:count] += 1
88 end
88 end
89 end
89 end
90 end
90 end
91
91
92 def problem_hof
92 def problem_hof
93 # gen problem list
93 # gen problem list
94 @user = User.find(session[:user_id])
94 @user = User.find(session[:user_id])
95 @problems = @user.available_problems
95 @problems = @user.available_problems
96
96
97 # get selected problems or the default
97 # get selected problems or the default
98 if params[:id]
98 if params[:id]
99 begin
99 begin
100 @problem = Problem.available.find(params[:id])
100 @problem = Problem.available.find(params[:id])
101 rescue
101 rescue
102 redirect_to action: :problem_hof
102 redirect_to action: :problem_hof
103 flash[:notice] = 'Error: submissions for that problem are not viewable.'
103 flash[:notice] = 'Error: submissions for that problem are not viewable.'
104 return
104 return
105 end
105 end
106 end
106 end
107
107
108 return unless @problem
108 return unless @problem
109
109
110 @by_lang = {} #aggregrate by language
110 @by_lang = {} #aggregrate by language
111
111
112 range =65
112 range =65
113 @histogram = { data: Array.new(range,0), summary: {} }
113 @histogram = { data: Array.new(range,0), summary: {} }
114 @summary = {count: 0, solve: 0, attempt: 0}
114 @summary = {count: 0, solve: 0, attempt: 0}
115 user = Hash.new(0)
115 user = Hash.new(0)
116 Submission.where(problem_id: @problem.id).find_each do |sub|
116 Submission.where(problem_id: @problem.id).find_each do |sub|
117 #histogram
117 #histogram
118 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
118 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
119 @histogram[:data][d.to_i] += 1 if d < range
119 @histogram[:data][d.to_i] += 1 if d < range
120
120
121 @summary[:count] += 1
121 @summary[:count] += 1
122 user[sub.user_id] = [user[sub.user_id], (sub.points >= @problem.full_score) ? 1 : 0].max
122 user[sub.user_id] = [user[sub.user_id], (sub.points >= @problem.full_score) ? 1 : 0].max
123
123
124 lang = Language.find_by_id(sub.language_id)
124 lang = Language.find_by_id(sub.language_id)
125 next unless lang
125 next unless lang
126 next unless sub.points >= @problem.full_score
126 next unless sub.points >= @problem.full_score
127
127
128 #initialize
128 #initialize
129 unless @by_lang.has_key?(lang.pretty_name)
129 unless @by_lang.has_key?(lang.pretty_name)
130 @by_lang[lang.pretty_name] = {
130 @by_lang[lang.pretty_name] = {
131 runtime: { avail: false, value: 2**30-1 },
131 runtime: { avail: false, value: 2**30-1 },
132 memory: { avail: false, value: 2**30-1 },
132 memory: { avail: false, value: 2**30-1 },
133 length: { avail: false, value: 2**30-1 },
133 length: { avail: false, value: 2**30-1 },
134 first: { avail: false, value: DateTime.new(3000,1,1) }
134 first: { avail: false, value: DateTime.new(3000,1,1) }
135 }
135 }
136 end
136 end
137
137
138 if sub.max_runtime and sub.max_runtime < @by_lang[lang.pretty_name][:runtime][:value]
138 if sub.max_runtime and sub.max_runtime < @by_lang[lang.pretty_name][:runtime][:value]
139 @by_lang[lang.pretty_name][:runtime] = { avail: true, user_id: sub.user_id, value: sub.max_runtime, sub_id: sub.id }
139 @by_lang[lang.pretty_name][:runtime] = { avail: true, user_id: sub.user_id, value: sub.max_runtime, sub_id: sub.id }
140 end
140 end
141
141
142 if sub.peak_memory and sub.peak_memory < @by_lang[lang.pretty_name][:memory][:value]
142 if sub.peak_memory and sub.peak_memory < @by_lang[lang.pretty_name][:memory][:value]
143 @by_lang[lang.pretty_name][:memory] = { avail: true, user_id: sub.user_id, value: sub.peak_memory, sub_id: sub.id }
143 @by_lang[lang.pretty_name][:memory] = { avail: true, user_id: sub.user_id, value: sub.peak_memory, sub_id: sub.id }
144 end
144 end
145
145
146 if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value] and
146 if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value] and
147 !sub.user.admin?
147 !sub.user.admin?
148 @by_lang[lang.pretty_name][:first] = { avail: true, user_id: sub.user_id, value: sub.submitted_at, sub_id: sub.id }
148 @by_lang[lang.pretty_name][:first] = { avail: true, user_id: sub.user_id, value: sub.submitted_at, sub_id: sub.id }
149 end
149 end
150
150
151 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
151 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
152 @by_lang[lang.pretty_name][:length] = { avail: true, user_id: sub.user_id, value: sub.effective_code_length, sub_id: sub.id }
152 @by_lang[lang.pretty_name][:length] = { avail: true, user_id: sub.user_id, value: sub.effective_code_length, sub_id: sub.id }
153 end
153 end
154 end
154 end
155
155
156 #process user_id
156 #process user_id
157 @by_lang.each do |lang,prop|
157 @by_lang.each do |lang,prop|
158 prop.each do |k,v|
158 prop.each do |k,v|
159 v[:user] = User.exists?(v[:user_id]) ? User.find(v[:user_id]).full_name : "(NULL)"
159 v[:user] = User.exists?(v[:user_id]) ? User.find(v[:user_id]).full_name : "(NULL)"
160 end
160 end
161 end
161 end
162
162
163 #sum into best
163 #sum into best
164 if @by_lang and @by_lang.first
164 if @by_lang and @by_lang.first
165 @best = @by_lang.first[1].clone
165 @best = @by_lang.first[1].clone
166 @by_lang.each do |lang,prop|
166 @by_lang.each do |lang,prop|
167 if @best[:runtime][:value] >= prop[:runtime][:value]
167 if @best[:runtime][:value] >= prop[:runtime][:value]
168 @best[:runtime] = prop[:runtime]
168 @best[:runtime] = prop[:runtime]
169 @best[:runtime][:lang] = lang
169 @best[:runtime][:lang] = lang
170 end
170 end
171 if @best[:memory][:value] >= prop[:memory][:value]
171 if @best[:memory][:value] >= prop[:memory][:value]
172 @best[:memory] = prop[:memory]
172 @best[:memory] = prop[:memory]
173 @best[:memory][:lang] = lang
173 @best[:memory][:lang] = lang
174 end
174 end
175 if @best[:length][:value] >= prop[:length][:value]
175 if @best[:length][:value] >= prop[:length][:value]
176 @best[:length] = prop[:length]
176 @best[:length] = prop[:length]
177 @best[:length][:lang] = lang
177 @best[:length][:lang] = lang
178 end
178 end
179 if @best[:first][:value] >= prop[:first][:value]
179 if @best[:first][:value] >= prop[:first][:value]
180 @best[:first] = prop[:first]
180 @best[:first] = prop[:first]
181 @best[:first][:lang] = lang
181 @best[:first][:lang] = lang
182 end
182 end
183 end
183 end
184 end
184 end
185
185
186 @histogram[:summary][:max] = [@histogram[:data].max,1].max
186 @histogram[:summary][:max] = [@histogram[:data].max,1].max
187 @summary[:attempt] = user.count
187 @summary[:attempt] = user.count
188 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
188 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
189 end
189 end
190
190
191 + def stuck #report struggling user,problem
192 + # init
193 + user,problem = nil
194 + solve = true
195 + tries = 0
196 + @struggle = Array.new
197 + record = {}
198 + Submission.includes(:problem,:user).order(:problem_id,:user_id).find_each do |sub|
199 + if user != sub.user_id or problem != sub.problem_id
200 + @struggle << { user: record[:user], problem: record[:problem], tries: tries } unless solve
201 + record = {user: sub.user, problem: sub.problem}
202 + user,problem = sub.user_id, sub.problem_id
203 + solve = false
204 + tries = 0
191 end
205 end
206 + if sub.points >= sub.problem.full_score
207 + solve = true
208 + else
209 + tries += 1
210 + end
211 + end
212 + @struggle.sort!{|a,b| b[:tries] <=> a[:tries] }
213 + @struggle = @struggle[0..50]
214 + end
215 +
216 + end
@@ -1,194 +1,195
1 require 'net/smtp'
1 require 'net/smtp'
2
2
3 class UsersController < ApplicationController
3 class UsersController < ApplicationController
4
4
5 include MailHelperMethods
5 include MailHelperMethods
6
6
7 before_filter :authenticate, :except => [:new,
7 before_filter :authenticate, :except => [:new,
8 :register,
8 :register,
9 :confirm,
9 :confirm,
10 :forget,
10 :forget,
11 :retrieve_password]
11 :retrieve_password]
12
12
13 before_filter :verify_online_registration, :only => [:new,
13 before_filter :verify_online_registration, :only => [:new,
14 :register,
14 :register,
15 :forget,
15 :forget,
16 :retrieve_password]
16 :retrieve_password]
17 before_filter :authenticate, :profile_authorization, only: [:profile]
17 before_filter :authenticate, :profile_authorization, only: [:profile]
18
18
19 verify :method => :post, :only => [:chg_passwd],
19 verify :method => :post, :only => [:chg_passwd],
20 :redirect_to => { :action => :index }
20 :redirect_to => { :action => :index }
21
21
22 #in_place_edit_for :user, :alias_for_editing
22 #in_place_edit_for :user, :alias_for_editing
23 #in_place_edit_for :user, :email_for_editing
23 #in_place_edit_for :user, :email_for_editing
24
24
25 def index
25 def index
26 if !GraderConfiguration['system.user_setting_enabled']
26 if !GraderConfiguration['system.user_setting_enabled']
27 redirect_to :controller => 'main', :action => 'list'
27 redirect_to :controller => 'main', :action => 'list'
28 else
28 else
29 @user = User.find(session[:user_id])
29 @user = User.find(session[:user_id])
30 end
30 end
31 end
31 end
32
32
33 def chg_passwd
33 def chg_passwd
34 user = User.find(session[:user_id])
34 user = User.find(session[:user_id])
35 user.password = params[:passwd]
35 user.password = params[:passwd]
36 user.password_confirmation = params[:passwd_verify]
36 user.password_confirmation = params[:passwd_verify]
37 if user.save
37 if user.save
38 flash[:notice] = 'password changed'
38 flash[:notice] = 'password changed'
39 else
39 else
40 flash[:notice] = 'Error: password changing failed'
40 flash[:notice] = 'Error: password changing failed'
41 end
41 end
42 redirect_to :action => 'index'
42 redirect_to :action => 'index'
43 end
43 end
44
44
45 def new
45 def new
46 @user = User.new
46 @user = User.new
47 render :action => 'new', :layout => 'empty'
47 render :action => 'new', :layout => 'empty'
48 end
48 end
49
49
50 def register
50 def register
51 if(params[:cancel])
51 if(params[:cancel])
52 redirect_to :controller => 'main', :action => 'login'
52 redirect_to :controller => 'main', :action => 'login'
53 return
53 return
54 end
54 end
55 @user = User.new(params[:user])
55 @user = User.new(params[:user])
56 @user.password_confirmation = @user.password = User.random_password
56 @user.password_confirmation = @user.password = User.random_password
57 @user.activated = false
57 @user.activated = false
58 if (@user.valid?) and (@user.save)
58 if (@user.valid?) and (@user.save)
59 if send_confirmation_email(@user)
59 if send_confirmation_email(@user)
60 render :action => 'new_splash', :layout => 'empty'
60 render :action => 'new_splash', :layout => 'empty'
61 else
61 else
62 @admin_email = GraderConfiguration['system.admin_email']
62 @admin_email = GraderConfiguration['system.admin_email']
63 render :action => 'email_error', :layout => 'empty'
63 render :action => 'email_error', :layout => 'empty'
64 end
64 end
65 else
65 else
66 @user.errors.add_to_base("Email cannot be blank") if @user.email==''
66 @user.errors.add_to_base("Email cannot be blank") if @user.email==''
67 render :action => 'new', :layout => 'empty'
67 render :action => 'new', :layout => 'empty'
68 end
68 end
69 end
69 end
70
70
71 def confirm
71 def confirm
72 login = params[:login]
72 login = params[:login]
73 key = params[:activation]
73 key = params[:activation]
74 @user = User.find_by_login(login)
74 @user = User.find_by_login(login)
75 if (@user) and (@user.verify_activation_key(key))
75 if (@user) and (@user.verify_activation_key(key))
76 if @user.valid? # check uniquenss of email
76 if @user.valid? # check uniquenss of email
77 @user.activated = true
77 @user.activated = true
78 @user.save
78 @user.save
79 @result = :successful
79 @result = :successful
80 else
80 else
81 @result = :email_used
81 @result = :email_used
82 end
82 end
83 else
83 else
84 @result = :failed
84 @result = :failed
85 end
85 end
86 render :action => 'confirm', :layout => 'empty'
86 render :action => 'confirm', :layout => 'empty'
87 end
87 end
88
88
89 def forget
89 def forget
90 render :action => 'forget', :layout => 'empty'
90 render :action => 'forget', :layout => 'empty'
91 end
91 end
92
92
93 def retrieve_password
93 def retrieve_password
94 email = params[:email]
94 email = params[:email]
95 user = User.find_by_email(email)
95 user = User.find_by_email(email)
96 if user
96 if user
97 last_updated_time = user.updated_at || user.created_at || (Time.now.gmtime - 1.hour)
97 last_updated_time = user.updated_at || user.created_at || (Time.now.gmtime - 1.hour)
98 if last_updated_time > Time.now.gmtime - 5.minutes
98 if last_updated_time > Time.now.gmtime - 5.minutes
99 flash[:notice] = 'The account has recently created or new password has recently been requested. Please wait for 5 minutes'
99 flash[:notice] = 'The account has recently created or new password has recently been requested. Please wait for 5 minutes'
100 else
100 else
101 user.password = user.password_confirmation = User.random_password
101 user.password = user.password_confirmation = User.random_password
102 user.save
102 user.save
103 send_new_password_email(user)
103 send_new_password_email(user)
104 flash[:notice] = 'New password has been mailed to you.'
104 flash[:notice] = 'New password has been mailed to you.'
105 end
105 end
106 else
106 else
107 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
107 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
108 end
108 end
109 redirect_to :action => 'forget'
109 redirect_to :action => 'forget'
110 end
110 end
111
111
112 def profile
112 def profile
113 @user = User.find(params[:id])
113 @user = User.find(params[:id])
114 @submission = Submission.includes(:problem).where(user_id: params[:id])
114 @submission = Submission.includes(:problem).where(user_id: params[:id])
115
115
116 range = 120
116 range = 120
117 @histogram = { data: Array.new(range,0), summary: {} }
117 @histogram = { data: Array.new(range,0), summary: {} }
118 @summary = {count: 0, solve: 0, attempt: 0}
118 @summary = {count: 0, solve: 0, attempt: 0}
119 problem = Hash.new(0)
119 problem = Hash.new(0)
120
120
121 @submission.find_each do |sub|
121 @submission.find_each do |sub|
122 #histogram
122 #histogram
123 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
123 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
124 @histogram[:data][d.to_i] += 1 if d < range
124 @histogram[:data][d.to_i] += 1 if d < range
125
125
126 @summary[:count] += 1
126 @summary[:count] += 1
127 + next unless sub.problem
127 problem[sub.problem] = [problem[sub.problem], (sub.points >= sub.problem.full_score) ? 1 : 0].max
128 problem[sub.problem] = [problem[sub.problem], (sub.points >= sub.problem.full_score) ? 1 : 0].max
128 end
129 end
129
130
130 @histogram[:summary][:max] = [@histogram[:data].max,1].max
131 @histogram[:summary][:max] = [@histogram[:data].max,1].max
131 @summary[:attempt] = problem.count
132 @summary[:attempt] = problem.count
132 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
133 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
133 end
134 end
134
135
135 protected
136 protected
136
137
137 def verify_online_registration
138 def verify_online_registration
138 if !GraderConfiguration['system.online_registration']
139 if !GraderConfiguration['system.online_registration']
139 redirect_to :controller => 'main', :action => 'login'
140 redirect_to :controller => 'main', :action => 'login'
140 end
141 end
141 end
142 end
142
143
143 def send_confirmation_email(user)
144 def send_confirmation_email(user)
144 contest_name = GraderConfiguration['contest.name']
145 contest_name = GraderConfiguration['contest.name']
145 activation_url = url_for(:action => 'confirm',
146 activation_url = url_for(:action => 'confirm',
146 :login => user.login,
147 :login => user.login,
147 :activation => user.activation_key)
148 :activation => user.activation_key)
148 home_url = url_for(:controller => 'main', :action => 'index')
149 home_url = url_for(:controller => 'main', :action => 'index')
149 mail_subject = "[#{contest_name}] Confirmation"
150 mail_subject = "[#{contest_name}] Confirmation"
150 mail_body = t('registration.email_body', {
151 mail_body = t('registration.email_body', {
151 :full_name => user.full_name,
152 :full_name => user.full_name,
152 :contest_name => contest_name,
153 :contest_name => contest_name,
153 :login => user.login,
154 :login => user.login,
154 :password => user.password,
155 :password => user.password,
155 :activation_url => activation_url,
156 :activation_url => activation_url,
156 :admin_email => admin_email
157 :admin_email => admin_email
157 })
158 })
158
159
159 logger.info mail_body
160 logger.info mail_body
160
161
161 send_mail(user.email, mail_subject, mail_body)
162 send_mail(user.email, mail_subject, mail_body)
162 end
163 end
163
164
164 def send_new_password_email(user)
165 def send_new_password_email(user)
165 contest_name = GraderConfiguration['contest.name']
166 contest_name = GraderConfiguration['contest.name']
166 mail_subject = "[#{contest_name}] Password recovery"
167 mail_subject = "[#{contest_name}] Password recovery"
167 mail_body = t('registration.password_retrieval.email_body', {
168 mail_body = t('registration.password_retrieval.email_body', {
168 :full_name => user.full_name,
169 :full_name => user.full_name,
169 :contest_name => contest_name,
170 :contest_name => contest_name,
170 :login => user.login,
171 :login => user.login,
171 :password => user.password,
172 :password => user.password,
172 :admin_email => admin_email
173 :admin_email => admin_email
173 })
174 })
174
175
175 logger.info mail_body
176 logger.info mail_body
176
177
177 send_mail(user.email, mail_subject, mail_body)
178 send_mail(user.email, mail_subject, mail_body)
178 end
179 end
179
180
180 # allow viewing of regular user profile only when options allow so
181 # allow viewing of regular user profile only when options allow so
181 # only admins can view admins profile
182 # only admins can view admins profile
182 def profile_authorization
183 def profile_authorization
183 #if view admins' profile, allow only admin
184 #if view admins' profile, allow only admin
184 return false unless(params[:id])
185 return false unless(params[:id])
185 user = User.find(params[:id])
186 user = User.find(params[:id])
186 return false unless user
187 return false unless user
187 return admin_authorization if user.admin?
188 return admin_authorization if user.admin?
188 return true if GraderConfiguration["right.user_view_submission"]
189 return true if GraderConfiguration["right.user_view_submission"]
189
190
190 #finally, we allow only admin
191 #finally, we allow only admin
191 admin_authorization
192 admin_authorization
192 end
193 end
193
194
194 end
195 end
@@ -1,51 +1,72
1 - content_for :head do
1 - content_for :head do
2 = stylesheet_link_tag 'graders'
2 = stylesheet_link_tag 'graders'
3 <meta http-equiv ="refresh" content="60"/>
3 <meta http-equiv ="refresh" content="60"/>
4
4
5 %h1 Grader information
5 %h1 Grader information
6
6
7 = link_to '[Refresh]', :action => 'list'
7 = link_to '[Refresh]', :action => 'list'
8 %br/
8 %br/
9
9
10 .submitbox
10 .submitbox
11 .item
11 .item
12 Grader control:
12 Grader control:
13 .item
13 .item
14 = form_for :clear, :url => {:action => 'start_grading'} do |f|
14 = form_for :clear, :url => {:action => 'start_grading'} do |f|
15 = submit_tag 'Start graders in grading env'
15 = submit_tag 'Start graders in grading env'
16 .item
16 .item
17 = form_for :clear, :url => {:action => 'start_exam'} do |f|
17 = form_for :clear, :url => {:action => 'start_exam'} do |f|
18 = submit_tag 'Start graders in exam env'
18 = submit_tag 'Start graders in exam env'
19 .item
19 .item
20 = form_for :clear, :url => {:action => 'stop_all'} do |f|
20 = form_for :clear, :url => {:action => 'stop_all'} do |f|
21 = submit_tag 'Stop all running graders'
21 = submit_tag 'Stop all running graders'
22 .item
22 .item
23 = form_for :clear, :url => {:action => 'clear_all'} do |f|
23 = form_for :clear, :url => {:action => 'clear_all'} do |f|
24 = submit_tag 'Clear all data'
24 = submit_tag 'Clear all data'
25 %br{:style => 'clear:both'}/
25 %br{:style => 'clear:both'}/
26
26
27 + %div{style: 'width:500px; float: left;'}
27 - if @last_task
28 - if @last_task
28 Last task:
29 Last task:
29 = link_to "#{@last_task.id}", :action => 'view', :id => @last_task.id, :type => 'Task'
30 = link_to "#{@last_task.id}", :action => 'view', :id => @last_task.id, :type => 'Task'
30
31
31 %br/
32 %br/
32
33
33 - if @last_test_request
34 - if @last_test_request
34 Last test_request:
35 Last test_request:
35 = link_to "#{@last_test_request.id}", :action => 'view', :id => @last_test_request.id, :type => 'TestRequest'
36 = link_to "#{@last_test_request.id}", :action => 'view', :id => @last_test_request.id, :type => 'TestRequest'
36
37
37 -
38 %h2 Current graders
38 %h2 Current graders
39
39
40 = render :partial => 'grader_list', :locals => {:grader_list => @grader_processes}
40 = render :partial => 'grader_list', :locals => {:grader_list => @grader_processes}
41
41
42 %h2 Stalled graders
42 %h2 Stalled graders
43
43
44 = render :partial => 'grader_list', :locals => {:grader_list => @stalled_processes}
44 = render :partial => 'grader_list', :locals => {:grader_list => @stalled_processes}
45
45
46 %h2 Terminated graders
46 %h2 Terminated graders
47
47
48 = form_for :clear, :url => {:action => 'clear_terminated'} do |f|
48 = form_for :clear, :url => {:action => 'clear_terminated'} do |f|
49 = submit_tag 'Clear data for terminated graders'
49 = submit_tag 'Clear data for terminated graders'
50
50
51 = render :partial => 'grader_list', :locals => {:grader_list => @terminated_processes}
51 = render :partial => 'grader_list', :locals => {:grader_list => @terminated_processes}
52 + %div{}
53 + %h2 Last 20 submissions
54 + %table.graders
55 + %thead
56 + %th ID
57 + %th User
58 + %th Problem
59 + %th Submitted
60 + %th Graded
61 + %th Result
62 + %tbody
63 + - @submission.each do |sub|
64 + %tr.inactive
65 + %td= link_to sub.id, controller: 'graders' ,action: 'submission', id: sub.id
66 + %td= sub.try(:user).try(:full_name)
67 + %td= sub.try(:problem).try(:full_name)
68 + %td= "#{time_ago_in_words(sub.submitted_at)} ago"
69 + %td= "#{time_ago_in_words(sub.graded_at)} ago"
70 + %td= sub.grader_comment
71 +
72 +
@@ -1,7 +1,7
1
1
2 .task-menu
2 .task-menu
3 Reports
3 Reports
4 %br/
4 %br/
5 = link_to '[Hall of Fame]', :action => 'problem_hof'
5 = link_to '[Hall of Fame]', :action => 'problem_hof'
6 - = link_to '[Submission]', :action => 'submission_stat'
6 + = link_to '[Struggle]', :action => 'stuck'
7 = link_to '[Login]', :action => 'login_stat'
7 = link_to '[Login]', :action => 'login_stat'
You need to be logged in to leave comments. Login now