Description:
- change user_admin default action from list to index - remove duplicate button in grader control
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r588:8bdb0ec71018 - - 4 files changed: 21 inserted, 23 deleted

@@ -1,122 +1,123
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 @submission = Submission.order("id desc").limit(20)
36 + @backlog_submission = Submission.where('graded_at is null')
36 end
37 end
37
38
38 def clear
39 def clear
39 grader_proc = GraderProcess.find(params[:id])
40 grader_proc = GraderProcess.find(params[:id])
40 grader_proc.destroy if grader_proc!=nil
41 grader_proc.destroy if grader_proc!=nil
41 redirect_to :action => 'list'
42 redirect_to :action => 'list'
42 end
43 end
43
44
44 def clear_terminated
45 def clear_terminated
45 GraderProcess.find_terminated_graders.each do |p|
46 GraderProcess.find_terminated_graders.each do |p|
46 p.destroy
47 p.destroy
47 end
48 end
48 redirect_to :action => 'list'
49 redirect_to :action => 'list'
49 end
50 end
50
51
51 def clear_all
52 def clear_all
52 GraderProcess.find(:all).each do |p|
53 GraderProcess.find(:all).each do |p|
53 p.destroy
54 p.destroy
54 end
55 end
55 redirect_to :action => 'list'
56 redirect_to :action => 'list'
56 end
57 end
57
58
58 def view
59 def view
59 if params[:type]=='Task'
60 if params[:type]=='Task'
60 redirect_to :action => 'task', :id => params[:id]
61 redirect_to :action => 'task', :id => params[:id]
61 else
62 else
62 redirect_to :action => 'test_request', :id => params[:id]
63 redirect_to :action => 'test_request', :id => params[:id]
63 end
64 end
64 end
65 end
65
66
66 def test_request
67 def test_request
67 @test_request = TestRequest.find(params[:id])
68 @test_request = TestRequest.find(params[:id])
68 end
69 end
69
70
70 def task
71 def task
71 @task = Task.find(params[:id])
72 @task = Task.find(params[:id])
72 end
73 end
73
74
74 def submission
75 def submission
75 @submission = Submission.find(params[:id])
76 @submission = Submission.find(params[:id])
76 formatter = Rouge::Formatters::HTML.new(css_class: 'highlight', line_numbers: true )
77 formatter = Rouge::Formatters::HTML.new(css_class: 'highlight', line_numbers: true )
77 lexer = case @submission.language.name
78 lexer = case @submission.language.name
78 when "c" then Rouge::Lexers::C.new
79 when "c" then Rouge::Lexers::C.new
79 when "cpp" then Rouge::Lexers::Cpp.new
80 when "cpp" then Rouge::Lexers::Cpp.new
80 when "pas" then Rouge::Lexers::Pas.new
81 when "pas" then Rouge::Lexers::Pas.new
81 when "ruby" then Rouge::Lexers::Ruby.new
82 when "ruby" then Rouge::Lexers::Ruby.new
82 when "python" then Rouge::Lexers::Python.new
83 when "python" then Rouge::Lexers::Python.new
83 when "java" then Rouge::Lexers::Java.new
84 when "java" then Rouge::Lexers::Java.new
84 when "php" then Rouge::Lexers::PHP.new
85 when "php" then Rouge::Lexers::PHP.new
85 end
86 end
86 @formatted_code = formatter.format(lexer.lex(@submission.source))
87 @formatted_code = formatter.format(lexer.lex(@submission.source))
87 @css_style = Rouge::Themes::ThankfulEyes.render(scope: '.highlight')
88 @css_style = Rouge::Themes::ThankfulEyes.render(scope: '.highlight')
88
89
89 user = User.find(session[:user_id])
90 user = User.find(session[:user_id])
90 SubmissionViewLog.create(user_id: session[:user_id],submission_id: @submission.id) unless user.admin?
91 SubmissionViewLog.create(user_id: session[:user_id],submission_id: @submission.id) unless user.admin?
91
92
92 end
93 end
93
94
94 # various grader controls
95 # various grader controls
95
96
96 def stop
97 def stop
97 grader_proc = GraderProcess.find(params[:id])
98 grader_proc = GraderProcess.find(params[:id])
98 GraderScript.stop_grader(grader_proc.pid)
99 GraderScript.stop_grader(grader_proc.pid)
99 flash[:notice] = 'Grader stopped. It may not disappear now, but it should disappear shortly.'
100 flash[:notice] = 'Grader stopped. It may not disappear now, but it should disappear shortly.'
100 redirect_to :action => 'list'
101 redirect_to :action => 'list'
101 end
102 end
102
103
103 def stop_all
104 def stop_all
104 GraderScript.stop_graders(GraderProcess.find_running_graders +
105 GraderScript.stop_graders(GraderProcess.find_running_graders +
105 GraderProcess.find_stalled_process)
106 GraderProcess.find_stalled_process)
106 flash[:notice] = 'Graders stopped. They may not disappear now, but they should disappear shortly.'
107 flash[:notice] = 'Graders stopped. They may not disappear now, but they should disappear shortly.'
107 redirect_to :action => 'list'
108 redirect_to :action => 'list'
108 end
109 end
109
110
110 def start_grading
111 def start_grading
111 GraderScript.start_grader('grading')
112 GraderScript.start_grader('grading')
112 flash[:notice] = '2 graders in grading env started, one for grading queue tasks, another for grading test request'
113 flash[:notice] = '2 graders in grading env started, one for grading queue tasks, another for grading test request'
113 redirect_to :action => 'list'
114 redirect_to :action => 'list'
114 end
115 end
115
116
116 def start_exam
117 def start_exam
117 GraderScript.start_grader('exam')
118 GraderScript.start_grader('exam')
118 flash[:notice] = '2 graders in grading env started, one for grading queue tasks, another for grading test request'
119 flash[:notice] = '2 graders in grading env started, one for grading queue tasks, another for grading test request'
119 redirect_to :action => 'list'
120 redirect_to :action => 'list'
120 end
121 end
121
122
122 end
123 end
@@ -1,215 +1,210
1 require 'csv'
1 require 'csv'
2
2
3 class UserAdminController < ApplicationController
3 class UserAdminController < ApplicationController
4
4
5 include MailHelperMethods
5 include MailHelperMethods
6
6
7 before_filter :admin_authorization
7 before_filter :admin_authorization
8
8
9 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
9 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
10 verify :method => :post, :only => [ :destroy,
10 verify :method => :post, :only => [ :destroy,
11 :create, :create_from_list,
11 :create, :create_from_list,
12 :update,
12 :update,
13 :manage_contest,
13 :manage_contest,
14 :bulk_mail
14 :bulk_mail
15 ],
15 ],
16 :redirect_to => { :action => :list }
16 :redirect_to => { :action => :list }
17
17
18 def index
18 def index
19 - list
20 - render :action => 'list'
21 - end
22 -
23 - def list
24 @user_count = User.count
19 @user_count = User.count
25 if params[:page] == 'all'
20 if params[:page] == 'all'
26 @users = User.all
21 @users = User.all
27 @paginated = false
22 @paginated = false
28 else
23 else
29 @users = User.paginate :page => params[:page]
24 @users = User.paginate :page => params[:page]
30 @paginated = true
25 @paginated = true
31 end
26 end
32 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
27 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
33 @contests = Contest.enabled
28 @contests = Contest.enabled
34 end
29 end
35
30
36 def active
31 def active
37 sessions = ActiveRecord::SessionStore::Session.find(:all, :conditions => ["updated_at >= ?", 60.minutes.ago])
32 sessions = ActiveRecord::SessionStore::Session.find(:all, :conditions => ["updated_at >= ?", 60.minutes.ago])
38 @users = []
33 @users = []
39 sessions.each do |session|
34 sessions.each do |session|
40 if session.data[:user_id]
35 if session.data[:user_id]
41 @users << User.find(session.data[:user_id])
36 @users << User.find(session.data[:user_id])
42 end
37 end
43 end
38 end
44 end
39 end
45
40
46 def show
41 def show
47 @user = User.find(params[:id])
42 @user = User.find(params[:id])
48 end
43 end
49
44
50 def new
45 def new
51 @user = User.new
46 @user = User.new
52 end
47 end
53
48
54 def create
49 def create
55 @user = User.new(params[:user])
50 @user = User.new(params[:user])
56 @user.activated = true
51 @user.activated = true
57 if @user.save
52 if @user.save
58 flash[:notice] = 'User was successfully created.'
53 flash[:notice] = 'User was successfully created.'
59 redirect_to :action => 'index'
54 redirect_to :action => 'index'
60 else
55 else
61 render :action => 'new'
56 render :action => 'new'
62 end
57 end
63 end
58 end
64
59
65 def clear_last_ip
60 def clear_last_ip
66 @user = User.find(params[:id])
61 @user = User.find(params[:id])
67 @user.last_ip = nil
62 @user.last_ip = nil
68 @user.save
63 @user.save
69 redirect_to action: 'index', page: params[:page]
64 redirect_to action: 'index', page: params[:page]
70 end
65 end
71
66
72 def create_from_list
67 def create_from_list
73 lines = params[:user_list]
68 lines = params[:user_list]
74
69
75 note = []
70 note = []
76
71
77 lines.split("\n").each do |line|
72 lines.split("\n").each do |line|
78 items = line.chomp.split(',')
73 items = line.chomp.split(',')
79 if items.length>=2
74 if items.length>=2
80 login = items[0]
75 login = items[0]
81 full_name = items[1]
76 full_name = items[1]
82
77
83 added_random_password = false
78 added_random_password = false
84 if items.length>=3
79 if items.length>=3
85 password = items[2].chomp(" ")
80 password = items[2].chomp(" ")
86 user_alias = (items.length>=4) ? items[3] : login
81 user_alias = (items.length>=4) ? items[3] : login
87 else
82 else
88 password = random_password
83 password = random_password
89 user_alias = (items.length>=4) ? items[3] : login
84 user_alias = (items.length>=4) ? items[3] : login
90 added_random_password = true
85 added_random_password = true
91 end
86 end
92
87
93 user = User.find_by_login(login)
88 user = User.find_by_login(login)
94 if (user)
89 if (user)
95 user.full_name = full_name
90 user.full_name = full_name
96 user.password = password
91 user.password = password
97 else
92 else
98 user = User.new({:login => login,
93 user = User.new({:login => login,
99 :full_name => full_name,
94 :full_name => full_name,
100 :password => password,
95 :password => password,
101 :password_confirmation => password,
96 :password_confirmation => password,
102 :alias => user_alias})
97 :alias => user_alias})
103 end
98 end
104 user.activated = true
99 user.activated = true
105 user.save
100 user.save
106
101
107 if added_random_password
102 if added_random_password
108 note << "'#{login}' (+)"
103 note << "'#{login}' (+)"
109 else
104 else
110 note << login
105 note << login
111 end
106 end
112 end
107 end
113 end
108 end
114 flash[:notice] = 'User(s) ' + note.join(', ') +
109 flash[:notice] = 'User(s) ' + note.join(', ') +
115 ' were successfully created. ' +
110 ' were successfully created. ' +
116 '( (+) - created with random passwords.)'
111 '( (+) - created with random passwords.)'
117 redirect_to :action => 'index'
112 redirect_to :action => 'index'
118 end
113 end
119
114
120 def edit
115 def edit
121 @user = User.find(params[:id])
116 @user = User.find(params[:id])
122 end
117 end
123
118
124 def update
119 def update
125 @user = User.find(params[:id])
120 @user = User.find(params[:id])
126 if @user.update_attributes(params[:user])
121 if @user.update_attributes(params[:user])
127 flash[:notice] = 'User was successfully updated.'
122 flash[:notice] = 'User was successfully updated.'
128 redirect_to :action => 'show', :id => @user
123 redirect_to :action => 'show', :id => @user
129 else
124 else
130 render :action => 'edit'
125 render :action => 'edit'
131 end
126 end
132 end
127 end
133
128
134 def destroy
129 def destroy
135 User.find(params[:id]).destroy
130 User.find(params[:id]).destroy
136 redirect_to :action => 'index'
131 redirect_to :action => 'index'
137 end
132 end
138
133
139 def user_stat
134 def user_stat
140 if params[:commit] == 'download csv'
135 if params[:commit] == 'download csv'
141 @problems = Problem.all
136 @problems = Problem.all
142 else
137 else
143 @problems = Problem.find_available_problems
138 @problems = Problem.find_available_problems
144 end
139 end
145 @users = User.includes(:contests, :contest_stat).where(enabled: true) #find(:all, :include => [:contests, :contest_stat]).where(enabled: true)
140 @users = User.includes(:contests, :contest_stat).where(enabled: true) #find(:all, :include => [:contests, :contest_stat]).where(enabled: true)
146 @scorearray = Array.new
141 @scorearray = Array.new
147 @users.each do |u|
142 @users.each do |u|
148 ustat = Array.new
143 ustat = Array.new
149 ustat[0] = u
144 ustat[0] = u
150 @problems.each do |p|
145 @problems.each do |p|
151 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
146 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
152 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
147 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
153 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
148 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
154 else
149 else
155 ustat << [0,false]
150 ustat << [0,false]
156 end
151 end
157 end
152 end
158 @scorearray << ustat
153 @scorearray << ustat
159 end
154 end
160 if params[:commit] == 'download csv' then
155 if params[:commit] == 'download csv' then
161 csv = gen_csv_from_scorearray(@scorearray,@problems)
156 csv = gen_csv_from_scorearray(@scorearray,@problems)
162 send_data csv, filename: 'last_score.csv'
157 send_data csv, filename: 'last_score.csv'
163 else
158 else
164 render template: 'user_admin/user_stat'
159 render template: 'user_admin/user_stat'
165 end
160 end
166 end
161 end
167
162
168 def user_stat_max
163 def user_stat_max
169 if params[:commit] == 'download csv'
164 if params[:commit] == 'download csv'
170 @problems = Problem.all
165 @problems = Problem.all
171 else
166 else
172 @problems = Problem.find_available_problems
167 @problems = Problem.find_available_problems
173 end
168 end
174 @users = User.find(:all, :include => [:contests, :contest_stat])
169 @users = User.find(:all, :include => [:contests, :contest_stat])
175 @scorearray = Array.new
170 @scorearray = Array.new
176 #set up range from param
171 #set up range from param
177 since_id = params.fetch(:since_id, 0).to_i
172 since_id = params.fetch(:since_id, 0).to_i
178 until_id = params.fetch(:until_id, 0).to_i
173 until_id = params.fetch(:until_id, 0).to_i
179 @users.each do |u|
174 @users.each do |u|
180 ustat = Array.new
175 ustat = Array.new
181 ustat[0] = u
176 ustat[0] = u
182 @problems.each do |p|
177 @problems.each do |p|
183 max_points = 0
178 max_points = 0
184 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
179 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
185 max_points = sub.points if sub and sub.points and (sub.points > max_points)
180 max_points = sub.points if sub and sub.points and (sub.points > max_points)
186 end
181 end
187 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
182 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
188 end
183 end
189 @scorearray << ustat
184 @scorearray << ustat
190 end
185 end
191
186
192 if params[:commit] == 'download csv' then
187 if params[:commit] == 'download csv' then
193 csv = gen_csv_from_scorearray(@scorearray,@problems)
188 csv = gen_csv_from_scorearray(@scorearray,@problems)
194 send_data csv, filename: 'max_score.csv'
189 send_data csv, filename: 'max_score.csv'
195 else
190 else
196 render template: 'user_admin/user_stat'
191 render template: 'user_admin/user_stat'
197 end
192 end
198 end
193 end
199
194
200 def import
195 def import
201 if params[:file]==''
196 if params[:file]==''
202 flash[:notice] = 'Error importing no file'
197 flash[:notice] = 'Error importing no file'
203 redirect_to :action => 'index' and return
198 redirect_to :action => 'index' and return
204 end
199 end
205 import_from_file(params[:file])
200 import_from_file(params[:file])
206 end
201 end
207
202
208 def random_all_passwords
203 def random_all_passwords
209 users = User.find(:all)
204 users = User.find(:all)
210 @prefix = params[:prefix] || ''
205 @prefix = params[:prefix] || ''
211 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
206 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
212 @changed = false
207 @changed = false
213 if request.request_method == 'POST'
208 if request.request_method == 'POST'
214 @non_admin_users.each do |user|
209 @non_admin_users.each do |user|
215 password = random_password
210 password = random_password
@@ -1,195 +1,196
1 # Methods added to this helper will be available to all templates in the application.
1 # Methods added to this helper will be available to all templates in the application.
2 module ApplicationHelper
2 module ApplicationHelper
3
3
4 + #new bootstrap header
4 def navbar_user_header
5 def navbar_user_header
5 left_menu = ''
6 left_menu = ''
6 right_menu = ''
7 right_menu = ''
7 user = User.find(session[:user_id])
8 user = User.find(session[:user_id])
8
9
9 if (user!=nil) and (GraderConfiguration.show_tasks_to?(user))
10 if (user!=nil) and (GraderConfiguration.show_tasks_to?(user))
10 left_menu << add_menu("#{I18n.t 'menu.tasks'}", 'tasks', 'list')
11 left_menu << add_menu("#{I18n.t 'menu.tasks'}", 'tasks', 'list')
11 left_menu << add_menu("#{I18n.t 'menu.submissions'}", 'main', 'submission')
12 left_menu << add_menu("#{I18n.t 'menu.submissions'}", 'main', 'submission')
12 left_menu << add_menu("#{I18n.t 'menu.test'}", 'test', 'index')
13 left_menu << add_menu("#{I18n.t 'menu.test'}", 'test', 'index')
13 end
14 end
14
15
15 if GraderConfiguration['right.user_hall_of_fame']
16 if GraderConfiguration['right.user_hall_of_fame']
16 left_menu << add_menu("#{I18n.t 'menu.hall_of_fame'}", 'report', 'problem_hof')
17 left_menu << add_menu("#{I18n.t 'menu.hall_of_fame'}", 'report', 'problem_hof')
17 end
18 end
18
19
19 right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-question-sign')}".html_safe, 'main', 'help')
20 right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-question-sign')}".html_safe, 'main', 'help')
20 right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-comment')}".html_safe, 'messages', 'list', {title: I18n.t('menu.messages'), data: {toggle: 'tooltip'}})
21 right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-comment')}".html_safe, 'messages', 'list', {title: I18n.t('menu.messages'), data: {toggle: 'tooltip'}})
21 if GraderConfiguration['system.user_setting_enabled']
22 if GraderConfiguration['system.user_setting_enabled']
22 right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-cog')}".html_safe, 'users', 'index', {title: I18n.t('menu.settings'), data: {toggle: 'tooltip'}})
23 right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-cog')}".html_safe, 'users', 'index', {title: I18n.t('menu.settings'), data: {toggle: 'tooltip'}})
23 end
24 end
24 right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-log-out')} #{user.full_name}".html_safe, 'main', 'login', {title: I18n.t('menu.log_out'), data: {toggle: 'tooltip'}})
25 right_menu << add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-log-out')} #{user.full_name}".html_safe, 'main', 'login', {title: I18n.t('menu.log_out'), data: {toggle: 'tooltip'}})
25
26
26
27
27 result = content_tag(:ul,left_menu.html_safe,class: 'nav navbar-nav') + content_tag(:ul,right_menu.html_safe,class: 'nav navbar-nav navbar-right')
28 result = content_tag(:ul,left_menu.html_safe,class: 'nav navbar-nav') + content_tag(:ul,right_menu.html_safe,class: 'nav navbar-nav navbar-right')
28 end
29 end
29
30
30 def add_menu(title, controller, action,html_option = {})
31 def add_menu(title, controller, action,html_option = {})
31 link_option = {controller: controller, action: action}
32 link_option = {controller: controller, action: action}
32 html_option[:class] = (html_option[:class] || '') + " active" if current_page?(link_option)
33 html_option[:class] = (html_option[:class] || '') + " active" if current_page?(link_option)
33 content_tag(:li, link_to(title,link_option),html_option)
34 content_tag(:li, link_to(title,link_option),html_option)
34 end
35 end
35
36
36 def user_header
37 def user_header
37 menu_items = ''
38 menu_items = ''
38 user = User.find(session[:user_id])
39 user = User.find(session[:user_id])
39
40
40 if (user!=nil) and (session[:admin])
41 if (user!=nil) and (session[:admin])
41 # admin menu
42 # admin menu
42 menu_items << "<b>Administrative task:</b> "
43 menu_items << "<b>Administrative task:</b> "
43 append_to menu_items, '[Announcements]', 'announcements', 'index'
44 append_to menu_items, '[Announcements]', 'announcements', 'index'
44 append_to menu_items, '[Msg console]', 'messages', 'console'
45 append_to menu_items, '[Msg console]', 'messages', 'console'
45 append_to menu_items, '[Problems]', 'problems', 'index'
46 append_to menu_items, '[Problems]', 'problems', 'index'
46 append_to menu_items, '[Users]', 'user_admin', 'index'
47 append_to menu_items, '[Users]', 'user_admin', 'index'
47 append_to menu_items, '[Results]', 'user_admin', 'user_stat'
48 append_to menu_items, '[Results]', 'user_admin', 'user_stat'
48 append_to menu_items, '[Report]', 'report', 'multiple_login'
49 append_to menu_items, '[Report]', 'report', 'multiple_login'
49 append_to menu_items, '[Graders]', 'graders', 'list'
50 append_to menu_items, '[Graders]', 'graders', 'list'
50 append_to menu_items, '[Contests]', 'contest_management', 'index'
51 append_to menu_items, '[Contests]', 'contest_management', 'index'
51 append_to menu_items, '[Sites]', 'sites', 'index'
52 append_to menu_items, '[Sites]', 'sites', 'index'
52 append_to menu_items, '[System config]', 'configurations', 'index'
53 append_to menu_items, '[System config]', 'configurations', 'index'
53 menu_items << "<br/>"
54 menu_items << "<br/>"
54 end
55 end
55
56
56 # main page
57 # main page
57 append_to menu_items, "[#{I18n.t 'menu.main'}]", 'main', 'list'
58 append_to menu_items, "[#{I18n.t 'menu.main'}]", 'main', 'list'
58 append_to menu_items, "[#{I18n.t 'menu.messages'}]", 'messages', 'list'
59 append_to menu_items, "[#{I18n.t 'menu.messages'}]", 'messages', 'list'
59
60
60 if (user!=nil) and (GraderConfiguration.show_tasks_to?(user))
61 if (user!=nil) and (GraderConfiguration.show_tasks_to?(user))
61 append_to menu_items, "[#{I18n.t 'menu.tasks'}]", 'tasks', 'list'
62 append_to menu_items, "[#{I18n.t 'menu.tasks'}]", 'tasks', 'list'
62 append_to menu_items, "[#{I18n.t 'menu.submissions'}]", 'main', 'submission'
63 append_to menu_items, "[#{I18n.t 'menu.submissions'}]", 'main', 'submission'
63 append_to menu_items, "[#{I18n.t 'menu.test'}]", 'test', 'index'
64 append_to menu_items, "[#{I18n.t 'menu.test'}]", 'test', 'index'
64 end
65 end
65
66
66 if GraderConfiguration['right.user_hall_of_fame']
67 if GraderConfiguration['right.user_hall_of_fame']
67 append_to menu_items, "[#{I18n.t 'menu.hall_of_fame'}]", 'report', 'problem_hof'
68 append_to menu_items, "[#{I18n.t 'menu.hall_of_fame'}]", 'report', 'problem_hof'
68 end
69 end
69 append_to menu_items, "[#{I18n.t 'menu.help'}]", 'main', 'help'
70 append_to menu_items, "[#{I18n.t 'menu.help'}]", 'main', 'help'
70
71
71 if GraderConfiguration['system.user_setting_enabled']
72 if GraderConfiguration['system.user_setting_enabled']
72 append_to menu_items, "[#{I18n.t 'menu.settings'}]", 'users', 'index'
73 append_to menu_items, "[#{I18n.t 'menu.settings'}]", 'users', 'index'
73 end
74 end
74 append_to menu_items, "[#{I18n.t 'menu.log_out'}]", 'main', 'login'
75 append_to menu_items, "[#{I18n.t 'menu.log_out'}]", 'main', 'login'
75
76
76 menu_items.html_safe
77 menu_items.html_safe
77 end
78 end
78
79
79 def append_to(option,label, controller, action)
80 def append_to(option,label, controller, action)
80 option << ' ' if option!=''
81 option << ' ' if option!=''
81 option << link_to_unless_current(label,
82 option << link_to_unless_current(label,
82 :controller => controller,
83 :controller => controller,
83 :action => action)
84 :action => action)
84 end
85 end
85
86
86 def format_short_time(time)
87 def format_short_time(time)
87 now = Time.now.gmtime
88 now = Time.now.gmtime
88 st = ''
89 st = ''
89 if (time.yday != now.yday) or
90 if (time.yday != now.yday) or
90 (time.year != now.year)
91 (time.year != now.year)
91 st = time.strftime("%x ")
92 st = time.strftime("%x ")
92 end
93 end
93 st + time.strftime("%X")
94 st + time.strftime("%X")
94 end
95 end
95
96
96 def format_short_duration(duration)
97 def format_short_duration(duration)
97 return '' if duration==nil
98 return '' if duration==nil
98 d = duration.to_f
99 d = duration.to_f
99 return Time.at(d).gmtime.strftime("%X")
100 return Time.at(d).gmtime.strftime("%X")
100 end
101 end
101
102
102 def read_textfile(fname,max_size=2048)
103 def read_textfile(fname,max_size=2048)
103 begin
104 begin
104 File.open(fname).read(max_size)
105 File.open(fname).read(max_size)
105 rescue
106 rescue
106 nil
107 nil
107 end
108 end
108 end
109 end
109
110
110 def toggle_button(on,toggle_url,id, option={})
111 def toggle_button(on,toggle_url,id, option={})
111 btn_size = option[:size] || 'btn-xs'
112 btn_size = option[:size] || 'btn-xs'
112 link_to (on ? "Yes" : "No"), toggle_url,
113 link_to (on ? "Yes" : "No"), toggle_url,
113 {class: "btn btn-block #{btn_size} btn-#{on ? 'success' : 'default'} ajax-toggle",
114 {class: "btn btn-block #{btn_size} btn-#{on ? 'success' : 'default'} ajax-toggle",
114 id: id,
115 id: id,
115 data: {remote: true, method: 'get'}}
116 data: {remote: true, method: 'get'}}
116 end
117 end
117
118
118 def get_ace_mode(language)
119 def get_ace_mode(language)
119 # return ace mode string from Language
120 # return ace mode string from Language
120
121
121 case language.pretty_name
122 case language.pretty_name
122 when 'Pascal'
123 when 'Pascal'
123 'ace/mode/pascal'
124 'ace/mode/pascal'
124 when 'C++','C'
125 when 'C++','C'
125 'ace/mode/c_cpp'
126 'ace/mode/c_cpp'
126 when 'Ruby'
127 when 'Ruby'
127 'ace/mode/ruby'
128 'ace/mode/ruby'
128 when 'Python'
129 when 'Python'
129 'ace/mode/python'
130 'ace/mode/python'
130 when 'Java'
131 when 'Java'
131 'ace/mode/java'
132 'ace/mode/java'
132 else
133 else
133 'ace/mode/c_cpp'
134 'ace/mode/c_cpp'
134 end
135 end
135 end
136 end
136
137
137
138
138 def user_title_bar(user)
139 def user_title_bar(user)
139 header = ''
140 header = ''
140 time_left = ''
141 time_left = ''
141
142
142 #
143 #
143 # if the contest is over
144 # if the contest is over
144 if GraderConfiguration.time_limit_mode?
145 if GraderConfiguration.time_limit_mode?
145 if user.contest_finished?
146 if user.contest_finished?
146 header = <<CONTEST_OVER
147 header = <<CONTEST_OVER
147 <tr><td colspan="2" align="center">
148 <tr><td colspan="2" align="center">
148 <span class="contest-over-msg">THE CONTEST IS OVER</span>
149 <span class="contest-over-msg">THE CONTEST IS OVER</span>
149 </td></tr>
150 </td></tr>
150 CONTEST_OVER
151 CONTEST_OVER
151 end
152 end
152 if !user.contest_started?
153 if !user.contest_started?
153 time_left = "&nbsp;&nbsp;" + (t 'title_bar.contest_not_started')
154 time_left = "&nbsp;&nbsp;" + (t 'title_bar.contest_not_started')
154 else
155 else
155 time_left = "&nbsp;&nbsp;" + (t 'title_bar.remaining_time') +
156 time_left = "&nbsp;&nbsp;" + (t 'title_bar.remaining_time') +
156 " #{format_short_duration(user.contest_time_left)}"
157 " #{format_short_duration(user.contest_time_left)}"
157 end
158 end
158 end
159 end
159
160
160 #
161 #
161 # if the contest is in the anaysis mode
162 # if the contest is in the anaysis mode
162 if GraderConfiguration.analysis_mode?
163 if GraderConfiguration.analysis_mode?
163 header = <<ANALYSISMODE
164 header = <<ANALYSISMODE
164 <tr><td colspan="2" align="center">
165 <tr><td colspan="2" align="center">
165 <span class="contest-over-msg">ANALYSIS MODE</span>
166 <span class="contest-over-msg">ANALYSIS MODE</span>
166 </td></tr>
167 </td></tr>
167 ANALYSISMODE
168 ANALYSISMODE
168 end
169 end
169
170
170 contest_name = GraderConfiguration['contest.name']
171 contest_name = GraderConfiguration['contest.name']
171
172
172 #
173 #
173 # build real title bar
174 # build real title bar
174 result = <<TITLEBAR
175 result = <<TITLEBAR
175 <div class="title">
176 <div class="title">
176 <table>
177 <table>
177 #{header}
178 #{header}
178 <tr>
179 <tr>
179 <td class="left-col">
180 <td class="left-col">
180 #{user.full_name}<br/>
181 #{user.full_name}<br/>
181 #{t 'title_bar.current_time'} #{format_short_time(Time.zone.now)}
182 #{t 'title_bar.current_time'} #{format_short_time(Time.zone.now)}
182 #{time_left}
183 #{time_left}
183 <br/>
184 <br/>
184 </td>
185 </td>
185 <td class="right-col">#{contest_name}</td>
186 <td class="right-col">#{contest_name}</td>
186 </tr>
187 </tr>
187 </table>
188 </table>
188 </div>
189 </div>
189 TITLEBAR
190 TITLEBAR
190 result.html_safe
191 result.html_safe
191 end
192 end
192
193
193 def markdown(text)
194 def markdown(text)
194 markdown = RDiscount.new(text)
195 markdown = RDiscount.new(text)
195 markdown.to_html.html_safe
196 markdown.to_html.html_safe
@@ -1,81 +1,82
1 - content_for :head do
1 - content_for :head do
2 <meta http-equiv ="refresh" content="60"/>
2 <meta http-equiv ="refresh" content="60"/>
3
3
4 %h1 Grader information
4 %h1 Grader information
5
5
6 %p
6 %p
7 = link_to 'Refresh', { :action => 'list' }, class: 'btn btn-info'
7 = link_to 'Refresh', { :action => 'list' }, class: 'btn btn-info'
8
8
9 .panel.panel-primary
9 .panel.panel-primary
10 .panel-heading
10 .panel-heading
11 Grader control:
11 Grader control:
12 .panel-body
12 .panel-body
13 =link_to 'Start Graders in grading env', { action: 'start_grading'}, class: 'btn btn-default', method: 'post'
13 =link_to 'Start Graders in grading env', { action: 'start_grading'}, class: 'btn btn-default', method: 'post'
14 =link_to 'Start Graders in exam env', { action: 'start_exam'}, class: 'btn btn-default', method: 'post'
14 =link_to 'Start Graders in exam env', { action: 'start_exam'}, class: 'btn btn-default', method: 'post'
15 =link_to 'Stop all running Graders', { action: 'stop_all'}, class: 'btn btn-default', method: 'post'
15 =link_to 'Stop all running Graders', { action: 'stop_all'}, class: 'btn btn-default', method: 'post'
16 =link_to 'Clear all data', { action: 'clear_all'}, class: 'btn btn-default', method: 'post'
16 =link_to 'Clear all data', { action: 'clear_all'}, class: 'btn btn-default', method: 'post'
17
17
18 - .submitbox
19 - .item
20 - Grader control:
21 - .item
22 - = form_for :clear, :url => {:action => 'start_grading'} do |f|
23 - = submit_tag 'Start graders in grading env'
24 - .item
25 - = form_for :clear, :url => {:action => 'start_exam'} do |f|
26 - = submit_tag 'Start graders in exam env'
27 - .item
28 - = form_for :clear, :url => {:action => 'stop_all'} do |f|
29 - = submit_tag 'Stop all running graders'
30 - .item
31 - = form_for :clear, :url => {:action => 'clear_all'} do |f|
32 - = submit_tag 'Clear all data'
33 - %br{:style => 'clear:both'}/
34 -
35 .row
18 .row
36 .col-md-6
19 .col-md-6
37 - if @last_task
20 - if @last_task
38 Last task:
21 Last task:
39 = link_to "#{@last_task.id}", :action => 'view', :id => @last_task.id, :type => 'Task'
22 = link_to "#{@last_task.id}", :action => 'view', :id => @last_task.id, :type => 'Task'
40
23
41 %br/
24 %br/
42
25
43 - if @last_test_request
26 - if @last_test_request
44 Last test_request:
27 Last test_request:
45 = link_to "#{@last_test_request.id}", :action => 'view', :id => @last_test_request.id, :type => 'TestRequest'
28 = link_to "#{@last_test_request.id}", :action => 'view', :id => @last_test_request.id, :type => 'TestRequest'
46
29
47 %h2 Current graders
30 %h2 Current graders
48
31
49 = render :partial => 'grader_list', :locals => {:grader_list => @grader_processes}
32 = render :partial => 'grader_list', :locals => {:grader_list => @grader_processes}
50
33
51 %h2 Stalled graders
34 %h2 Stalled graders
52
35
53 = render :partial => 'grader_list', :locals => {:grader_list => @stalled_processes}
36 = render :partial => 'grader_list', :locals => {:grader_list => @stalled_processes}
54
37
55 %h2 Terminated graders
38 %h2 Terminated graders
56
39
57 %p= link_to 'Clear data for terminated graders', { action: 'clear_terminated'}, class: 'btn btn-default', method: 'post'
40 %p= link_to 'Clear data for terminated graders', { action: 'clear_terminated'}, class: 'btn btn-default', method: 'post'
58
41
59 = render :partial => 'grader_list', :locals => {:grader_list => @terminated_processes}
42 = render :partial => 'grader_list', :locals => {:grader_list => @terminated_processes}
60 .col-md-6
43 .col-md-6
61 %h2 Last 20 submissions
44 %h2 Last 20 submissions
62 %table.table.table-striped.table-condensed
45 %table.table.table-striped.table-condensed
63 %thead
46 %thead
64 %th ID
47 %th ID
65 %th User
48 %th User
66 %th Problem
49 %th Problem
67 %th Submitted
50 %th Submitted
68 %th Graded
51 %th Graded
69 %th Result
52 %th Result
70 - %th
71 %tbody
53 %tbody
72 - @submission.each do |sub|
54 - @submission.each do |sub|
73 %tr.inactive
55 %tr.inactive
74 %td= link_to sub.id, controller: 'graders' ,action: 'submission', id: sub.id
56 %td= link_to sub.id, controller: 'graders' ,action: 'submission', id: sub.id
75 %td= sub.try(:user).try(:full_name)
57 %td= sub.try(:user).try(:full_name)
76 %td= sub.try(:problem).try(:full_name)
58 %td= sub.try(:problem).try(:full_name)
77 %td= "#{time_ago_in_words(sub.submitted_at)} ago"
59 %td= "#{time_ago_in_words(sub.submitted_at)} ago"
78 %td= sub.graded_at ? "#{time_ago_in_words(sub.graded_at)} ago" : " "
60 %td= sub.graded_at ? "#{time_ago_in_words(sub.graded_at)} ago" : " "
79 %td= sub.grader_comment
61 %td= sub.grader_comment
62 + %h2 Ungraded submission
63 + %table.table.table-striped.table-condensed
64 + %thead
65 + %th ID
66 + %th User
67 + %th Problem
68 + %th Submitted
69 + %th Graded
70 + %th Result
71 + %tbody
72 + - @backlog_submission.each do |sub|
73 + %tr.inactive
74 + %td= link_to sub.id, controller: 'graders' ,action: 'submission', id: sub.id
75 + %td= sub.try(:user).try(:full_name)
76 + %td= sub.try(:problem).try(:full_name)
77 + %td= "#{time_ago_in_words(sub.submitted_at)} ago"
78 + %td= sub.graded_at ? "#{time_ago_in_words(sub.graded_at)} ago" : " "
79 + %td= sub.grader_comment
80
80
81
81
82 +
You need to be logged in to leave comments. Login now