Description:
- clean up link to problem stat and user stat
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r606:7b10ea3e4720 - - 6 files changed: 15 inserted, 13 deleted

@@ -16,193 +16,193
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(:base,"Email cannot be blank") if @user.email==''
66 @user.errors.add(: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 stat
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 next unless sub.problem
128 problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max
128 problem[sub.problem] = [problem[sub.problem], ( (sub.try(:points) || 0) >= sub.problem.full_score) ? 1 : 0].max
129 end
129 end
130
130
131 @histogram[:summary][:max] = [@histogram[:data].max,1].max
131 @histogram[:summary][:max] = [@histogram[:data].max,1].max
132 @summary[:attempt] = problem.count
132 @summary[:attempt] = problem.count
133 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
133 problem.each_value { |v| @summary[:solve] += 1 if v == 1 }
134 end
134 end
135
135
136 def toggle_activate
136 def toggle_activate
137 @user = User.find(params[:id])
137 @user = User.find(params[:id])
138 @user.update_attributes( activated: !@user.activated? )
138 @user.update_attributes( activated: !@user.activated? )
139 respond_to do |format|
139 respond_to do |format|
140 format.js { render partial: 'toggle_button',
140 format.js { render partial: 'toggle_button',
141 locals: {button_id: "#toggle_activate_user_#{@user.id}",button_on: @user.activated? } }
141 locals: {button_id: "#toggle_activate_user_#{@user.id}",button_on: @user.activated? } }
142 end
142 end
143 end
143 end
144
144
145 def toggle_enable
145 def toggle_enable
146 @user = User.find(params[:id])
146 @user = User.find(params[:id])
147 @user.update_attributes( enabled: !@user.enabled? )
147 @user.update_attributes( enabled: !@user.enabled? )
148 respond_to do |format|
148 respond_to do |format|
149 format.js { render partial: 'toggle_button',
149 format.js { render partial: 'toggle_button',
150 locals: {button_id: "#toggle_enable_user_#{@user.id}",button_on: @user.enabled? } }
150 locals: {button_id: "#toggle_enable_user_#{@user.id}",button_on: @user.enabled? } }
151 end
151 end
152 end
152 end
153
153
154 protected
154 protected
155
155
156 def verify_online_registration
156 def verify_online_registration
157 if !GraderConfiguration['system.online_registration']
157 if !GraderConfiguration['system.online_registration']
158 redirect_to :controller => 'main', :action => 'login'
158 redirect_to :controller => 'main', :action => 'login'
159 end
159 end
160 end
160 end
161
161
162 def send_confirmation_email(user)
162 def send_confirmation_email(user)
163 contest_name = GraderConfiguration['contest.name']
163 contest_name = GraderConfiguration['contest.name']
164 activation_url = url_for(:action => 'confirm',
164 activation_url = url_for(:action => 'confirm',
165 :login => user.login,
165 :login => user.login,
166 :activation => user.activation_key)
166 :activation => user.activation_key)
167 home_url = url_for(:controller => 'main', :action => 'index')
167 home_url = url_for(:controller => 'main', :action => 'index')
168 mail_subject = "[#{contest_name}] Confirmation"
168 mail_subject = "[#{contest_name}] Confirmation"
169 mail_body = t('registration.email_body', {
169 mail_body = t('registration.email_body', {
170 :full_name => user.full_name,
170 :full_name => user.full_name,
171 :contest_name => contest_name,
171 :contest_name => contest_name,
172 :login => user.login,
172 :login => user.login,
173 :password => user.password,
173 :password => user.password,
174 :activation_url => activation_url,
174 :activation_url => activation_url,
175 :admin_email => GraderConfiguration['system.admin_email']
175 :admin_email => GraderConfiguration['system.admin_email']
176 })
176 })
177
177
178 logger.info mail_body
178 logger.info mail_body
179
179
180 send_mail(user.email, mail_subject, mail_body)
180 send_mail(user.email, mail_subject, mail_body)
181 end
181 end
182
182
183 def send_new_password_email(user)
183 def send_new_password_email(user)
184 contest_name = GraderConfiguration['contest.name']
184 contest_name = GraderConfiguration['contest.name']
185 mail_subject = "[#{contest_name}] Password recovery"
185 mail_subject = "[#{contest_name}] Password recovery"
186 mail_body = t('registration.password_retrieval.email_body', {
186 mail_body = t('registration.password_retrieval.email_body', {
187 :full_name => user.full_name,
187 :full_name => user.full_name,
188 :contest_name => contest_name,
188 :contest_name => contest_name,
189 :login => user.login,
189 :login => user.login,
190 :password => user.password,
190 :password => user.password,
191 :admin_email => GraderConfiguration['system.admin_email']
191 :admin_email => GraderConfiguration['system.admin_email']
192 })
192 })
193
193
194 logger.info mail_body
194 logger.info mail_body
195
195
196 send_mail(user.email, mail_subject, mail_body)
196 send_mail(user.email, mail_subject, mail_body)
197 end
197 end
198
198
199 # allow viewing of regular user profile only when options allow so
199 # allow viewing of regular user profile only when options allow so
200 # only admins can view admins profile
200 # only admins can view admins profile
201 def profile_authorization
201 def profile_authorization
202 #if view admins' profile, allow only admin
202 #if view admins' profile, allow only admin
203 return false unless(params[:id])
203 return false unless(params[:id])
204 user = User.find(params[:id])
204 user = User.find(params[:id])
205 return false unless user
205 return false unless user
206 return admin_authorization if user.admin?
206 return admin_authorization if user.admin?
207 return true if GraderConfiguration["right.user_view_submission"]
207 return true if GraderConfiguration["right.user_view_submission"]
208
208
@@ -1,82 +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 .row
18 .row
19 .col-md-6
19 .col-md-6
20 - if @last_task
20 - if @last_task
21 Last task:
21 Last task:
22 = 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'
23
23
24 %br/
24 %br/
25
25
26 - if @last_test_request
26 - if @last_test_request
27 Last test_request:
27 Last test_request:
28 = 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'
29
29
30 %h2 Current graders
30 %h2 Current graders
31
31
32 = render :partial => 'grader_list', :locals => {:grader_list => @grader_processes}
32 = render :partial => 'grader_list', :locals => {:grader_list => @grader_processes}
33
33
34 %h2 Stalled graders
34 %h2 Stalled graders
35
35
36 = render :partial => 'grader_list', :locals => {:grader_list => @stalled_processes}
36 = render :partial => 'grader_list', :locals => {:grader_list => @stalled_processes}
37
37
38 %h2 Terminated graders
38 %h2 Terminated graders
39
39
40 %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'
41
41
42 = render :partial => 'grader_list', :locals => {:grader_list => @terminated_processes}
42 = render :partial => 'grader_list', :locals => {:grader_list => @terminated_processes}
43 .col-md-6
43 .col-md-6
44 %h2 Last 20 submissions
44 %h2 Last 20 submissions
45 %table.table.table-striped.table-condensed
45 %table.table.table-striped.table-condensed
46 %thead
46 %thead
47 %th ID
47 %th ID
48 %th User
48 %th User
49 %th Problem
49 %th Problem
50 %th Submitted
50 %th Submitted
51 %th Graded
51 %th Graded
52 %th Result
52 %th Result
53 %tbody
53 %tbody
54 - @submission.each do |sub|
54 - @submission.each do |sub|
55 %tr.inactive
55 %tr.inactive
56 - %td= link_to sub.id, controller: 'graders' ,action: 'submission', id: sub.id
56 + %td= link_to sub.id, submission_path(sub.id)
57 - %td= sub.try(:user).try(:full_name)
57 + %td= link_to sub.try(:user).try(:full_name), stat_user_path(sub.user.id)
58 - %td= sub.try(:problem).try(:full_name)
58 + %td= link_to sub.try(:problem).try(:full_name), stat_problem_path(sub.problem.id)
59 %td= "#{time_ago_in_words(sub.submitted_at)} ago"
59 %td= "#{time_ago_in_words(sub.submitted_at)} ago"
60 %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" : " "
61 %td= sub.grader_comment
61 %td= sub.grader_comment
62 %h2 Ungraded submission
62 %h2 Ungraded submission
63 %table.table.table-striped.table-condensed
63 %table.table.table-striped.table-condensed
64 %thead
64 %thead
65 %th ID
65 %th ID
66 %th User
66 %th User
67 %th Problem
67 %th Problem
68 %th Submitted
68 %th Submitted
69 %th Graded
69 %th Graded
70 %th Result
70 %th Result
71 %tbody
71 %tbody
72 - @backlog_submission.each do |sub|
72 - @backlog_submission.each do |sub|
73 %tr.inactive
73 %tr.inactive
74 - %td= link_to sub.id, controller: 'graders' ,action: 'submission', id: sub.id
74 + %td= link_to sub.id, submission_path(sub.id)
75 - %td= sub.try(:user).try(:full_name)
75 + %td= link_to sub.try(:user).try(:full_name), stat_user_path(sub.user.id)
76 - %td= sub.try(:problem).try(:full_name)
76 + %td= link_to sub.try(:problem).try(:full_name), stat_problem_path(sub.problem.id)
77 %td= "#{time_ago_in_words(sub.submitted_at)} ago"
77 %td= "#{time_ago_in_words(sub.submitted_at)} ago"
78 %td= sub.graded_at ? "#{time_ago_in_words(sub.graded_at)} ago" : " "
78 %td= sub.graded_at ? "#{time_ago_in_words(sub.graded_at)} ago" : " "
79 %td= sub.grader_comment
79 %td= sub.grader_comment
80
80
81
81
82
82
@@ -1,53 +1,53
1 :css
1 :css
2 .fix-width {
2 .fix-width {
3 font-family: "Consolas, Monaco, Droid Sans Mono,Mono, Monospace,Courier"
3 font-family: "Consolas, Monaco, Droid Sans Mono,Mono, Monospace,Courier"
4 }
4 }
5
5
6 %h1 Problem stat: #{@problem.name}
6 %h1 Problem stat: #{@problem.name}
7 %h2 Overview
7 %h2 Overview
8
8
9
9
10 %table.info
10 %table.info
11 %thead
11 %thead
12 %tr.info-head
12 %tr.info-head
13 %th Stat
13 %th Stat
14 %th Value
14 %th Value
15 %tbody
15 %tbody
16 %tr{class: cycle('info-even','info-odd')}
16 %tr{class: cycle('info-even','info-odd')}
17 %td Submissions
17 %td Submissions
18 %td= @submissions.count
18 %td= @submissions.count
19 %tr{class: cycle('info-even','info-odd')}
19 %tr{class: cycle('info-even','info-odd')}
20 %td Solved/Attempted User
20 %td Solved/Attempted User
21 %td #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
21 %td #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
22
22
23 %h2 Submissions Count
23 %h2 Submissions Count
24 = render partial: 'application/bar_graph', locals: { histogram: @histogram }
24 = render partial: 'application/bar_graph', locals: { histogram: @histogram }
25
25
26 %h2 Submissions
26 %h2 Submissions
27 - if @submissions and @submissions.count > 0
27 - if @submissions and @submissions.count > 0
28 %table.info#main_table
28 %table.info#main_table
29 %thead
29 %thead
30 %tr.info-head
30 %tr.info-head
31 %th ID
31 %th ID
32 %th Login
32 %th Login
33 %th Name
33 %th Name
34 %th Submitted_at
34 %th Submitted_at
35 %th Points
35 %th Points
36 %th comment
36 %th comment
37 %th IP
37 %th IP
38 %tbody
38 %tbody
39 - row_odd,curr = true,''
39 - row_odd,curr = true,''
40 - @submissions.each do |sub|
40 - @submissions.each do |sub|
41 - next unless sub.user
41 - next unless sub.user
42 - row_odd,curr = !row_odd, sub.user if curr != sub.user
42 - row_odd,curr = !row_odd, sub.user if curr != sub.user
43 %tr{class: row_odd ? "info-odd" : "info-even"}
43 %tr{class: row_odd ? "info-odd" : "info-even"}
44 - %td= link_to sub.id, controller: 'graders', action: 'submission', id: sub.id
44 + %td= link_to sub.id, submission_path(sub)
45 - %td= link_to sub.user.login, controller: :users, action: :profile, id: sub.user.id
45 + %td= link_to sub.user.login, stat_user_path(sub.user)
46 %td= sub.user.full_name
46 %td= sub.user.full_name
47 %td= time_ago_in_words(sub.submitted_at) + " ago"
47 %td= time_ago_in_words(sub.submitted_at) + " ago"
48 %td= sub.points
48 %td= sub.points
49 %td.fix-width= sub.grader_comment
49 %td.fix-width= sub.grader_comment
50 %td= sub.ip_address
50 %td= sub.ip_address
51 - else
51 - else
52 No submission
52 No submission
53
53
@@ -1,84 +1,84
1 %h1= "Submission: #{@submission.id}"
1 %h1= "Submission: #{@submission.id}"
2
2
3 %textarea#data{style: "display:none;"}
3 %textarea#data{style: "display:none;"}
4 :preserve
4 :preserve
5 #{@submission.source}
5 #{@submission.source}
6
6
7 //%div.highlight{:style => "border: 1px solid black;"}
7 //%div.highlight{:style => "border: 1px solid black;"}
8 //=@formatted_code.html_safe
8 //=@formatted_code.html_safe
9 .containter
9 .containter
10 .row
10 .row
11 .col-md-7
11 .col-md-7
12 %h2 Source Code
12 %h2 Source Code
13 .col-md-5
13 .col-md-5
14 %h2 Stat
14 %h2 Stat
15 .row
15 .row
16 .col-md-7
16 .col-md-7
17 %div#editor{ style: "font-size: 14px; height: 400px; border-radius:5px;" }
17 %div#editor{ style: "font-size: 14px; height: 400px; border-radius:5px;" }
18 :javascript
18 :javascript
19 e = ace.edit("editor")
19 e = ace.edit("editor")
20 e.setOptions({ maxLines: Infinity })
20 e.setOptions({ maxLines: Infinity })
21 e.setValue($("#data").text())
21 e.setValue($("#data").text())
22 e.gotoLine(1)
22 e.gotoLine(1)
23 e.getSession().setMode("#{get_ace_mode(@submission.language)}")
23 e.getSession().setMode("#{get_ace_mode(@submission.language)}")
24 e.setReadOnly(true)
24 e.setReadOnly(true)
25 .col-md-5
25 .col-md-5
26 %table.table.table-striped
26 %table.table.table-striped
27 %tr
27 %tr
28 %td.text-right
28 %td.text-right
29 %strong User
29 %strong User
30 %td
30 %td
31 - if @submission.user
31 - if @submission.user
32 - = link_to "(#{@submission.user.login})", controller: "users", action: "profile", id: @submission.user
32 + = link_to "#{@submission.user.login}", stat_user_path(@submission.user)
33 = @submission.user.full_name
33 = @submission.user.full_name
34 - else
34 - else
35 = "(n/a)"
35 = "(n/a)"
36 %tr
36 %tr
37 %td.text-right
37 %td.text-right
38 %strong Task
38 %strong Task
39 %td
39 %td
40 - if @submission.problem!=nil
40 - if @submission.problem!=nil
41 - = link_to "(#{@submission.problem.name})", controller: "problems", action: "stat", id: @submission.problem
41 + = link_to "[#{@submission.problem.name}]", stat_problem_path(@submission.problem)
42 = @submission.problem.full_name
42 = @submission.problem.full_name
43 - else
43 - else
44 = "(n/a)"
44 = "(n/a)"
45 %tr
45 %tr
46 %td.text-right
46 %td.text-right
47 %strong Tries
47 %strong Tries
48 %td= @submission.number
48 %td= @submission.number
49 %tr
49 %tr
50 %td.text-right
50 %td.text-right
51 %strong Language
51 %strong Language
52 %td= @submission.language.pretty_name
52 %td= @submission.language.pretty_name
53 %tr
53 %tr
54 %td.text-right
54 %td.text-right
55 %strong Submitted
55 %strong Submitted
56 %td #{time_ago_in_words(@submission.submitted_at)} ago (at #{@submission.submitted_at.to_formatted_s(:long)})
56 %td #{time_ago_in_words(@submission.submitted_at)} ago (at #{@submission.submitted_at.to_formatted_s(:long)})
57 %tr
57 %tr
58 %td.text-right
58 %td.text-right
59 %strong Graded
59 %strong Graded
60 - if @submission.graded_at
60 - if @submission.graded_at
61 %td #{time_ago_in_words(@submission.graded_at)} ago (at #{@submission.graded_at.to_formatted_s(:long)})
61 %td #{time_ago_in_words(@submission.graded_at)} ago (at #{@submission.graded_at.to_formatted_s(:long)})
62 - else
62 - else
63 %td -
63 %td -
64 %tr
64 %tr
65 %td.text-right
65 %td.text-right
66 %strong Points
66 %strong Points
67 %td #{@submission.points}/#{@submission.problem.full_score}
67 %td #{@submission.points}/#{@submission.problem.full_score}
68 %tr
68 %tr
69 %td.text-right
69 %td.text-right
70 %strong Comment
70 %strong Comment
71 %td #{@submission.grader_comment}
71 %td #{@submission.grader_comment}
72 %tr
72 %tr
73 %td.text-right
73 %td.text-right
74 %strong Runtime (s)
74 %strong Runtime (s)
75 %td #{@submission.max_runtime}
75 %td #{@submission.max_runtime}
76 %tr
76 %tr
77 %td.text-right
77 %td.text-right
78 %strong Memory (kb)
78 %strong Memory (kb)
79 %td #{@submission.peak_memory}
79 %td #{@submission.peak_memory}
80 - if session[:admin]
80 - if session[:admin]
81 %tr
81 %tr
82 %td.text-right
82 %td.text-right
83 %strong IP
83 %strong IP
84 %td #{@submission.ip_address}
84 %td #{@submission.ip_address}
@@ -1,66 +1,66
1 - content_for :header do
1 - content_for :header do
2 = javascript_include_tag 'local_jquery'
2 = javascript_include_tag 'local_jquery'
3
3
4 :javascript
4 :javascript
5 $(function () {
5 $(function () {
6 $('#submission_table').tablesorter({widgets: ['zebra']});
6 $('#submission_table').tablesorter({widgets: ['zebra']});
7 });
7 });
8
8
9 :css
9 :css
10 .fix-width {
10 .fix-width {
11 font-family: Droid Sans Mono,Consolas, monospace, mono, Courier New, Courier;
11 font-family: Droid Sans Mono,Consolas, monospace, mono, Courier New, Courier;
12 }
12 }
13
13
14 %h1= @user.full_name
14 %h1= @user.full_name
15
15
16 <b>Login:</b> #{@user.login} <br/>
16 <b>Login:</b> #{@user.login} <br/>
17 <b>Full name:</b> #{@user.full_name} <br />
17 <b>Full name:</b> #{@user.full_name} <br />
18
18
19
19
20 %h2 Problem Stat
20 %h2 Problem Stat
21 %table.info
21 %table.info
22 %thead
22 %thead
23 %tr.info-head
23 %tr.info-head
24 %th Stat
24 %th Stat
25 %th Value
25 %th Value
26 %tbody
26 %tbody
27 %tr{class: cycle('info-even','info-odd')}
27 %tr{class: cycle('info-even','info-odd')}
28 %td.info_param Submissions
28 %td.info_param Submissions
29 %td= @summary[:count]
29 %td= @summary[:count]
30 %tr{class: cycle('info-even','info-odd')}
30 %tr{class: cycle('info-even','info-odd')}
31 %td.info_param Solved/Attempted Problem
31 %td.info_param Solved/Attempted Problem
32 %td #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
32 %td #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
33
33
34 %h2 Submission History
34 %h2 Submission History
35
35
36 =render partial: 'application/bar_graph', locals: {histogram: @histogram, param: {bar_width: 7}}
36 =render partial: 'application/bar_graph', locals: {histogram: @histogram, param: {bar_width: 7}}
37
37
38
38
39 %table.tablesorter-cafe#submission_table
39 %table.tablesorter-cafe#submission_table
40 %thead
40 %thead
41 %tr
41 %tr
42 %th ID
42 %th ID
43 %th Problem code
43 %th Problem code
44 %th Problem full name
44 %th Problem full name
45 %th Language
45 %th Language
46 %th Submitted at
46 %th Submitted at
47 %th Result
47 %th Result
48 %th Score
48 %th Score
49 - if session[:admin]
49 - if session[:admin]
50 %th IP
50 %th IP
51 %tbody
51 %tbody
52 - @submission.each do |s|
52 - @submission.each do |s|
53 - next unless s.problem
53 - next unless s.problem
54 %tr
54 %tr
55 - %td= link_to "#{s.id}", controller: "graders", action: "submission", id: s.id
55 + %td= link_to s.id, submission_path(s)
56 - %td= link_to s.problem.name, controller: "problems", action: "stat", id: s.problem
56 + %td= link_to s.problem.name, stat_problem_path(s.problem)
57 %td= s.problem.full_name
57 %td= s.problem.full_name
58 %td= s.language.pretty_name
58 %td= s.language.pretty_name
59 %td #{s.submitted_at.strftime('%Y-%m-%d %H:%M')} (#{time_ago_in_words(s.submitted_at)} ago)
59 %td #{s.submitted_at.strftime('%Y-%m-%d %H:%M')} (#{time_ago_in_words(s.submitted_at)} ago)
60 %td.fix-width= s.grader_comment
60 %td.fix-width= s.grader_comment
61 %td= ( s.try(:points) ? (s.points*100/s.problem.full_score) : '' )
61 %td= ( s.try(:points) ? (s.points*100/s.problem.full_score) : '' )
62 - if session[:admin]
62 - if session[:admin]
63 %td= s.ip_address
63 %td= s.ip_address
64
64
65
65
66
66
@@ -1,71 +1,73
1 CafeGrader::Application.routes.draw do
1 CafeGrader::Application.routes.draw do
2 get "sources/direct_edit"
2 get "sources/direct_edit"
3
3
4 root :to => 'main#login'
4 root :to => 'main#login'
5
5
6 resources :contests
6 resources :contests
7
7
8 resources :sites
8 resources :sites
9
9
10 resources :announcements do
10 resources :announcements do
11 member do
11 member do
12 get 'toggle','toggle_front'
12 get 'toggle','toggle_front'
13 end
13 end
14 end
14 end
15
15
16 resources :problems do
16 resources :problems do
17 member do
17 member do
18 get 'toggle'
18 get 'toggle'
19 get 'toggle_test'
19 get 'toggle_test'
20 + get 'stat'
20 end
21 end
21 collection do
22 collection do
22 get 'turn_all_off'
23 get 'turn_all_off'
23 get 'turn_all_on'
24 get 'turn_all_on'
24 get 'import'
25 get 'import'
25 get 'manage'
26 get 'manage'
26 end
27 end
27 end
28 end
28
29
29 resources :grader_configuration, controller: 'configurations'
30 resources :grader_configuration, controller: 'configurations'
30
31
31 resources :users do
32 resources :users do
32 member do
33 member do
33 get 'toggle_activate', 'toggle_enable'
34 get 'toggle_activate', 'toggle_enable'
35 + get 'stat'
34 end
36 end
35 end
37 end
36
38
37 resources :submissions do
39 resources :submissions do
38 collection do
40 collection do
39 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
41 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
40 get 'direct_edit_problem/:problem_id', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
42 get 'direct_edit_problem/:problem_id', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
41 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
43 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
42 end
44 end
43 end
45 end
44
46
45 match 'tasks/view/:file.:ext' => 'tasks#view'
47 match 'tasks/view/:file.:ext' => 'tasks#view'
46 match 'tasks/download/:id/:file.:ext' => 'tasks#download'
48 match 'tasks/download/:id/:file.:ext' => 'tasks#download'
47 match 'heartbeat/:id/edit' => 'heartbeat#edit'
49 match 'heartbeat/:id/edit' => 'heartbeat#edit'
48
50
49 #main
51 #main
50 get "main/list"
52 get "main/list"
51 get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
53 get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
52
54
53 #report
55 #report
54 get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
56 get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
55 get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
57 get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
56 get "report/login"
58 get "report/login"
57 get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
59 get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
58 post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
60 post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
59
61
60 #grader
62 #grader
61 get 'graders/list', to: 'graders#list', as: 'grader_list'
63 get 'graders/list', to: 'graders#list', as: 'grader_list'
62
64
63
65
64 match 'heartbeat/:id/edit' => 'heartbeat#edit'
66 match 'heartbeat/:id/edit' => 'heartbeat#edit'
65
67
66 # See how all your routes lay out with "rake routes"
68 # See how all your routes lay out with "rake routes"
67
69
68 # This is a legacy wild controller route that's not recommended for RESTful applications.
70 # This is a legacy wild controller route that's not recommended for RESTful applications.
69 # Note: This route will make all actions in every controller accessible via GET requests.
71 # Note: This route will make all actions in every controller accessible via GET requests.
70 match ':controller(/:action(/:id))(.:format)'
72 match ':controller(/:action(/:id))(.:format)'
71 end
73 end
You need to be logged in to leave comments. Login now