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

r509:bb124a034509 - - 8 files changed: 112 inserted, 53 deleted

@@ -0,0 +1,5
1 + class AddIpToSubmissions < ActiveRecord::Migration
2 + def change
3 + add_column :submissions, :ip_address, :string
4 + end
5 + end
@@ -22,96 +22,97
22 # COMMENT OUT: only need when having high load
22 # COMMENT OUT: only need when having high load
23 # caches_action :index, :login
23 # caches_action :index, :login
24
24
25 # NOTE: This method is not actually needed, 'config/routes.rb' has
25 # NOTE: This method is not actually needed, 'config/routes.rb' has
26 # assigned action login as a default action.
26 # assigned action login as a default action.
27 def index
27 def index
28 redirect_to :action => 'login'
28 redirect_to :action => 'login'
29 end
29 end
30
30
31 def login
31 def login
32 saved_notice = flash[:notice]
32 saved_notice = flash[:notice]
33 reset_session
33 reset_session
34 flash.now[:notice] = saved_notice
34 flash.now[:notice] = saved_notice
35
35
36 # EXPERIMENT:
36 # EXPERIMENT:
37 # Hide login if in single user mode and the url does not
37 # Hide login if in single user mode and the url does not
38 # explicitly specify /login
38 # explicitly specify /login
39 #
39 #
40 # logger.info "PATH: #{request.path}"
40 # logger.info "PATH: #{request.path}"
41 # if GraderConfiguration['system.single_user_mode'] and
41 # if GraderConfiguration['system.single_user_mode'] and
42 # request.path!='/main/login'
42 # request.path!='/main/login'
43 # @hidelogin = true
43 # @hidelogin = true
44 # end
44 # end
45
45
46 @announcements = Announcement.find_for_frontpage
46 @announcements = Announcement.find_for_frontpage
47 render :action => 'login', :layout => 'empty'
47 render :action => 'login', :layout => 'empty'
48 end
48 end
49
49
50 def list
50 def list
51 prepare_list_information
51 prepare_list_information
52 end
52 end
53
53
54 def help
54 def help
55 @user = User.find(session[:user_id])
55 @user = User.find(session[:user_id])
56 end
56 end
57
57
58 def submit
58 def submit
59 user = User.find(session[:user_id])
59 user = User.find(session[:user_id])
60
60
61 @submission = Submission.new
61 @submission = Submission.new
62 @submission.problem_id = params[:submission][:problem_id]
62 @submission.problem_id = params[:submission][:problem_id]
63 @submission.user = user
63 @submission.user = user
64 @submission.language_id = 0
64 @submission.language_id = 0
65 if (params['file']) and (params['file']!='')
65 if (params['file']) and (params['file']!='')
66 @submission.source = params['file'].read
66 @submission.source = params['file'].read
67 @submission.source_filename = params['file'].original_filename
67 @submission.source_filename = params['file'].original_filename
68 end
68 end
69 @submission.submitted_at = Time.new.gmtime
69 @submission.submitted_at = Time.new.gmtime
70 + @submission.ip_address = request.remote_ip
70
71
71 if GraderConfiguration.time_limit_mode? and user.contest_finished?
72 if GraderConfiguration.time_limit_mode? and user.contest_finished?
72 @submission.errors.add_to_base "The contest is over."
73 @submission.errors.add_to_base "The contest is over."
73 prepare_list_information
74 prepare_list_information
74 render :action => 'list' and return
75 render :action => 'list' and return
75 end
76 end
76
77
77 if @submission.valid?
78 if @submission.valid?
78 if @submission.save == false
79 if @submission.save == false
79 flash[:notice] = 'Error saving your submission'
80 flash[:notice] = 'Error saving your submission'
80 elsif Task.create(:submission_id => @submission.id,
81 elsif Task.create(:submission_id => @submission.id,
81 :status => Task::STATUS_INQUEUE) == false
82 :status => Task::STATUS_INQUEUE) == false
82 flash[:notice] = 'Error adding your submission to task queue'
83 flash[:notice] = 'Error adding your submission to task queue'
83 end
84 end
84 else
85 else
85 prepare_list_information
86 prepare_list_information
86 render :action => 'list' and return
87 render :action => 'list' and return
87 end
88 end
88 redirect_to :action => 'list'
89 redirect_to :action => 'list'
89 end
90 end
90
91
91 def source
92 def source
92 submission = Submission.find(params[:id])
93 submission = Submission.find(params[:id])
93 if ((submission.user_id == session[:user_id]) and
94 if ((submission.user_id == session[:user_id]) and
94 (submission.problem != nil) and
95 (submission.problem != nil) and
95 (submission.problem.available))
96 (submission.problem.available))
96 send_data(submission.source,
97 send_data(submission.source,
97 {:filename => submission.download_filename,
98 {:filename => submission.download_filename,
98 :type => 'text/plain'})
99 :type => 'text/plain'})
99 else
100 else
100 flash[:notice] = 'Error viewing source'
101 flash[:notice] = 'Error viewing source'
101 redirect_to :action => 'list'
102 redirect_to :action => 'list'
102 end
103 end
103 end
104 end
104
105
105 def compiler_msg
106 def compiler_msg
106 @submission = Submission.find(params[:id])
107 @submission = Submission.find(params[:id])
107 if @submission.user_id == session[:user_id]
108 if @submission.user_id == session[:user_id]
108 render :action => 'compiler_msg', :layout => 'empty'
109 render :action => 'compiler_msg', :layout => 'empty'
109 else
110 else
110 flash[:notice] = 'Error viewing source'
111 flash[:notice] = 'Error viewing source'
111 redirect_to :action => 'list'
112 redirect_to :action => 'list'
112 end
113 end
113 end
114 end
114
115
115 def submission
116 def submission
116 @user = User.find(session[:user_id])
117 @user = User.find(session[:user_id])
117 @problems = @user.available_problems
118 @problems = @user.available_problems
@@ -1,89 +1,95
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 + md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
20 + @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
20 rescue
21 rescue
21 @since_time = DateTime.new(1000,1,1)
22 @since_time = DateTime.new(1000,1,1)
22 end
23 end
23 begin
24 begin
24 - @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
25 + md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
26 + @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
25 rescue
27 rescue
26 @until_time = DateTime.new(3000,1,1)
28 @until_time = DateTime.new(3000,1,1)
27 end
29 end
28
30
29 User.all.each do |user|
31 User.all.each do |user|
30 @logins << { id: user.id,
32 @logins << { id: user.id,
31 login: user.login,
33 login: user.login,
32 full_name: user.full_name,
34 full_name: user.full_name,
33 count: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
35 count: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
34 user.id,@since_time,@until_time)
36 user.id,@since_time,@until_time)
35 .count(:id),
37 .count(:id),
36 min: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
38 min: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
37 user.id,@since_time,@until_time)
39 user.id,@since_time,@until_time)
38 .minimum(:created_at),
40 .minimum(:created_at),
39 max: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
41 max: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
40 user.id,@since_time,@until_time)
42 user.id,@since_time,@until_time)
41 - .maximum(:created_at)
43 + .maximum(:created_at),
44 + ip: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
45 + user.id,@since_time,@until_time)
46 + .select(:ip_address).uniq
47 +
42 }
48 }
43 end
49 end
44 end
50 end
45
51
46 def submission_stat
52 def submission_stat
47
53
48 date_and_time = '%Y-%m-%d %H:%M'
54 date_and_time = '%Y-%m-%d %H:%M'
49 begin
55 begin
50 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
56 @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
51 rescue
57 rescue
52 @since_time = DateTime.new(1000,1,1)
58 @since_time = DateTime.new(1000,1,1)
53 end
59 end
54 begin
60 begin
55 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
61 @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
56 rescue
62 rescue
57 @until_time = DateTime.new(3000,1,1)
63 @until_time = DateTime.new(3000,1,1)
58 end
64 end
59
65
60 @submissions = {}
66 @submissions = {}
61
67
62 User.find_each do |user|
68 User.find_each do |user|
63 @submissions[user.id] = { login: user.login, full_name: user.full_name, count: 0, sub: { } }
69 @submissions[user.id] = { login: user.login, full_name: user.full_name, count: 0, sub: { } }
64 end
70 end
65
71
66 Submission.where("submitted_at >= ? AND submitted_at <= ?",@since_time,@until_time).find_each do |s|
72 Submission.where("submitted_at >= ? AND submitted_at <= ?",@since_time,@until_time).find_each do |s|
67 if @submissions[s.user_id]
73 if @submissions[s.user_id]
68 if not @submissions[s.user_id][:sub].has_key?(s.problem_id)
74 if not @submissions[s.user_id][:sub].has_key?(s.problem_id)
69 a = nil
75 a = nil
70 begin
76 begin
71 a = Problem.find(s.problem_id)
77 a = Problem.find(s.problem_id)
72 rescue
78 rescue
73 a = nil
79 a = nil
74 end
80 end
75 @submissions[s.user_id][:sub][s.problem_id] =
81 @submissions[s.user_id][:sub][s.problem_id] =
76 { prob_name: (a ? a.full_name : '(NULL)'),
82 { prob_name: (a ? a.full_name : '(NULL)'),
77 sub_ids: [s.id] }
83 sub_ids: [s.id] }
78 else
84 else
79 @submissions[s.user_id][:sub][s.problem_id][:sub_ids] << s.id
85 @submissions[s.user_id][:sub][s.problem_id][:sub_ids] << s.id
80 end
86 end
81 @submissions[s.user_id][:count] += 1
87 @submissions[s.user_id][:count] += 1
82 end
88 end
83 end
89 end
84 end
90 end
85
91
86 def problem_hof
92 def problem_hof
87 # gen problem list
93 # gen problem list
88 @user = User.find(session[:user_id])
94 @user = User.find(session[:user_id])
89 @problems = @user.available_problems
95 @problems = @user.available_problems
@@ -119,71 +125,71
119
125
120 if sub.max_runtime and sub.max_runtime < @by_lang[lang.pretty_name][:runtime][:value]
126 if sub.max_runtime and sub.max_runtime < @by_lang[lang.pretty_name][:runtime][:value]
121 @by_lang[lang.pretty_name][:runtime] = {
127 @by_lang[lang.pretty_name][:runtime] = {
122 avail: true,
128 avail: true,
123 user_id: sub.user_id,
129 user_id: sub.user_id,
124 value: sub.max_runtime,
130 value: sub.max_runtime,
125 sub_id: sub.id
131 sub_id: sub.id
126 }
132 }
127 end
133 end
128
134
129 if sub.peak_memory and sub.peak_memory < @by_lang[lang.pretty_name][:memory][:value]
135 if sub.peak_memory and sub.peak_memory < @by_lang[lang.pretty_name][:memory][:value]
130 @by_lang[lang.pretty_name][:memory] = {
136 @by_lang[lang.pretty_name][:memory] = {
131 avail: true,
137 avail: true,
132 user_id: sub.user_id,
138 user_id: sub.user_id,
133 value: sub.peak_memory,
139 value: sub.peak_memory,
134 sub_id: sub.id
140 sub_id: sub.id
135 }
141 }
136 end
142 end
137
143
138 if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value] and
144 if sub.submitted_at and sub.submitted_at < @by_lang[lang.pretty_name][:first][:value] and
139 !sub.user.admin?
145 !sub.user.admin?
140 @by_lang[lang.pretty_name][:first] = {
146 @by_lang[lang.pretty_name][:first] = {
141 avail: true,
147 avail: true,
142 user_id: sub.user_id,
148 user_id: sub.user_id,
143 value: sub.submitted_at,
149 value: sub.submitted_at,
144 sub_id: sub.id
150 sub_id: sub.id
145 }
151 }
146 end
152 end
147
153
148 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
154 if @by_lang[lang.pretty_name][:length][:value] > sub.effective_code_length
149 @by_lang[lang.pretty_name][:length] = {
155 @by_lang[lang.pretty_name][:length] = {
150 avail: true,
156 avail: true,
151 user_id: sub.user_id,
157 user_id: sub.user_id,
152 value: sub.effective_code_length,
158 value: sub.effective_code_length,
153 sub_id: sub.id
159 sub_id: sub.id
154 }
160 }
155 end
161 end
156 end
162 end
157
163
158 #process user_id
164 #process user_id
159 @by_lang.each do |lang,prop|
165 @by_lang.each do |lang,prop|
160 prop.each do |k,v|
166 prop.each do |k,v|
161 v[:user] = User.exists?(v[:user_id]) ? User.find(v[:user_id]).full_name : "(NULL)"
167 v[:user] = User.exists?(v[:user_id]) ? User.find(v[:user_id]).full_name : "(NULL)"
162 end
168 end
163 end
169 end
164
170
165 #sum into best
171 #sum into best
166 if @by_lang and @by_lang.first
172 if @by_lang and @by_lang.first
167 - @best = @by_lang.first[1]
173 + @best = @by_lang.first[1].clone
168 @by_lang.each do |lang,prop|
174 @by_lang.each do |lang,prop|
169 if @best[:runtime][:value] >= prop[:runtime][:value]
175 if @best[:runtime][:value] >= prop[:runtime][:value]
170 @best[:runtime] = prop[:runtime]
176 @best[:runtime] = prop[:runtime]
171 @best[:runtime][:lang] = lang
177 @best[:runtime][:lang] = lang
172 end
178 end
173 if @best[:memory][:value] >= prop[:memory][:value]
179 if @best[:memory][:value] >= prop[:memory][:value]
174 @best[:memory] = prop[:memory]
180 @best[:memory] = prop[:memory]
175 @best[:memory][:lang] = lang
181 @best[:memory][:lang] = lang
176 end
182 end
177 if @best[:length][:value] >= prop[:length][:value]
183 if @best[:length][:value] >= prop[:length][:value]
178 @best[:length] = prop[:length]
184 @best[:length] = prop[:length]
179 @best[:length][:lang] = lang
185 @best[:length][:lang] = lang
180 end
186 end
181 if @best[:first][:value] >= prop[:first][:value]
187 if @best[:first][:value] >= prop[:first][:value]
182 @best[:first] = prop[:first]
188 @best[:first] = prop[:first]
183 @best[:first][:lang] = lang
189 @best[:first][:lang] = lang
184 end
190 end
185 end
191 end
186 end
192 end
187 end
193 end
188 end
194 end
189 end
195 end
@@ -1,27 +1,61
1 %style{type: "text/css"}
1 %style{type: "text/css"}
2 = @css_style
2 = @css_style
3 + :css
4 + .field {
5 + font-weight: bold;
6 + text-align: right;
7 + padding: 3px;
8 + }
9 +
3
10
4 %h1= "Submission: #{@submission.id}"
11 %h1= "Submission: #{@submission.id}"
5
12
6 - %p
13 +
7 - User:
14 + %h2 Stat
8 - = "(#{@submission.user.login}) #{@submission.user.full_name}"
9 - %br/
10 - Problem:
11 - - if @submission.problem!=nil
12 - = "#{@submission.problem.full_name}"
13 - - else
14 - = "(n/a)"
15 - %br/
16 - = "Number: #{@submission.number}"
17 - %br/
18 - = "Submitted at: #{format_short_time(@submission.submitted_at)}"
19 - %br/
20 - = "Points : #{@submission.points}/#{@submission.problem.full_score}"
21 - %br/
22 - = "Comment : #{@submission.grader_comment}"
23
15
24 - %b Source code (first 10kb)
16 + %table.info
17 + %thead
18 + %tr.info-head
19 + %th Field
20 + %th Value
21 + %tbody
22 + %tr{class: cycle('info-even','info-odd')}
23 + %td.field User:
24 + %td.value= "(#{@submission.user.login}) #{@submission.user.full_name}"
25 + %tr{class: cycle('info-even','info-odd')}
26 + %td.field Problem:
27 + %td.value
28 + - if @submission.problem!=nil
29 + = "(#{@submission.problem.name}) #{@submission.problem.full_name}"
30 + - else
31 + = "(n/a)"
32 + %tr{class: cycle('info-even','info-odd')}
33 + %td.field Tries:
34 + %td.value= @submission.number
35 + %tr{class: cycle('info-even','info-odd')}
36 + %td.field Submitted:
37 + %td.value #{time_ago_in_words(@submission.submitted_at)} ago (at #{@submission.submitted_at.to_formatted_s(:long)})
38 + %tr{class: cycle('info-even','info-odd')}
39 + %td.field Graded:
40 + %td.value #{time_ago_in_words(@submission.graded_at)} ago (at #{@submission.graded_at.to_formatted_s(:long)})
41 + %tr{class: cycle('info-even','info-odd')}
42 + %td.field Points:
43 + %td.value #{@submission.points}/#{@submission.problem.full_score}
44 + %tr{class: cycle('info-even','info-odd')}
45 + %td.field Comment:
46 + %td.value #{@submission.grader_comment}
47 + %tr{class: cycle('info-even','info-odd')}
48 + %td.field Runtime (s):
49 + %td.value #{@submission.max_runtime}
50 + %tr{class: cycle('info-even','info-odd')}
51 + %td.field Memory (kb):
52 + %td.value #{@submission.peak_memory}
53 + - if session[:admin]
54 + %tr{class: cycle('info-even','info-odd')}
55 + %td.field IP:
56 + %td.value #{@submission.ip_address}
57 +
58 + %h2 Source code
25 //%div.highlight{:style => "border: 1px solid black;"}
59 //%div.highlight{:style => "border: 1px solid black;"}
26 =@formatted_code.html_safe
60 =@formatted_code.html_safe
27
61
@@ -1,79 +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 of #{Problem.find(params[:id]).full_name}
7
7
8 - if @best
8 - if @best
9 %b Best Runtime:
9 %b Best Runtime:
10 by #{link_to @best[:runtime][:user], controller:'users', action:'profile', id:@best[:memory][:user_id]}
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>
11 using <span class="hof_language">#{@best[:runtime][:lang]}</span>
12 with <span class="hof_value">#{@best[:runtime][:value] * 1000} milliseconds</span>
12 with <span class="hof_value">#{@best[:runtime][:value] * 1000} milliseconds</span>
13 at submission
13 at submission
14 = 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])
15 %br/
15 %br/
16
16
17 %b Best Memory Usage:
17 %b Best Memory Usage:
18 by #{link_to @best[:memory][:user], controller:'users', action:'profile', id:@best[:memory][:user_id]}
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>
19 using <span class="hof_language">#{@best[:memory][:lang]}</span>
20 - with <span class="hof_value">#{@best[:memory][:value]} kbytes </span>
20 + with <span class="hof_value">#{number_with_delimiter(@best[:memory][:value])} kbytes </span>
21 at submission
21 at submission
22 = 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])
23 %br/
23 %br/
24
24
25 %b Shortest Code:
25 %b Shortest Code:
26 by #{link_to @best[:length][:user], controller:'users', action:'profile', id:@best[:length][:user_id]}
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>
27 using <span class="hof_language">#{@best[:length][:lang]}</span>
28 with <span class="hof_value">#{@best[:length][:value]} bytes</span>
28 with <span class="hof_value">#{@best[:length][:value]} bytes</span>
29 at submission
29 at submission
30 = 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])
31 %br/
31 %br/
32
32
33 %b First solver:
33 %b First solver:
34 #{link_to @best[:first][:user], controller:'users', action:'profile', id:@best[:first][:user_id]} is the first solver
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>
35 using <span class="hof_language">#{@best[:first][:lang]}</span>
36 on <span class="hof_value">#{@best[:first][:value]}</span>
36 on <span class="hof_value">#{@best[:first][:value]}</span>
37 at submission
37 at submission
38 = 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])
39 %br/
39 %br/
40
40
41
41
42 %p
42 %p
43 This counts only for submission with 100% score <br/>
43 This counts only for submission with 100% score <br/>
44 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...)
45
45
46 %h2 By language
46 %h2 By language
47
47
48 %table.info
48 %table.info
49 %thead
49 %thead
50 %tr.info-head
50 %tr.info-head
51 %th Language
51 %th Language
52 %th Best runtime (ms)
52 %th Best runtime (ms)
53 %th Best memory (kbytes)
53 %th Best memory (kbytes)
54 %th Shortest Code (bytes)
54 %th Shortest Code (bytes)
55 %th First solver
55 %th First solver
56 %tbody
56 %tbody
57 - @by_lang.each do |lang,value|
57 - @by_lang.each do |lang,value|
58 %tr{class: cycle('info-even','info-odd')}
58 %tr{class: cycle('info-even','info-odd')}
59 %td= lang
59 %td= lang
60 %td
60 %td
61 = link_to value[:runtime][:user], controller: 'users', action: 'profile', id: value[:runtime][:user_id]
61 = link_to value[:runtime][:user], controller: 'users', action: 'profile', id: value[:runtime][:user_id]
62 = "(#{(value[:runtime][:value] * 1000).to_i} @"
62 = "(#{(value[:runtime][:value] * 1000).to_i} @"
63 = "#{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
64 %td
64 %td
65 = link_to value[:memory][:user], controller: 'users', action: 'profile', id: value[:memory][:user_id]
65 = link_to value[:memory][:user], controller: 'users', action: 'profile', id: value[:memory][:user_id]
66 - = "(#{value[:memory][:value]} @"
66 + = "(#{number_with_delimiter(value[:memory][:value])} @"
67 = "#{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
68 %td
68 %td
69 = link_to value[:length][:user], controller: 'users', action: 'profile', id: value[:length][:user_id]
69 = link_to value[:length][:user], controller: 'users', action: 'profile', id: value[:length][:user_id]
70 = "(#{value[:length][:value]} @"
70 = "(#{value[:length][:value]} @"
71 = "#{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
72 %td
72 %td
73 - if value[:first][:user] != '(NULL)' #TODO: i know... this is wrong...
73 - if value[:first][:user] != '(NULL)' #TODO: i know... this is wrong...
74 = link_to value[:first][:user], controller: 'users', action: 'profile', id: value[:first][:user_id]
74 = link_to value[:first][:user], controller: 'users', action: 'profile', id: value[:first][:user_id]
75 = "(#{value[:first][:value]} @"
75 = "(#{value[:first][:value]} @"
76 = "#{link_to("#" + value[:first][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:first][:sub_id])} )".html_safe
76 = "#{link_to("#" + value[:first][:sub_id].to_s, controller: 'graders' , action: 'submission', id: value[:first][:sub_id])} )".html_safe
77
77
78 - else
78 - else
79 %h3 No submissions
79 %h3 No submissions
@@ -1,32 +1,36
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 + %th IP
25 %tbody
26 %tbody
26 - @logins.each do |l|
27 - @logins.each do |l|
27 %tr{class: cycle('info-even','info-odd')}
28 %tr{class: cycle('info-even','info-odd')}
28 %td= link_to l[:login], controller: 'users', action: 'profile', id: l[:id]
29 %td= link_to l[:login], controller: 'users', action: 'profile', id: l[:id]
29 %td= l[:full_name]
30 %td= l[:full_name]
30 %td= l[:count]
31 %td= l[:count]
31 %td= l[:min] ? l[:min].in_time_zone.strftime('%Y-%m-%d %H:%M') : ''
32 %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' : ''
33 + %td= l[:max] ? "#{l[:max].in_time_zone.strftime('%Y-%m-%d %H:%M.%S')} (#{time_ago_in_words(l[:max].in_time_zone)} ago)" : ''
34 + %td
35 + - l[:ip].each do |ip|
36 + #{ip.ip_address} <br/>
@@ -1,46 +1,50
1 - content_for :header do
1 - content_for :header do
2 = javascript_include_tag 'new'
2 = javascript_include_tag 'new'
3
3
4 %script{:type=>"text/javascript"}
4 %script{:type=>"text/javascript"}
5 $(function () {
5 $(function () {
6 $('#submission_table').tablesorter({widgets: ['zebra','filter']});
6 $('#submission_table').tablesorter({widgets: ['zebra','filter']});
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 + ' Profile'
14 %h1= @user.full_name + ' Profile'
15
15
16 %h2 Basic info
16 %h2 Basic info
17 <b>Login:</b> #{@user.login} <br/>
17 <b>Login:</b> #{@user.login} <br/>
18 <b>Full name:</b> #{@user.full_name} <br />
18 <b>Full name:</b> #{@user.full_name} <br />
19
19
20
20
21 %h2 Problem Stat
21 %h2 Problem Stat
22
22
23 %h2 Submissions
23 %h2 Submissions
24
24
25 %table.tablesorter-cafe#submission_table
25 %table.tablesorter-cafe#submission_table
26 %thead
26 %thead
27 %tr
27 %tr
28 %th ID
28 %th ID
29 %th Problem code
29 %th Problem code
30 %th Problem name
30 %th Problem name
31 %th Language
31 %th Language
32 %th Result
32 %th Result
33 %th Score
33 %th Score
34 + - if session[:admin]
35 + %th IP
34 %tbody
36 %tbody
35 - @submission.each do |s|
37 - @submission.each do |s|
36 - next unless s.problem
38 - next unless s.problem
37 %tr
39 %tr
38 %td= link_to "#{s.id}", controller: "graders", action: "submission", id: s.id
40 %td= link_to "#{s.id}", controller: "graders", action: "submission", id: s.id
39 %td= s.problem.name
41 %td= s.problem.name
40 %td= s.problem.full_name
42 %td= s.problem.full_name
41 %td= s.language.pretty_name
43 %td= s.language.pretty_name
42 %td.fix-width= s.grader_comment
44 %td.fix-width= s.grader_comment
43 - %td= s.points/s.problem.full_score * 100
45 + %td= (s.points*100)/s.problem.full_score
46 + - if session[:admin]
47 + %td= s.ip_address
44
48
45
49
46
50
@@ -1,242 +1,247
1 # encoding: UTF-8
1 # encoding: UTF-8
2 # This file is auto-generated from the current state of the database. Instead
2 # This file is auto-generated from the current state of the database. Instead
3 # of editing this file, please use the migrations feature of Active Record to
3 # of editing this file, please use the migrations feature of Active Record to
4 # incrementally modify your database, and then regenerate this schema definition.
4 # incrementally modify your database, and then regenerate this schema definition.
5 #
5 #
6 # Note that this schema.rb definition is the authoritative source for your
6 # Note that this schema.rb definition is the authoritative source for your
7 # database schema. If you need to create the application database on another
7 # database schema. If you need to create the application database on another
8 # system, you should be using db:schema:load, not running all the migrations
8 # system, you should be using db:schema:load, not running all the migrations
9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10 # you'll amass, the slower it'll run and the greater likelihood for issues).
10 # you'll amass, the slower it'll run and the greater likelihood for issues).
11 #
11 #
12 # It's strongly recommended to check this file into your version control system.
12 # It's strongly recommended to check this file into your version control system.
13
13
14 - ActiveRecord::Schema.define(:version => 20140826095949) do
14 + ActiveRecord::Schema.define(:version => 20140917150629) do
15
15
16 create_table "announcements", :force => true do |t|
16 create_table "announcements", :force => true do |t|
17 t.string "author"
17 t.string "author"
18 - t.text "body", :limit => 16777215
18 + t.text "body"
19 t.boolean "published"
19 t.boolean "published"
20 - t.datetime "created_at", :null => false
20 + t.datetime "created_at", :null => false
21 - t.datetime "updated_at", :null => false
21 + t.datetime "updated_at", :null => false
22 - t.boolean "frontpage", :default => false
22 + t.boolean "frontpage", :default => false
23 - t.boolean "contest_only", :default => false
23 + t.boolean "contest_only", :default => false
24 t.string "title"
24 t.string "title"
25 t.string "notes"
25 t.string "notes"
26 end
26 end
27
27
28 create_table "contests", :force => true do |t|
28 create_table "contests", :force => true do |t|
29 t.string "title"
29 t.string "title"
30 t.boolean "enabled"
30 t.boolean "enabled"
31 t.datetime "created_at", :null => false
31 t.datetime "created_at", :null => false
32 t.datetime "updated_at", :null => false
32 t.datetime "updated_at", :null => false
33 t.string "name"
33 t.string "name"
34 end
34 end
35
35
36 create_table "contests_problems", :id => false, :force => true do |t|
36 create_table "contests_problems", :id => false, :force => true do |t|
37 t.integer "contest_id"
37 t.integer "contest_id"
38 t.integer "problem_id"
38 t.integer "problem_id"
39 end
39 end
40
40
41 create_table "contests_users", :id => false, :force => true do |t|
41 create_table "contests_users", :id => false, :force => true do |t|
42 t.integer "contest_id"
42 t.integer "contest_id"
43 t.integer "user_id"
43 t.integer "user_id"
44 end
44 end
45
45
46 create_table "countries", :force => true do |t|
46 create_table "countries", :force => true do |t|
47 t.string "name"
47 t.string "name"
48 t.datetime "created_at", :null => false
48 t.datetime "created_at", :null => false
49 t.datetime "updated_at", :null => false
49 t.datetime "updated_at", :null => false
50 end
50 end
51
51
52 create_table "descriptions", :force => true do |t|
52 create_table "descriptions", :force => true do |t|
53 - t.text "body", :limit => 16777215
53 + t.text "body"
54 t.boolean "markdowned"
54 t.boolean "markdowned"
55 - t.datetime "created_at", :null => false
55 + t.datetime "created_at", :null => false
56 - t.datetime "updated_at", :null => false
56 + t.datetime "updated_at", :null => false
57 end
57 end
58
58
59 create_table "grader_configurations", :force => true do |t|
59 create_table "grader_configurations", :force => true do |t|
60 t.string "key"
60 t.string "key"
61 t.string "value_type"
61 t.string "value_type"
62 t.string "value"
62 t.string "value"
63 - t.datetime "created_at", :null => false
63 + t.datetime "created_at", :null => false
64 - t.datetime "updated_at", :null => false
64 + t.datetime "updated_at", :null => false
65 - t.text "description", :limit => 16777215
65 + t.text "description"
66 end
66 end
67
67
68 create_table "grader_processes", :force => true do |t|
68 create_table "grader_processes", :force => true do |t|
69 t.string "host", :limit => 20
69 t.string "host", :limit => 20
70 t.integer "pid"
70 t.integer "pid"
71 t.string "mode"
71 t.string "mode"
72 t.boolean "active"
72 t.boolean "active"
73 t.datetime "created_at", :null => false
73 t.datetime "created_at", :null => false
74 t.datetime "updated_at", :null => false
74 t.datetime "updated_at", :null => false
75 t.integer "task_id"
75 t.integer "task_id"
76 t.string "task_type"
76 t.string "task_type"
77 t.boolean "terminated"
77 t.boolean "terminated"
78 end
78 end
79
79
80 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
80 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
81
81
82 create_table "languages", :force => true do |t|
82 create_table "languages", :force => true do |t|
83 t.string "name", :limit => 10
83 t.string "name", :limit => 10
84 t.string "pretty_name"
84 t.string "pretty_name"
85 t.string "ext", :limit => 10
85 t.string "ext", :limit => 10
86 t.string "common_ext"
86 t.string "common_ext"
87 end
87 end
88
88
89 create_table "logins", :force => true do |t|
89 create_table "logins", :force => true do |t|
90 t.string "user_id"
90 t.string "user_id"
91 t.string "ip_address"
91 t.string "ip_address"
92 t.datetime "created_at", :null => false
92 t.datetime "created_at", :null => false
93 t.datetime "updated_at", :null => false
93 t.datetime "updated_at", :null => false
94 end
94 end
95
95
96 create_table "messages", :force => true do |t|
96 create_table "messages", :force => true do |t|
97 t.integer "sender_id"
97 t.integer "sender_id"
98 t.integer "receiver_id"
98 t.integer "receiver_id"
99 t.integer "replying_message_id"
99 t.integer "replying_message_id"
100 - t.text "body", :limit => 16777215
100 + t.text "body"
101 t.boolean "replied"
101 t.boolean "replied"
102 - t.datetime "created_at", :null => false
102 + t.datetime "created_at", :null => false
103 - t.datetime "updated_at", :null => false
103 + t.datetime "updated_at", :null => false
104 end
104 end
105
105
106 create_table "problems", :force => true do |t|
106 create_table "problems", :force => true do |t|
107 t.string "name", :limit => 30
107 t.string "name", :limit => 30
108 t.string "full_name"
108 t.string "full_name"
109 t.integer "full_score"
109 t.integer "full_score"
110 t.date "date_added"
110 t.date "date_added"
111 t.boolean "available"
111 t.boolean "available"
112 t.string "url"
112 t.string "url"
113 t.integer "description_id"
113 t.integer "description_id"
114 t.boolean "test_allowed"
114 t.boolean "test_allowed"
115 t.boolean "output_only"
115 t.boolean "output_only"
116 t.string "description_filename"
116 t.string "description_filename"
117 end
117 end
118
118
119 create_table "rights", :force => true do |t|
119 create_table "rights", :force => true do |t|
120 t.string "name"
120 t.string "name"
121 t.string "controller"
121 t.string "controller"
122 t.string "action"
122 t.string "action"
123 end
123 end
124
124
125 create_table "rights_roles", :id => false, :force => true do |t|
125 create_table "rights_roles", :id => false, :force => true do |t|
126 t.integer "right_id"
126 t.integer "right_id"
127 t.integer "role_id"
127 t.integer "role_id"
128 end
128 end
129
129
130 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
130 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
131
131
132 create_table "roles", :force => true do |t|
132 create_table "roles", :force => true do |t|
133 t.string "name"
133 t.string "name"
134 end
134 end
135
135
136 create_table "roles_users", :id => false, :force => true do |t|
136 create_table "roles_users", :id => false, :force => true do |t|
137 t.integer "role_id"
137 t.integer "role_id"
138 t.integer "user_id"
138 t.integer "user_id"
139 end
139 end
140
140
141 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
141 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
142
142
143 create_table "sessions", :force => true do |t|
143 create_table "sessions", :force => true do |t|
144 t.string "session_id"
144 t.string "session_id"
145 - t.text "data", :limit => 16777215
145 + t.text "data"
146 t.datetime "updated_at"
146 t.datetime "updated_at"
147 end
147 end
148
148
149 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
149 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
150 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
150 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
151
151
152 create_table "sites", :force => true do |t|
152 create_table "sites", :force => true do |t|
153 t.string "name"
153 t.string "name"
154 t.boolean "started"
154 t.boolean "started"
155 t.datetime "start_time"
155 t.datetime "start_time"
156 t.datetime "created_at", :null => false
156 t.datetime "created_at", :null => false
157 t.datetime "updated_at", :null => false
157 t.datetime "updated_at", :null => false
158 t.integer "country_id"
158 t.integer "country_id"
159 t.string "password"
159 t.string "password"
160 end
160 end
161
161
162 create_table "submissions", :force => true do |t|
162 create_table "submissions", :force => true do |t|
163 t.integer "user_id"
163 t.integer "user_id"
164 t.integer "problem_id"
164 t.integer "problem_id"
165 t.integer "language_id"
165 t.integer "language_id"
166 - t.text "source", :limit => 16777215
166 + t.text "source"
167 t.binary "binary"
167 t.binary "binary"
168 t.datetime "submitted_at"
168 t.datetime "submitted_at"
169 t.datetime "compiled_at"
169 t.datetime "compiled_at"
170 - t.text "compiler_message", :limit => 16777215
170 + t.text "compiler_message"
171 t.datetime "graded_at"
171 t.datetime "graded_at"
172 t.integer "points"
172 t.integer "points"
173 - t.text "grader_comment", :limit => 16777215
173 + t.text "grader_comment"
174 t.integer "number"
174 t.integer "number"
175 t.string "source_filename"
175 t.string "source_filename"
176 + t.float "max_runtime"
177 + t.integer "peak_memory"
178 + t.integer "effective_code_length"
179 + t.string "ip_address"
176 end
180 end
177
181
178 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
182 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
179 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
183 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
180
184
181 create_table "tasks", :force => true do |t|
185 create_table "tasks", :force => true do |t|
182 t.integer "submission_id"
186 t.integer "submission_id"
183 t.datetime "created_at"
187 t.datetime "created_at"
184 t.integer "status"
188 t.integer "status"
185 t.datetime "updated_at"
189 t.datetime "updated_at"
186 end
190 end
187
191
188 create_table "test_pairs", :force => true do |t|
192 create_table "test_pairs", :force => true do |t|
189 t.integer "problem_id"
193 t.integer "problem_id"
190 - t.text "input", :limit => 2147483647
194 + t.text "input", :limit => 16777215
191 - t.text "solution", :limit => 2147483647
195 + t.text "solution", :limit => 16777215
192 - t.datetime "created_at", :null => false
196 + t.datetime "created_at", :null => false
193 - t.datetime "updated_at", :null => false
197 + t.datetime "updated_at", :null => false
194 end
198 end
195
199
196 create_table "test_requests", :force => true do |t|
200 create_table "test_requests", :force => true do |t|
197 t.integer "user_id"
201 t.integer "user_id"
198 t.integer "problem_id"
202 t.integer "problem_id"
199 t.integer "submission_id"
203 t.integer "submission_id"
200 t.string "input_file_name"
204 t.string "input_file_name"
201 t.string "output_file_name"
205 t.string "output_file_name"
202 t.string "running_stat"
206 t.string "running_stat"
203 t.integer "status"
207 t.integer "status"
204 - t.datetime "updated_at", :null => false
208 + t.datetime "updated_at", :null => false
205 t.datetime "submitted_at"
209 t.datetime "submitted_at"
206 t.datetime "compiled_at"
210 t.datetime "compiled_at"
207 - t.text "compiler_message", :limit => 16777215
211 + t.text "compiler_message"
208 t.datetime "graded_at"
212 t.datetime "graded_at"
209 t.string "grader_comment"
213 t.string "grader_comment"
210 - t.datetime "created_at", :null => false
214 + t.datetime "created_at", :null => false
211 t.float "running_time"
215 t.float "running_time"
212 t.string "exit_status"
216 t.string "exit_status"
213 t.integer "memory_usage"
217 t.integer "memory_usage"
214 end
218 end
215
219
216 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
220 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
217
221
218 create_table "user_contest_stats", :force => true do |t|
222 create_table "user_contest_stats", :force => true do |t|
219 t.integer "user_id"
223 t.integer "user_id"
220 t.datetime "started_at"
224 t.datetime "started_at"
221 t.datetime "created_at", :null => false
225 t.datetime "created_at", :null => false
222 t.datetime "updated_at", :null => false
226 t.datetime "updated_at", :null => false
223 t.boolean "forced_logout"
227 t.boolean "forced_logout"
224 end
228 end
225
229
226 create_table "users", :force => true do |t|
230 create_table "users", :force => true do |t|
227 t.string "login", :limit => 50
231 t.string "login", :limit => 50
228 t.string "full_name"
232 t.string "full_name"
229 t.string "hashed_password"
233 t.string "hashed_password"
230 t.string "salt", :limit => 5
234 t.string "salt", :limit => 5
231 t.string "alias"
235 t.string "alias"
232 t.string "email"
236 t.string "email"
233 t.integer "site_id"
237 t.integer "site_id"
234 t.integer "country_id"
238 t.integer "country_id"
235 t.boolean "activated", :default => false
239 t.boolean "activated", :default => false
236 t.datetime "created_at"
240 t.datetime "created_at"
237 t.datetime "updated_at"
241 t.datetime "updated_at"
242 + t.string "section"
238 end
243 end
239
244
240 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
245 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
241
246
242 end
247 end
You need to be logged in to leave comments. Login now