Description:
add user profile page listing all submission, permission is by 'right.user_view_submission' add link from users to their profile page
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r431:7654a9f33bc8 - - 6 files changed: 92 inserted, 14 deleted

@@ -0,0 +1,40
1 + - content_for :header do
2 + = javascript_include_tag 'new'
3 +
4 + %script{:type=>"text/javascript"}
5 + $(function () {
6 + $('#submission_table').tablesorter({widgets: ['zebra','filter']});
7 + });
8 +
9 + %h1= @user.full_name + ' Profile'
10 +
11 + %h2 Basic info
12 + <b>Login:</b> #{@user.login} <br/>
13 + <b>Full name:</b> #{@user.full_name} <br />
14 +
15 +
16 + %h2 Problem Stat
17 +
18 + %h2 Submissions
19 +
20 + %table.tablesorter-cafe#submission_table
21 + %thead
22 + %tr
23 + %th ID
24 + %th Problem code
25 + %th Problem name
26 + %th Language
27 + %th Result
28 + %th Score
29 + %tbody
30 + - @submission.each do |s|
31 + %tr
32 + %td= link_to "#{s.id}", controller: "graders", action: "submission", id: s.id
33 + %td= s.problem.name
34 + %td= s.problem.full_name
35 + %td= s.language.pretty_name
36 + %td{style: 'font-family: Droid Sans Mono,Consolas, monospace, mono'}= s.grader_comment
37 + %td= s.points/s.problem.full_score * 100
38 +
39 +
40 +
@@ -1,188 +1,189
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 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
19 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
20 rescue
20 rescue
21 @since_time = DateTime.new(1000,1,1)
21 @since_time = DateTime.new(1000,1,1)
22 end
22 end
23 begin
23 begin
24 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
24 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
25 rescue
25 rescue
26 @until_time = DateTime.new(3000,1,1)
26 @until_time = DateTime.new(3000,1,1)
27 end
27 end
28
28
29 User.all.each do |user|
29 User.all.each do |user|
30 - @logins << { login: user.login,
30 + @logins << { id: user.id,
31 + login: user.login,
31 full_name: user.full_name,
32 full_name: user.full_name,
32 count: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
33 count: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
33 user.id,@since_time,@until_time)
34 user.id,@since_time,@until_time)
34 .count(:id),
35 .count(:id),
35 min: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
36 min: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
36 user.id,@since_time,@until_time)
37 user.id,@since_time,@until_time)
37 .minimum(:created_at),
38 .minimum(:created_at),
38 max: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
39 max: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
39 user.id,@since_time,@until_time)
40 user.id,@since_time,@until_time)
40 .maximum(:created_at)
41 .maximum(:created_at)
41 }
42 }
42 end
43 end
43 end
44 end
44
45
45 def submission_stat
46 def submission_stat
46
47
47 date_and_time = '%Y-%m-%d %H:%M'
48 date_and_time = '%Y-%m-%d %H:%M'
48 begin
49 begin
49 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
50 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
50 rescue
51 rescue
51 @since_time = DateTime.new(1000,1,1)
52 @since_time = DateTime.new(1000,1,1)
52 end
53 end
53 begin
54 begin
54 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
55 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
55 rescue
56 rescue
56 @until_time = DateTime.new(3000,1,1)
57 @until_time = DateTime.new(3000,1,1)
57 end
58 end
58
59
59 @submissions = {}
60 @submissions = {}
60
61
61 User.find_each do |user|
62 User.find_each do |user|
62 @submissions[user.id] = { login: user.login, full_name: user.full_name, count: 0, sub: { } }
63 @submissions[user.id] = { login: user.login, full_name: user.full_name, count: 0, sub: { } }
63 end
64 end
64
65
65 Submission.where("submitted_at >= ? AND submitted_at <= ?",@since_time,@until_time).find_each do |s|
66 Submission.where("submitted_at >= ? AND submitted_at <= ?",@since_time,@until_time).find_each do |s|
66 if @submissions[s.user_id]
67 if @submissions[s.user_id]
67 if not @submissions[s.user_id][:sub].has_key?(s.problem_id)
68 if not @submissions[s.user_id][:sub].has_key?(s.problem_id)
68 a = nil
69 a = nil
69 begin
70 begin
70 a = Problem.find(s.problem_id)
71 a = Problem.find(s.problem_id)
71 rescue
72 rescue
72 a = nil
73 a = nil
73 end
74 end
74 @submissions[s.user_id][:sub][s.problem_id] =
75 @submissions[s.user_id][:sub][s.problem_id] =
75 { prob_name: (a ? a.full_name : '(NULL)'),
76 { prob_name: (a ? a.full_name : '(NULL)'),
76 sub_ids: [s.id] }
77 sub_ids: [s.id] }
77 else
78 else
78 @submissions[s.user_id][:sub][s.problem_id][:sub_ids] << s.id
79 @submissions[s.user_id][:sub][s.problem_id][:sub_ids] << s.id
79 end
80 end
80 @submissions[s.user_id][:count] += 1
81 @submissions[s.user_id][:count] += 1
81 end
82 end
82 end
83 end
83 end
84 end
84
85
85 def problem_hof
86 def problem_hof
86 # gen problem list
87 # gen problem list
87 @user = User.find(session[:user_id])
88 @user = User.find(session[:user_id])
88 @problems = @user.available_problems
89 @problems = @user.available_problems
89
90
90 # get selected problems or the default
91 # get selected problems or the default
91 if params[:id]
92 if params[:id]
92 begin
93 begin
93 @problem = Problem.available.find(params[:id])
94 @problem = Problem.available.find(params[:id])
94 rescue
95 rescue
95 redirect_to action: :problem_hof
96 redirect_to action: :problem_hof
96 flash[:notice] = 'Error: submissions for that problem are not viewable.'
97 flash[:notice] = 'Error: submissions for that problem are not viewable.'
97 return
98 return
98 end
99 end
99 end
100 end
100
101
101 if @problem
102 if @problem
102 #aggregrate by language
103 #aggregrate by language
103 @by_lang = {}
104 @by_lang = {}
104 Submission.where(problem_id: @problem.id).find_each do |sub|
105 Submission.where(problem_id: @problem.id).find_each do |sub|
105 lang = Language.find_by_id(sub.language_id)
106 lang = Language.find_by_id(sub.language_id)
106 next unless lang
107 next unless lang
107 next unless sub.points >= @problem.full_score
108 next unless sub.points >= @problem.full_score
108
109
109 #initialize
110 #initialize
110 unless @by_lang.has_key?(lang.pretty_name)
111 unless @by_lang.has_key?(lang.pretty_name)
111 @by_lang[lang.pretty_name] = {
112 @by_lang[lang.pretty_name] = {
112 runtime: { avail: false, value: 2**30-1 },
113 runtime: { avail: false, value: 2**30-1 },
113 memory: { avail: false, value: 2**30-1 },
114 memory: { avail: false, value: 2**30-1 },
114 length: { avail: false, value: 2**30-1 },
115 length: { avail: false, value: 2**30-1 },
115 first: { avail: false, value: DateTime.new(3000,1,1) }
116 first: { avail: false, value: DateTime.new(3000,1,1) }
116 }
117 }
117 end
118 end
118
119
119 if sub.max_runtime and sub.max_runtime < @by_lang[lang.pretty_name][:runtime][:value]
120 if sub.max_runtime and sub.max_runtime < @by_lang[lang.pretty_name][:runtime][:value]
120 @by_lang[lang.pretty_name][:runtime] = {
121 @by_lang[lang.pretty_name][:runtime] = {
121 avail: true,
122 avail: true,
122 user_id: sub.user_id,
123 user_id: sub.user_id,
123 value: sub.max_runtime,
124 value: sub.max_runtime,
124 sub_id: sub.id
125 sub_id: sub.id
125 }
126 }
126 end
127 end
127
128
128 if sub.peak_memory and sub.peak_memory < @by_lang[lang.pretty_name][:memory][:value]
129 if sub.peak_memory and sub.peak_memory < @by_lang[lang.pretty_name][:memory][:value]
129 @by_lang[lang.pretty_name][:memory] = {
130 @by_lang[lang.pretty_name][:memory] = {
130 avail: true,
131 avail: true,
131 user_id: sub.user_id,
132 user_id: sub.user_id,
132 value: sub.peak_memory,
133 value: sub.peak_memory,
133 sub_id: sub.id
134 sub_id: sub.id
134 }
135 }
135 end
136 end
136
137
137 if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value] and
138 if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value] and
138 !sub.user.admin?
139 !sub.user.admin?
139 @by_lang[lang.pretty_name][:first] = {
140 @by_lang[lang.pretty_name][:first] = {
140 avail: true,
141 avail: true,
141 user_id: sub.user_id,
142 user_id: sub.user_id,
142 value: sub.submitted_at,
143 value: sub.submitted_at,
143 sub_id: sub.id
144 sub_id: sub.id
144 }
145 }
145 end
146 end
146
147
147 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
148 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
148 @by_lang[lang.pretty_name][:length] = {
149 @by_lang[lang.pretty_name][:length] = {
149 avail: true,
150 avail: true,
150 user_id: sub.user_id,
151 user_id: sub.user_id,
151 value: sub.effective_code_length,
152 value: sub.effective_code_length,
152 sub_id: sub.id
153 sub_id: sub.id
153 }
154 }
154 end
155 end
155 end
156 end
156
157
157 #process user_id
158 #process user_id
158 @by_lang.each do |lang,prop|
159 @by_lang.each do |lang,prop|
159 prop.each do |k,v|
160 prop.each do |k,v|
160 v[:user] = User.exists?(v[:user_id]) ? User.find(v[:user_id]).full_name : "(NULL)"
161 v[:user] = User.exists?(v[:user_id]) ? User.find(v[:user_id]).full_name : "(NULL)"
161 end
162 end
162 end
163 end
163
164
164 #sum into best
165 #sum into best
165 if @by_lang and @by_lang.first
166 if @by_lang and @by_lang.first
166 @best = @by_lang.first[1]
167 @best = @by_lang.first[1]
167 @by_lang.each do |lang,prop|
168 @by_lang.each do |lang,prop|
168 if @best[:runtime][:value] >= prop[:runtime][:value]
169 if @best[:runtime][:value] >= prop[:runtime][:value]
169 @best[:runtime] = prop[:runtime]
170 @best[:runtime] = prop[:runtime]
170 @best[:runtime][:lang] = lang
171 @best[:runtime][:lang] = lang
171 end
172 end
172 if @best[:memory][:value] >= prop[:memory][:value]
173 if @best[:memory][:value] >= prop[:memory][:value]
173 @best[:memory] = prop[:memory]
174 @best[:memory] = prop[:memory]
174 @best[:memory][:lang] = lang
175 @best[:memory][:lang] = lang
175 end
176 end
176 if @best[:length][:value] >= prop[:length][:value]
177 if @best[:length][:value] >= prop[:length][:value]
177 @best[:length] = prop[:length]
178 @best[:length] = prop[:length]
178 @best[:length][:lang] = lang
179 @best[:length][:lang] = lang
179 end
180 end
180 if @best[:first][:value] >= prop[:first][:value]
181 if @best[:first][:value] >= prop[:first][:value]
181 @best[:first] = prop[:first]
182 @best[:first] = prop[:first]
182 @best[:first][:lang] = lang
183 @best[:first][:lang] = lang
183 end
184 end
184 end
185 end
185 end
186 end
186 end
187 end
187 end
188 end
188 end
189 end
@@ -1,156 +1,176
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
18
18 verify :method => :post, :only => [:chg_passwd],
19 verify :method => :post, :only => [:chg_passwd],
19 :redirect_to => { :action => :index }
20 :redirect_to => { :action => :index }
20
21
21 #in_place_edit_for :user, :alias_for_editing
22 #in_place_edit_for :user, :alias_for_editing
22 #in_place_edit_for :user, :email_for_editing
23 #in_place_edit_for :user, :email_for_editing
23
24
24 def index
25 def index
25 if !GraderConfiguration['system.user_setting_enabled']
26 if !GraderConfiguration['system.user_setting_enabled']
26 redirect_to :controller => 'main', :action => 'list'
27 redirect_to :controller => 'main', :action => 'list'
27 else
28 else
28 @user = User.find(session[:user_id])
29 @user = User.find(session[:user_id])
29 end
30 end
30 end
31 end
31
32
32 def chg_passwd
33 def chg_passwd
33 user = User.find(session[:user_id])
34 user = User.find(session[:user_id])
34 user.password = params[:passwd]
35 user.password = params[:passwd]
35 user.password_confirmation = params[:passwd_verify]
36 user.password_confirmation = params[:passwd_verify]
36 if user.save
37 if user.save
37 flash[:notice] = 'password changed'
38 flash[:notice] = 'password changed'
38 else
39 else
39 flash[:notice] = 'Error: password changing failed'
40 flash[:notice] = 'Error: password changing failed'
40 end
41 end
41 redirect_to :action => 'index'
42 redirect_to :action => 'index'
42 end
43 end
43
44
44 def new
45 def new
45 @user = User.new
46 @user = User.new
46 render :action => 'new', :layout => 'empty'
47 render :action => 'new', :layout => 'empty'
47 end
48 end
48
49
49 def register
50 def register
50 if(params[:cancel])
51 if(params[:cancel])
51 redirect_to :controller => 'main', :action => 'login'
52 redirect_to :controller => 'main', :action => 'login'
52 return
53 return
53 end
54 end
54 @user = User.new(params[:user])
55 @user = User.new(params[:user])
55 @user.password_confirmation = @user.password = User.random_password
56 @user.password_confirmation = @user.password = User.random_password
56 @user.activated = false
57 @user.activated = false
57 if (@user.valid?) and (@user.save)
58 if (@user.valid?) and (@user.save)
58 if send_confirmation_email(@user)
59 if send_confirmation_email(@user)
59 render :action => 'new_splash', :layout => 'empty'
60 render :action => 'new_splash', :layout => 'empty'
60 else
61 else
61 @admin_email = GraderConfiguration['system.admin_email']
62 @admin_email = GraderConfiguration['system.admin_email']
62 render :action => 'email_error', :layout => 'empty'
63 render :action => 'email_error', :layout => 'empty'
63 end
64 end
64 else
65 else
65 @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==''
66 render :action => 'new', :layout => 'empty'
67 render :action => 'new', :layout => 'empty'
67 end
68 end
68 end
69 end
69
70
70 def confirm
71 def confirm
71 login = params[:login]
72 login = params[:login]
72 key = params[:activation]
73 key = params[:activation]
73 @user = User.find_by_login(login)
74 @user = User.find_by_login(login)
74 if (@user) and (@user.verify_activation_key(key))
75 if (@user) and (@user.verify_activation_key(key))
75 if @user.valid? # check uniquenss of email
76 if @user.valid? # check uniquenss of email
76 @user.activated = true
77 @user.activated = true
77 @user.save
78 @user.save
78 @result = :successful
79 @result = :successful
79 else
80 else
80 @result = :email_used
81 @result = :email_used
81 end
82 end
82 else
83 else
83 @result = :failed
84 @result = :failed
84 end
85 end
85 render :action => 'confirm', :layout => 'empty'
86 render :action => 'confirm', :layout => 'empty'
86 end
87 end
87
88
88 def forget
89 def forget
89 render :action => 'forget', :layout => 'empty'
90 render :action => 'forget', :layout => 'empty'
90 end
91 end
91
92
92 def retrieve_password
93 def retrieve_password
93 email = params[:email]
94 email = params[:email]
94 user = User.find_by_email(email)
95 user = User.find_by_email(email)
95 if user
96 if user
96 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)
97 if last_updated_time > Time.now.gmtime - 5.minutes
98 if last_updated_time > Time.now.gmtime - 5.minutes
98 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'
99 else
100 else
100 user.password = user.password_confirmation = User.random_password
101 user.password = user.password_confirmation = User.random_password
101 user.save
102 user.save
102 send_new_password_email(user)
103 send_new_password_email(user)
103 flash[:notice] = 'New password has been mailed to you.'
104 flash[:notice] = 'New password has been mailed to you.'
104 end
105 end
105 else
106 else
106 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
107 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
107 end
108 end
108 redirect_to :action => 'forget'
109 redirect_to :action => 'forget'
109 end
110 end
110
111
112 + def profile
113 + @user = User.find(params[:id])
114 + @submission = Submission.where(user_id: params[:id]).all
115 + end
116 +
111 protected
117 protected
112
118
113 def verify_online_registration
119 def verify_online_registration
114 if !GraderConfiguration['system.online_registration']
120 if !GraderConfiguration['system.online_registration']
115 redirect_to :controller => 'main', :action => 'login'
121 redirect_to :controller => 'main', :action => 'login'
116 end
122 end
117 end
123 end
118
124
119 def send_confirmation_email(user)
125 def send_confirmation_email(user)
120 contest_name = GraderConfiguration['contest.name']
126 contest_name = GraderConfiguration['contest.name']
121 activation_url = url_for(:action => 'confirm',
127 activation_url = url_for(:action => 'confirm',
122 :login => user.login,
128 :login => user.login,
123 :activation => user.activation_key)
129 :activation => user.activation_key)
124 home_url = url_for(:controller => 'main', :action => 'index')
130 home_url = url_for(:controller => 'main', :action => 'index')
125 mail_subject = "[#{contest_name}] Confirmation"
131 mail_subject = "[#{contest_name}] Confirmation"
126 mail_body = t('registration.email_body', {
132 mail_body = t('registration.email_body', {
127 :full_name => user.full_name,
133 :full_name => user.full_name,
128 :contest_name => contest_name,
134 :contest_name => contest_name,
129 :login => user.login,
135 :login => user.login,
130 :password => user.password,
136 :password => user.password,
131 :activation_url => activation_url,
137 :activation_url => activation_url,
132 :admin_email => admin_email
138 :admin_email => admin_email
133 })
139 })
134
140
135 logger.info mail_body
141 logger.info mail_body
136
142
137 send_mail(user.email, mail_subject, mail_body)
143 send_mail(user.email, mail_subject, mail_body)
138 end
144 end
139
145
140 def send_new_password_email(user)
146 def send_new_password_email(user)
141 contest_name = GraderConfiguration['contest.name']
147 contest_name = GraderConfiguration['contest.name']
142 mail_subject = "[#{contest_name}] Password recovery"
148 mail_subject = "[#{contest_name}] Password recovery"
143 mail_body = t('registration.password_retrieval.email_body', {
149 mail_body = t('registration.password_retrieval.email_body', {
144 :full_name => user.full_name,
150 :full_name => user.full_name,
145 :contest_name => contest_name,
151 :contest_name => contest_name,
146 :login => user.login,
152 :login => user.login,
147 :password => user.password,
153 :password => user.password,
148 :admin_email => admin_email
154 :admin_email => admin_email
149 })
155 })
150
156
151 logger.info mail_body
157 logger.info mail_body
152
158
153 send_mail(user.email, mail_subject, mail_body)
159 send_mail(user.email, mail_subject, mail_body)
154 end
160 end
161 +
162 + # allow viewing of regular user profile only when options allow so
163 + # only admins can view admins profile
164 + def profile_authorization
165 + #if view admins' profile, allow only admin
166 + return false unless(params[:id])
167 + user = User.find(params[:id])
168 + return false unless user
169 + return admin_authorization if user.admin?
170 + return true if GraderConfiguration["right.user_view_submission"]
171 +
172 + #finally, we allow only admin
173 + admin_authorization
174 + end
155
175
156 end
176 end
@@ -1,62 +1,79
1 :css
1 :css
2 .hof_user { color: orangered; font-style: italic; }
2 .hof_user { color: orangered; font-style: italic; }
3 .hof_language { color: green; font-style: italic; }
3 .hof_language { color: green; font-style: italic; }
4 .hof_value { color: deeppink;font-style: italic; }
4 .hof_value { color: deeppink;font-style: italic; }
5
5
6 %h2 Overall
6 %h2 Overall
7
7
8 - if @best
8 - if @best
9 %b Best Runtime:
9 %b Best Runtime:
10 - by <span class="hof_user">#{@best[:runtime][:user]}</span> using <span class="hof_language">#{@best[:runtime][:lang]}</span> with <span class="hof_value">#{@best[:runtime][:value] * 1000} milliseconds</span> at submission
10 + by #{link_to @best[:runtime][:user], controller:'users', action:'profile', id:@best[:memory][:user_id]}
11 + using <span class="hof_language">#{@best[:runtime][:lang]}</span>
12 + with <span class="hof_value">#{@best[:runtime][:value] * 1000} milliseconds</span>
13 + at submission
11 = link_to("#" + @best[:runtime][:sub_id].to_s, controller: 'graders', action: 'submission', id:@best[:runtime][:sub_id])
14 = link_to("#" + @best[:runtime][:sub_id].to_s, controller: 'graders', action: 'submission', id:@best[:runtime][:sub_id])
12 %br/
15 %br/
13
16
14 %b Best Memory Usage:
17 %b Best Memory Usage:
15 - by <span class="hof_user">#{@best[:memory][:user]}</span> using <span class="hof_language">#{@best[:memory][:lang]}</span> with <span class="hof_value">#{@best[:memory][:value]} kbytes </span> at submission
18 + by #{link_to @best[:memory][:user], controller:'users', action:'profile', id:@best[:memory][:user_id]}
19 + using <span class="hof_language">#{@best[:memory][:lang]}</span>
20 + with <span class="hof_value">#{@best[:memory][:value]} kbytes </span>
21 + at submission
16 = link_to("#" + @best[:memory][:sub_id].to_s, controller: 'graders' , action: 'submission', id:@best[:memory][:sub_id])
22 = link_to("#" + @best[:memory][:sub_id].to_s, controller: 'graders' , action: 'submission', id:@best[:memory][:sub_id])
17 %br/
23 %br/
18
24
19 - %b Shortest Code:
25 + %b Shortest Code:
20 - by <span class="hof_user">#{@best[:length][:user]}</span> using <span class="hof_language">#{@best[:length][:lang]}</span> with <span class="hof_value">#{@best[:length][:value]} bytes</span> at submission
26 + by #{link_to @best[:length][:user], controller:'users', action:'profile', id:@best[:length][:user_id]}
27 + using <span class="hof_language">#{@best[:length][:lang]}</span>
28 + with <span class="hof_value">#{@best[:length][:value]} bytes</span>
29 + at submission
21 = link_to("#" + @best[:length][:sub_id].to_s, controller: 'graders' , action: 'submission', id: @best[:length][:sub_id])
30 = link_to("#" + @best[:length][:sub_id].to_s, controller: 'graders' , action: 'submission', id: @best[:length][:sub_id])
22 %br/
31 %br/
23
32
24 - %b First solver:
33 + %b First solver:
25 - <span class="hof_user">#{@best[:first][:user]}</span> is the first solver using <span class="hof_language">#{@best[:first][:lang]}</span> on <span class="hof_value">#{@best[:first][:value]}</span> at submission
34 + #{link_to @best[:first][:user], controller:'users', action:'profile', id:@best[:first][:user_id]} is the first solver
35 + using <span class="hof_language">#{@best[:first][:lang]}</span>
36 + on <span class="hof_value">#{@best[:first][:value]}</span>
37 + at submission
26 = link_to("#" + @best[:first][:sub_id].to_s, controller: 'graders' , action: 'submission', id: @best[:first][:sub_id])
38 = link_to("#" + @best[:first][:sub_id].to_s, controller: 'graders' , action: 'submission', id: @best[:first][:sub_id])
27 %br/
39 %br/
28
40
29
41
30 %p
42 %p
31 This counts only for submission with 100% score <br/>
43 This counts only for submission with 100% score <br/>
32 Right now, java is excluded from memory usage competition. (Because it always uses 2GB memory...)
44 Right now, java is excluded from memory usage competition. (Because it always uses 2GB memory...)
33
45
34 %h2 By language
46 %h2 By language
35
47
36 %table.info
48 %table.info
37 %thead
49 %thead
38 %tr.info-head
50 %tr.info-head
39 %th Language
51 %th Language
40 %th Best runtime (ms)
52 %th Best runtime (ms)
41 %th Best memory (kbytes)
53 %th Best memory (kbytes)
42 %th Shortest Code (bytes)
54 %th Shortest Code (bytes)
43 %th First solver
55 %th First solver
44 %tbody
56 %tbody
45 - @by_lang.each do |lang,value|
57 - @by_lang.each do |lang,value|
46 %tr{class: cycle('info-even','info-odd')}
58 %tr{class: cycle('info-even','info-odd')}
47 %td= lang
59 %td= lang
48 %td
60 %td
49 - = "#{value[:runtime][:user]} (#{(value[:runtime][:value] * 1000).to_i} @"
61 + = link_to value[:runtime][:user], controller: 'users', action: 'profile', id: value[:runtime][:user_id]
62 + = "(#{(value[:runtime][:value] * 1000).to_i} @"
50 = "#{link_to("#" + value[:runtime][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:runtime][:sub_id])} )".html_safe
63 = "#{link_to("#" + value[:runtime][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:runtime][:sub_id])} )".html_safe
51 %td
64 %td
52 - = "#{value[:memory][:user]} (#{value[:memory][:value]} @"
65 + = link_to value[:memory][:user], controller: 'users', action: 'profile', id: value[:memory][:user_id]
66 + = "(#{value[:memory][:value]} @"
53 = "#{link_to("#" + value[:memory][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:memory][:sub_id])} )".html_safe
67 = "#{link_to("#" + value[:memory][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:memory][:sub_id])} )".html_safe
54 %td
68 %td
55 - = "#{value[:length][:user]} (#{value[:length][:value]} @"
69 + = link_to value[:length][:user], controller: 'users', action: 'profile', id: value[:length][:user_id]
70 + = "(#{value[:length][:value]} @"
56 = "#{link_to("#" + value[:length][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:length][:sub_id])} )".html_safe
71 = "#{link_to("#" + value[:length][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:length][:sub_id])} )".html_safe
57 %td
72 %td
58 - = "#{value[:first][:user]} (#{value[:first][:value]} @"
73 + - if value[:first][:user] != '(NULL)' #TODO: i know... this is wrong...
59 - = "#{link_to("#" + value[:first][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:first][:sub_id])} )".html_safe
74 + = link_to value[:first][:user], controller: 'users', action: 'profile', id: value[:first][:user_id]
75 + = "(#{value[:first][:value]} @"
76 + = "#{link_to("#" + value[:first][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:first][:sub_id])} )".html_safe
60
77
61 - else
78 - else
62 %h3 No submissions
79 %h3 No submissions
@@ -1,32 +1,32
1 - content_for :header do
1 - content_for :header do
2 = stylesheet_link_tag 'tablesorter-theme.cafe'
2 = stylesheet_link_tag 'tablesorter-theme.cafe'
3 = javascript_include_tag 'new'
3 = javascript_include_tag 'new'
4
4
5 %script{:type=>"text/javascript"}
5 %script{:type=>"text/javascript"}
6 $(function () {
6 $(function () {
7 $('#since_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
7 $('#since_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
8 $('#until_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
8 $('#until_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
9 $('#my_table').tablesorter({widthFixed: true, widgets: ['zebra']});
9 $('#my_table').tablesorter({widthFixed: true, widgets: ['zebra']});
10 });
10 });
11
11
12 %h1 Login status
12 %h1 Login status
13
13
14 =render partial: 'report_menu'
14 =render partial: 'report_menu'
15 =render partial: 'date_range', locals: {param_text: 'Login date range:', title: 'Query login stat in the range' }
15 =render partial: 'date_range', locals: {param_text: 'Login date range:', title: 'Query login stat in the range' }
16
16
17 %table.tablesorter-cafe#my_table
17 %table.tablesorter-cafe#my_table
18 %thead
18 %thead
19 %tr
19 %tr
20 %th login
20 %th login
21 %th full name
21 %th full name
22 %th login count
22 %th login count
23 %th earliest
23 %th earliest
24 %th latest
24 %th latest
25 %tbody
25 %tbody
26 - @logins.each do |l|
26 - @logins.each do |l|
27 %tr{class: cycle('info-even','info-odd')}
27 %tr{class: cycle('info-even','info-odd')}
28 - %td= l[:login]
28 + %td= link_to l[:login], controller: 'users', action: 'profile', id: l[:id]
29 %td= l[:full_name]
29 %td= l[:full_name]
30 %td= l[:count]
30 %td= l[:count]
31 %td= l[:min] ? l[:min].in_time_zone.strftime('%Y-%m-%d %H:%M') : ''
31 %td= l[:min] ? l[:min].in_time_zone.strftime('%Y-%m-%d %H:%M') : ''
32 %td= l[:max] ? time_ago_in_words(l[:max].in_time_zone) + ' ago' : ''
32 %td= l[:max] ? time_ago_in_words(l[:max].in_time_zone) + ' ago' : ''
@@ -1,54 +1,54
1 - content_for :header do
1 - content_for :header do
2 = javascript_include_tag 'new'
2 = javascript_include_tag 'new'
3 = stylesheet_link_tag 'tablesorter-theme.cafe'
3 = stylesheet_link_tag 'tablesorter-theme.cafe'
4
4
5 %script{:type=>"text/javascript"}
5 %script{:type=>"text/javascript"}
6 $(function () {
6 $(function () {
7 $('#since_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
7 $('#since_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
8 $('#until_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
8 $('#until_datetime').datetimepicker({ showButtonPanel: true, dateFormat: "yy-mm-dd", controlType: "slider"} );
9 $('#my_table').tablesorter({widgets: ['zebra']});
9 $('#my_table').tablesorter({widgets: ['zebra']});
10 });
10 });
11
11
12 %h1 User grading results
12 %h1 User grading results
13 %h2= params[:action] == 'user_stat' ? "Show scores from latest submission" : "Show max scores in submission range"
13 %h2= params[:action] == 'user_stat' ? "Show scores from latest submission" : "Show max scores in submission range"
14
14
15
15
16 - if @problem and @problem.errors
16 - if @problem and @problem.errors
17 =error_messages_for 'problem'
17 =error_messages_for 'problem'
18
18
19 = render partial: 'submission_range'
19 = render partial: 'submission_range'
20
20
21 - if params[:action] == 'user_stat'
21 - if params[:action] == 'user_stat'
22 = "latest score"
22 = "latest score"
23 - else
23 - else
24 = link_to '[Show only latest submissions]', controller: :user_admin, action: :user_stat
24 = link_to '[Show only latest submissions]', controller: :user_admin, action: :user_stat
25
25
26 %table.tablesorter-cafe#my_table
26 %table.tablesorter-cafe#my_table
27 %thead
27 %thead
28 %tr
28 %tr
29 %th User
29 %th User
30 %th Name
30 %th Name
31 %th Activated?
31 %th Activated?
32 %th Logged in
32 %th Logged in
33 %th Contest(s)
33 %th Contest(s)
34 - @problems.each do |p|
34 - @problems.each do |p|
35 %th= p.name
35 %th= p.name
36 %th Total
36 %th Total
37 %th Passed
37 %th Passed
38 %tbody
38 %tbody
39 - @scorearray.each do |sc|
39 - @scorearray.each do |sc|
40 %tr{class: cycle('info-even','info-odd')}
40 %tr{class: cycle('info-even','info-odd')}
41 - total,num_passed = 0,0
41 - total,num_passed = 0,0
42 - sc.each_index do |i|
42 - sc.each_index do |i|
43 - if i == 0
43 - if i == 0
44 - %td= sc[i].login
44 + %td= link_to sc[i].login, controller: 'users', action: 'profile', id: sc[i]
45 %td= sc[i].full_name
45 %td= sc[i].full_name
46 %td= sc[i].activated
46 %td= sc[i].activated
47 %td= sc[i].try(:contest_stat).try(:started_at)!=nil ? 'yes' : 'no'
47 %td= sc[i].try(:contest_stat).try(:started_at)!=nil ? 'yes' : 'no'
48 %td= sc[i].contests.collect {|c| c.name}.join(', ')
48 %td= sc[i].contests.collect {|c| c.name}.join(', ')
49 - else
49 - else
50 %td= sc[i][0]
50 %td= sc[i][0]
51 - total += sc[i][0]
51 - total += sc[i][0]
52 - num_passed += 1 if sc[i][1]
52 - num_passed += 1 if sc[i][1]
53 %td= total
53 %td= total
54 %td= num_passed
54 %td= num_passed
You need to be logged in to leave comments. Login now