Description:
allow ta to set model submission
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r857:aa5ee227f493 - - 4 files changed: 13 inserted, 10 deleted

@@ -1,190 +1,190
1 require 'digest/sha1'
1 require 'digest/sha1'
2 require 'net/pop'
2 require 'net/pop'
3 require 'net/https'
3 require 'net/https'
4 require 'net/http'
4 require 'net/http'
5 require 'json'
5 require 'json'
6
6
7 class User < ActiveRecord::Base
7 class User < ActiveRecord::Base
8
8
9 has_and_belongs_to_many :roles
9 has_and_belongs_to_many :roles
10
10
11 #has_and_belongs_to_many :groups
11 #has_and_belongs_to_many :groups
12 has_many :groups_users, class_name: 'GroupUser'
12 has_many :groups_users, class_name: 'GroupUser'
13 has_many :groups, :through => :groups_users
13 has_many :groups, :through => :groups_users
14
14
15 has_many :test_requests, -> {order(submitted_at: :desc)}
15 has_many :test_requests, -> {order(submitted_at: :desc)}
16
16
17 has_many :messages, -> { order(created_at: :desc) },
17 has_many :messages, -> { order(created_at: :desc) },
18 :class_name => "Message",
18 :class_name => "Message",
19 :foreign_key => "sender_id"
19 :foreign_key => "sender_id"
20
20
21 has_many :replied_messages, -> { order(created_at: :desc) },
21 has_many :replied_messages, -> { order(created_at: :desc) },
22 :class_name => "Message",
22 :class_name => "Message",
23 :foreign_key => "receiver_id"
23 :foreign_key => "receiver_id"
24
24
25 has_many :logins
25 has_many :logins
26
26
27 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
27 has_one :contest_stat, :class_name => "UserContestStat", :dependent => :destroy
28
28
29 belongs_to :site
29 belongs_to :site
30 belongs_to :country
30 belongs_to :country
31
31
32 has_and_belongs_to_many :contests, -> { order(:name)}
32 has_and_belongs_to_many :contests, -> { order(:name)}
33
33
34 scope :activated_users, -> {where activated: true}
34 scope :activated_users, -> {where activated: true}
35
35
36 validates_presence_of :login
36 validates_presence_of :login
37 validates_uniqueness_of :login
37 validates_uniqueness_of :login
38 validates_format_of :login, :with => /\A[\_A-Za-z0-9]+\z/
38 validates_format_of :login, :with => /\A[\_A-Za-z0-9]+\z/
39 validates_length_of :login, :within => 3..30
39 validates_length_of :login, :within => 3..30
40
40
41 validates_presence_of :full_name
41 validates_presence_of :full_name
42 validates_length_of :full_name, :minimum => 1
42 validates_length_of :full_name, :minimum => 1
43
43
44 validates_presence_of :password, :if => :password_required?
44 validates_presence_of :password, :if => :password_required?
45 validates_length_of :password, :within => 4..50, :if => :password_required?
45 validates_length_of :password, :within => 4..50, :if => :password_required?
46 validates_confirmation_of :password, :if => :password_required?
46 validates_confirmation_of :password, :if => :password_required?
47
47
48 validates_format_of :email,
48 validates_format_of :email,
49 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
49 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
50 :if => :email_validation?
50 :if => :email_validation?
51 validate :uniqueness_of_email_from_activated_users,
51 validate :uniqueness_of_email_from_activated_users,
52 :if => :email_validation?
52 :if => :email_validation?
53 validate :enough_time_interval_between_same_email_registrations,
53 validate :enough_time_interval_between_same_email_registrations,
54 :if => :email_validation?
54 :if => :email_validation?
55
55
56 # these are for ytopc
56 # these are for ytopc
57 # disable for now
57 # disable for now
58 #validates_presence_of :province
58 #validates_presence_of :province
59
59
60 attr_accessor :password
60 attr_accessor :password
61
61
62 before_save :encrypt_new_password
62 before_save :encrypt_new_password
63 before_save :assign_default_site
63 before_save :assign_default_site
64 before_save :assign_default_contest
64 before_save :assign_default_contest
65
65
66 # this is for will_paginate
66 # this is for will_paginate
67 cattr_reader :per_page
67 cattr_reader :per_page
68 @@per_page = 50
68 @@per_page = 50
69
69
70 def self.authenticate(login, password)
70 def self.authenticate(login, password)
71 user = find_by_login(login)
71 user = find_by_login(login)
72 if user
72 if user
73 return user if user.authenticated?(password)
73 return user if user.authenticated?(password)
74 end
74 end
75 end
75 end
76
76
77 def authenticated?(password)
77 def authenticated?(password)
78 if self.activated
78 if self.activated
79 hashed_password == User.encrypt(password,self.salt)
79 hashed_password == User.encrypt(password,self.salt)
80 else
80 else
81 false
81 false
82 end
82 end
83 end
83 end
84
84
85 def login_with_name
85 def login_with_name
86 "[#{login}] #{full_name}"
86 "[#{login}] #{full_name}"
87 end
87 end
88
88
89 def admin?
89 def admin?
90 has_role?('admin')
90 has_role?('admin')
91 end
91 end
92
92
93 def has_role?(role)
93 def has_role?(role)
94 - self.roles.where(name: role).count > 0
94 + self.roles.where(name: [role,'admin']).count > 0
95 end
95 end
96
96
97 def email_for_editing
97 def email_for_editing
98 if self.email==nil
98 if self.email==nil
99 "(unknown)"
99 "(unknown)"
100 elsif self.email==''
100 elsif self.email==''
101 "(blank)"
101 "(blank)"
102 else
102 else
103 self.email
103 self.email
104 end
104 end
105 end
105 end
106
106
107 def email_for_editing=(e)
107 def email_for_editing=(e)
108 self.email=e
108 self.email=e
109 end
109 end
110
110
111 def alias_for_editing
111 def alias_for_editing
112 if self.alias==nil
112 if self.alias==nil
113 "(unknown)"
113 "(unknown)"
114 elsif self.alias==''
114 elsif self.alias==''
115 "(blank)"
115 "(blank)"
116 else
116 else
117 self.alias
117 self.alias
118 end
118 end
119 end
119 end
120
120
121 def alias_for_editing=(e)
121 def alias_for_editing=(e)
122 self.alias=e
122 self.alias=e
123 end
123 end
124
124
125 def activation_key
125 def activation_key
126 if self.hashed_password==nil
126 if self.hashed_password==nil
127 encrypt_new_password
127 encrypt_new_password
128 end
128 end
129 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
129 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
130 end
130 end
131
131
132 def verify_activation_key(key)
132 def verify_activation_key(key)
133 key == activation_key
133 key == activation_key
134 end
134 end
135
135
136 def self.random_password(length=5)
136 def self.random_password(length=5)
137 chars = 'abcdefghjkmnopqrstuvwxyz'
137 chars = 'abcdefghjkmnopqrstuvwxyz'
138 password = ''
138 password = ''
139 length.times { password << chars[rand(chars.length - 1)] }
139 length.times { password << chars[rand(chars.length - 1)] }
140 password
140 password
141 end
141 end
142
142
143
143
144 # Contest information
144 # Contest information
145
145
146 def self.find_users_with_no_contest()
146 def self.find_users_with_no_contest()
147 users = User.all
147 users = User.all
148 return users.find_all { |u| u.contests.length == 0 }
148 return users.find_all { |u| u.contests.length == 0 }
149 end
149 end
150
150
151
151
152 def contest_time_left
152 def contest_time_left
153 if GraderConfiguration.contest_mode?
153 if GraderConfiguration.contest_mode?
154 return nil if site==nil
154 return nil if site==nil
155 return site.time_left
155 return site.time_left
156 elsif GraderConfiguration.indv_contest_mode?
156 elsif GraderConfiguration.indv_contest_mode?
157 time_limit = GraderConfiguration.contest_time_limit
157 time_limit = GraderConfiguration.contest_time_limit
158 if time_limit == nil
158 if time_limit == nil
159 return nil
159 return nil
160 end
160 end
161 if contest_stat==nil or contest_stat.started_at==nil
161 if contest_stat==nil or contest_stat.started_at==nil
162 return (Time.now.gmtime + time_limit) - Time.now.gmtime
162 return (Time.now.gmtime + time_limit) - Time.now.gmtime
163 else
163 else
164 finish_time = contest_stat.started_at + time_limit
164 finish_time = contest_stat.started_at + time_limit
165 current_time = Time.now.gmtime
165 current_time = Time.now.gmtime
166 if current_time > finish_time
166 if current_time > finish_time
167 return 0
167 return 0
168 else
168 else
169 return finish_time - current_time
169 return finish_time - current_time
170 end
170 end
171 end
171 end
172 else
172 else
173 return nil
173 return nil
174 end
174 end
175 end
175 end
176
176
177 def contest_finished?
177 def contest_finished?
178 if GraderConfiguration.contest_mode?
178 if GraderConfiguration.contest_mode?
179 return false if site==nil
179 return false if site==nil
180 return site.finished?
180 return site.finished?
181 elsif GraderConfiguration.indv_contest_mode?
181 elsif GraderConfiguration.indv_contest_mode?
182 return false if self.contest_stat==nil
182 return false if self.contest_stat==nil
183 return contest_time_left == 0
183 return contest_time_left == 0
184 else
184 else
185 return false
185 return false
186 end
186 end
187 end
187 end
188
188
189 def contest_started?
189 def contest_started?
190 if GraderConfiguration.indv_contest_mode?
190 if GraderConfiguration.indv_contest_mode?
@@ -1,154 +1,156
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 .info_param { font-weight: bold;text-align: right; }
5 .info_param { font-weight: bold;text-align: right; }
6 .tooltip {
6 .tooltip {
7 font-family: Verdana,sans-serif;
7 font-family: Verdana,sans-serif;
8 font-weight: normal;
8 font-weight: normal;
9 text-align: left;
9 text-align: left;
10 font-size: 1.0em;
10 font-size: 1.0em;
11 color: black;
11 color: black;
12 line-height: 1.1;
12 line-height: 1.1;
13 display: none;
13 display: none;
14 min-width: 20em;
14 min-width: 20em;
15 position: absolute;
15 position: absolute;
16 left: 25px;
16 left: 25px;
17 bottom: 5px;
17 bottom: 5px;
18 border: 1px solid;
18 border: 1px solid;
19 padding: 5px;
19 padding: 5px;
20 background-color: #FFF;
20 background-color: #FFF;
21 word-wrap: break-word;
21 word-wrap: break-word;
22 z-index: 9999;
22 z-index: 9999;
23 overflow: auto;
23 overflow: auto;
24 }
24 }
25
25
26
26
27 .container-fluid
27 .container-fluid
28 .row
28 .row
29 .col-md-8
29 .col-md-8
30 .card
30 .card
31 .card-body
31 .card-body
32 %h2.card-title Submission History
32 %h2.card-title Submission History
33 %canvas#chart{height: '50px'}
33 %canvas#chart{height: '50px'}
34
34
35 .col-md-4
35 .col-md-4
36 .card
36 .card
37 .card-body
37 .card-body
38 %h2.card-title General Info
38 %h2.card-title General Info
39 .row
39 .row
40 .col-sm-6
40 .col-sm-6
41 Subs
41 Subs
42 .col-sm-6
42 .col-sm-6
43 = @summary[:count]
43 = @summary[:count]
44 .row
44 .row
45 .col-sm-6
45 .col-sm-6
46 Solved/Attempted User
46 Solved/Attempted User
47 .col-sm-6
47 .col-sm-6
48 #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
48 #{@summary[:solve]}/#{@summary[:attempt]} (#{(@summary[:solve]*100.0/@summary[:attempt]).round(1)}%)
49 .row
49 .row
50 .col-md-4
50 .col-md-4
51 .card
51 .card
52 .card-body
52 .card-body
53 %h2.card-title Model submission
53 %h2.card-title Model submission
54 %table.table.table-hover
54 %table.table.table-hover
55 %thead
55 %thead
56 %tr
56 %tr
57 - %th #Sub
57 + %th #Sub (lang)
58 %th Author
58 %th Author
59 %tbody
59 %tbody
60 - @model_subs.each do |sub|
60 - @model_subs.each do |sub|
61 %tr
61 %tr
62 - %td= link_to "##{sub.id}", submission_path(sub)
62 + %td
63 + = link_to "##{sub.id}", submission_path(sub)
64 + = "(#{sub.language.pretty_name})"
63 %td= sub.user.full_name
65 %td= sub.user.full_name
64 .col-md-8
66 .col-md-8
65 - if @best
67 - if @best
66 .card
68 .card
67 .card-body
69 .card-body
68 %h2.card-title Top Submissions
70 %h2.card-title Top Submissions
69 %table.table.table-hover
71 %table.table.table-hover
70 %thead
72 %thead
71 %tr
73 %tr
72 %th Language
74 %th Language
73 %th Best runtime (ms)
75 %th Best runtime (ms)
74 %th Best memory (kbytes)
76 %th Best memory (kbytes)
75 %th Shortest Code (bytes)
77 %th Shortest Code (bytes)
76 %th First solver
78 %th First solver
77 %tbody
79 %tbody
78 %tr.bg-warning
80 %tr.bg-warning
79 %td
81 %td
80 Overall
82 Overall
81 %td
83 %td
82 by #{link_to @best[:runtime][:user], stat_user_path(@best[:runtime][:user_id])}
84 by #{link_to @best[:runtime][:user], stat_user_path(@best[:runtime][:user_id])}
83 %br
85 %br
84 using <span class="text-success">#{@best[:runtime][:lang]}</span>
86 using <span class="text-success">#{@best[:runtime][:lang]}</span>
85 %br
87 %br
86 with <span class="text-success">#{@best[:runtime][:value] * 1000} milliseconds</span>
88 with <span class="text-success">#{@best[:runtime][:value] * 1000} milliseconds</span>
87 %br= link_to "#" + @best[:runtime][:sub_id].to_s, submission_path(@best[:runtime][:sub_id])
89 %br= link_to "#" + @best[:runtime][:sub_id].to_s, submission_path(@best[:runtime][:sub_id])
88 %td
90 %td
89 by #{link_to @best[:memory][:user], stat_user_path(@best[:memory][:user_id])}
91 by #{link_to @best[:memory][:user], stat_user_path(@best[:memory][:user_id])}
90 %br
92 %br
91 using <span class="text-success">#{@best[:memory][:lang]}</span>
93 using <span class="text-success">#{@best[:memory][:lang]}</span>
92 %br
94 %br
93 with <span class="text-success">#{number_with_delimiter(@best[:memory][:value])} kbytes </span>
95 with <span class="text-success">#{number_with_delimiter(@best[:memory][:value])} kbytes </span>
94 %br= link_to "#" + @best[:memory][:sub_id].to_s, submission_path(@best[:memory][:sub_id])
96 %br= link_to "#" + @best[:memory][:sub_id].to_s, submission_path(@best[:memory][:sub_id])
95 %td
97 %td
96 by #{link_to @best[:length][:user], stat_user_path(@best[:length][:user_id])}
98 by #{link_to @best[:length][:user], stat_user_path(@best[:length][:user_id])}
97 %br
99 %br
98 using <span class="text-success">#{@best[:length][:lang]}</span>
100 using <span class="text-success">#{@best[:length][:lang]}</span>
99 %br
101 %br
100 with <span class="text-success">#{@best[:length][:value]} bytes</span>
102 with <span class="text-success">#{@best[:length][:value]} bytes</span>
101 %br= link_to "#" + @best[:length][:sub_id].to_s, submission_path(@best[:length][:sub_id])
103 %br= link_to "#" + @best[:length][:sub_id].to_s, submission_path(@best[:length][:sub_id])
102 %td
104 %td
103 - if @best[:first][:user] != '(NULL)'
105 - if @best[:first][:user] != '(NULL)'
104 #{link_to @best[:first][:user], stat_user_path(@best[:first][:user_id])} is the first solver
106 #{link_to @best[:first][:user], stat_user_path(@best[:first][:user_id])} is the first solver
105 %br
107 %br
106 using <span class="text-success">#{@best[:first][:lang]}</span>
108 using <span class="text-success">#{@best[:first][:lang]}</span>
107 %br
109 %br
108 on <span class="text-success">#{@best[:first][:value]}</span>
110 on <span class="text-success">#{@best[:first][:value]}</span>
109 %br= link_to "#" + @best[:first][:sub_id].to_s, submission_path( @best[:first][:sub_id])
111 %br= link_to "#" + @best[:first][:sub_id].to_s, submission_path( @best[:first][:sub_id])
110 - else
112 - else
111 no first solver
113 no first solver
112 - @by_lang.each do |lang,value|
114 - @by_lang.each do |lang,value|
113 %tr
115 %tr
114 %td= lang
116 %td= lang
115 %td
117 %td
116 = link_to value[:runtime][:user], stat_user_path(value[:runtime][:user_id])
118 = link_to value[:runtime][:user], stat_user_path(value[:runtime][:user_id])
117 %br
119 %br
118 = "#{(value[:runtime][:value] * 1000).to_i} @"
120 = "#{(value[:runtime][:value] * 1000).to_i} @"
119 = link_to "#" + value[:runtime][:sub_id].to_s, submission_path( value[:runtime][:sub_id])
121 = link_to "#" + value[:runtime][:sub_id].to_s, submission_path( value[:runtime][:sub_id])
120 %td
122 %td
121 = link_to value[:memory][:user], stat_user_path( value[:memory][:user_id])
123 = link_to value[:memory][:user], stat_user_path( value[:memory][:user_id])
122 %br
124 %br
123 = "#{number_with_delimiter(value[:memory][:value])} @"
125 = "#{number_with_delimiter(value[:memory][:value])} @"
124 = link_to "#" + value[:memory][:sub_id].to_s, submission_path(value[:memory][:sub_id])
126 = link_to "#" + value[:memory][:sub_id].to_s, submission_path(value[:memory][:sub_id])
125 %td
127 %td
126 = link_to value[:length][:user], stat_user_path(value[:length][:user_id])
128 = link_to value[:length][:user], stat_user_path(value[:length][:user_id])
127 %br
129 %br
128 = "#{value[:length][:value]} @"
130 = "#{value[:length][:value]} @"
129 = link_to "#" + value[:length][:sub_id].to_s, submission_path(value[:length][:sub_id])
131 = link_to "#" + value[:length][:sub_id].to_s, submission_path(value[:length][:sub_id])
130 %td
132 %td
131 - if value[:first][:user] != '(NULL)' #TODO: i know... this is wrong...
133 - if value[:first][:user] != '(NULL)' #TODO: i know... this is wrong...
132 = link_to value[:first][:user], stat_user_path(value[:first][:user_id])
134 = link_to value[:first][:user], stat_user_path(value[:first][:user_id])
133 %br
135 %br
134 = "#{value[:first][:value]} @"
136 = "#{value[:first][:value]} @"
135 = link_to "#" + value[:first][:sub_id].to_s, submission_path( value[:first][:sub_id])
137 = link_to "#" + value[:first][:sub_id].to_s, submission_path( value[:first][:sub_id])
136
138
137 %script{src:"https://cdn.jsdelivr.net/npm/chart.js"}
139 %script{src:"https://cdn.jsdelivr.net/npm/chart.js"}
138 :javascript
140 :javascript
139 data = #{@chart_dataset}
141 data = #{@chart_dataset}
140 config = {
142 config = {
141 type: 'bar',
143 type: 'bar',
142 data: data,
144 data: data,
143 options: {
145 options: {
144 plugins: {
146 plugins: {
145 legend: {
147 legend: {
146 display: false
148 display: false
147 },
149 },
148 },
150 },
149 }
151 }
150 }
152 }
151 Chart.defaults.font.size = 15
153 Chart.defaults.font.size = 15
152 //Chart.defaults.font.family = 'Sarabun Light'
154 //Chart.defaults.font.family = 'Sarabun Light'
153 chart = new Chart($('#chart'),config)
155 chart = new Chart($('#chart'),config)
154
156
@@ -1,29 +1,30
1
1
2 /- if params[:id]
2 /- if params[:id]
3 / %h1 Tasks Hall of Fame
3 / %h1 Tasks Hall of Fame
4 / = link_to('[back to All-Time Hall of Fame]', action: 'problem_hof', id: nil )
4 / = link_to('[back to All-Time Hall of Fame]', action: 'problem_hof', id: nil )
5 /- else
5 /- else
6 / %h1 All-Time Hall of Fame
6 / %h1 All-Time Hall of Fame
7
7
8 .panel.panel-info
8 .panel.panel-info
9 .panel-heading
9 .panel-heading
10 Select Task
10 Select Task
11 .panel-body
11 .panel-body
12 .form-inline
12 .form-inline
13 = select 'report',
13 = select 'report',
14 'problem_id',
14 'problem_id',
15 @problems.collect {|p| ["[#{p.name}] #{p.full_name}", problem_hof_report_path(p)]},
15 @problems.collect {|p| ["[#{p.name}] #{p.full_name}", problem_hof_report_path(p)]},
16 {:selected => problem_hof_report_path(@problem)},
16 {:selected => problem_hof_report_path(@problem)},
17 { class: 'select2 form-control' }
17 { class: 'select2 form-control' }
18 %button.btn.btn-primary.btn-sm.go-button#problem_go{data: {source: "#report_problem_id"}} Go
18 %button.btn.btn-primary.btn-sm.go-button#problem_go{data: {source: "#report_problem_id"}} Go
19
19
20
20
21 - unless params[:id]
21 - unless params[:id]
22 /=render partial: 'all_time_hof'
22 /=render partial: 'all_time_hof'
23 Please select a problem.
23 Please select a problem.
24 - else
24 - else
25 - %h1 [#{Problem.find(params[:id]).name}] #{Problem.find(params[:id]).full_name}
25 + %h1
26 - -# %h2 Submission History
26 + [#{Problem.find(params[:id]).name}] #{Problem.find(params[:id]).full_name}
27 - -# =render partial: 'application/bar_graph', locals: { histogram: @histogram }
27 + - if @current_user.has_role?('ta')
28 + %a{href:stat_problem_path(@problem)} (stat)
28 =render partial: 'task_hof'
29 =render partial: 'task_hof'
29
30
@@ -1,128 +1,128
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
9
10
10
11 .containter
11 .containter
12 .row
12 .row
13 .col-md-7
13 .col-md-7
14 %h2 Source Code
14 %h2 Source Code
15 .col-md-5
15 .col-md-5
16 %h2 Stat
16 %h2 Stat
17 .row
17 .row
18 .col-md-7
18 .col-md-7
19 %div#editor{ style: "font-size: 14px; height: 400px; border-radius:5px;" }
19 %div#editor{ style: "font-size: 14px; height: 400px; border-radius:5px;" }
20 :javascript
20 :javascript
21 e = ace.edit("editor")
21 e = ace.edit("editor")
22 e.setOptions({ maxLines: Infinity })
22 e.setOptions({ maxLines: Infinity })
23 e.setValue($("#data").text())
23 e.setValue($("#data").text())
24 e.gotoLine(1)
24 e.gotoLine(1)
25 e.getSession().setMode("#{get_ace_mode(@submission.language)}")
25 e.getSession().setMode("#{get_ace_mode(@submission.language)}")
26 e.setReadOnly(true)
26 e.setReadOnly(true)
27 .col-md-5
27 .col-md-5
28 %table.table.table-striped
28 %table.table.table-striped
29 %tr
29 %tr
30 %td.text-right
30 %td.text-right
31 %strong User
31 %strong User
32 %td
32 %td
33 - if @current_user.admin? ||@current_user == @submission.user
33 - if @current_user.admin? ||@current_user == @submission.user
34 - if @submission.user
34 - if @submission.user
35 = link_to "#{@submission.user.login}", stat_user_path(@submission.user)
35 = link_to "#{@submission.user.login}", stat_user_path(@submission.user)
36 = @submission.user.full_name
36 = @submission.user.full_name
37 - else
37 - else
38 = "(n/a)"
38 = "(n/a)"
39 - else
39 - else
40 = '-- REDACTED --'
40 = '-- REDACTED --'
41 %tr
41 %tr
42 %td.text-right
42 %td.text-right
43 %strong Task
43 %strong Task
44 %td
44 %td
45 - if @submission.problem!=nil
45 - if @submission.problem!=nil
46 = link_to "[#{@submission.problem.name}]", stat_problem_path(@submission.problem)
46 = link_to "[#{@submission.problem.name}]", stat_problem_path(@submission.problem)
47 = @submission.problem.full_name
47 = @submission.problem.full_name
48 = link_to_description_if_any "[download] <span class='glyphicon glyphicon-file'></span>".html_safe, @submission.problem
48 = link_to_description_if_any "[download] <span class='glyphicon glyphicon-file'></span>".html_safe, @submission.problem
49 - else
49 - else
50 = "(n/a)"
50 = "(n/a)"
51 %tr
51 %tr
52 %td.text-right
52 %td.text-right
53 %strong Tries
53 %strong Tries
54 %td= @submission.number
54 %td= @submission.number
55 %tr
55 %tr
56 %td.text-right
56 %td.text-right
57 %strong Language
57 %strong Language
58 %td= @submission.language.pretty_name
58 %td= @submission.language.pretty_name
59 %tr
59 %tr
60 %td.text-right
60 %td.text-right
61 %strong Submitted
61 %strong Submitted
62 %td #{time_ago_in_words(@submission.submitted_at)} ago (at #{@submission.submitted_at.to_formatted_s(:long)})
62 %td #{time_ago_in_words(@submission.submitted_at)} ago (at #{@submission.submitted_at.to_formatted_s(:long)})
63 %tr
63 %tr
64 %td.text-right
64 %td.text-right
65 %strong Graded
65 %strong Graded
66 - if @submission.graded_at
66 - if @submission.graded_at
67 %td #{time_ago_in_words(@submission.graded_at)} ago (at #{@submission.graded_at.to_formatted_s(:long)})
67 %td #{time_ago_in_words(@submission.graded_at)} ago (at #{@submission.graded_at.to_formatted_s(:long)})
68 - else
68 - else
69 %td -
69 %td -
70 %tr
70 %tr
71 %td.text-right
71 %td.text-right
72 %strong Points
72 %strong Points
73 %td #{@submission.points}/#{@submission.try(:problem).try(:full_score)}
73 %td #{@submission.points}/#{@submission.try(:problem).try(:full_score)}
74 %tr
74 %tr
75 %td.text-right
75 %td.text-right
76 %strong Comment
76 %strong Comment
77 %td #{@submission.grader_comment}
77 %td #{@submission.grader_comment}
78 %tr
78 %tr
79 %td.text-right
79 %td.text-right
80 %strong Runtime (s)
80 %strong Runtime (s)
81 %td #{@submission.max_runtime}
81 %td #{@submission.max_runtime}
82 %tr
82 %tr
83 %td.text-right
83 %td.text-right
84 %strong Memory (kb)
84 %strong Memory (kb)
85 %td #{@submission.peak_memory}
85 %td #{@submission.peak_memory}
86 %tr
86 %tr
87 %td.text-right
87 %td.text-right
88 %strong Compiler result
88 %strong Compiler result
89 %td
89 %td
90 %button.btn.btn-info.btn-xs{type: 'button', data: {toggle: 'modal', target: '#compiler'}}
90 %button.btn.btn-info.btn-xs{type: 'button', data: {toggle: 'modal', target: '#compiler'}}
91 view
91 view
92 %tr
92 %tr
93 %td.text-right
93 %td.text-right
94 %strong Grading Task Status
94 %strong Grading Task Status
95 %td
95 %td
96 = @task.status_str if @task
96 = @task.status_str if @task
97 - - if session[:admin]
97 + - if @current_user.admin?
98 = link_to "rejudge", rejudge_submission_path, data: {remote: true}, class: 'btn btn-info btn-xs'
98 = link_to "rejudge", rejudge_submission_path, data: {remote: true}, class: 'btn btn-info btn-xs'
99 - - if session[:admin]
99 + - if @current_user.has_role?('ta')
100 %tr
100 %tr
101 %td.text-right
101 %td.text-right
102 %strong IP
102 %strong IP
103 %td #{@submission.ip_address}
103 %td #{@submission.ip_address}
104 %tr
104 %tr
105 %td.text-right
105 %td.text-right
106 %strong Model solution
106 %strong Model solution
107 %td
107 %td
108 - if @submission.tag_model?
108 - if @submission.tag_model?
109 YES
109 YES
110 - - if session[:admin]
110 + - if @current_user.has_role?('ta')
111 = link_to "remove model status", set_tag_submission_path(@submission, tag: :default), class: 'btn btn-warning btn-xs'
111 = link_to "remove model status", set_tag_submission_path(@submission, tag: :default), class: 'btn btn-warning btn-xs'
112 - else
112 - else
113 No
113 No
114 - - if session[:admin]
114 + - if @current_user.has_role?('ta')
115 = link_to "set as model solution", set_tag_submission_path(@submission, tag: :model), class: 'btn btn-success btn-xs'
115 = link_to "set as model solution", set_tag_submission_path(@submission, tag: :model), class: 'btn btn-success btn-xs'
116
116
117
117
118 .modal.fade#compiler{tabindex: -1,role: 'dialog'}
118 .modal.fade#compiler{tabindex: -1,role: 'dialog'}
119 .modal-dialog.modal-lg{role:'document'}
119 .modal-dialog.modal-lg{role:'document'}
120 .modal-content
120 .modal-content
121 .modal-header
121 .modal-header
122 %button.close{type: 'button', data: {dismissed: :modal}, aria: {label: 'close'}}
122 %button.close{type: 'button', data: {dismissed: :modal}, aria: {label: 'close'}}
123 %span{aria: {hidden: 'true'}, data: {dismiss: 'modal'}} &times;
123 %span{aria: {hidden: 'true'}, data: {dismiss: 'modal'}} &times;
124 %h4 Compiler message
124 %h4 Compiler message
125 .modal-body
125 .modal-body
126 %pre#compiler_msg= @submission.compiler_message
126 %pre#compiler_msg= @submission.compiler_message
127 .modal-footer
127 .modal-footer
128 %button.btn.btn-default{type: 'button', data: {dismiss: 'modal'}} Close
128 %button.btn.btn-default{type: 'button', data: {dismiss: 'modal'}} Close
You need to be logged in to leave comments. Login now