Description:
submission report
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r790:7ddf708c67bd - - 16 files changed: 374 inserted, 350 deleted

@@ -0,0 +1,20
1 + .panel.panel-primary
2 + .panel-heading
3 + Date ranges
4 + .panel-body
5 + .row.form-group
6 + .col-md-4
7 + From Date:
8 + .col-md-6
9 + .input-group.date
10 + = text_field_tag :since_datetime, nil, class: 'form-control'
11 + %span.input-group-addon
12 + %span.glyphicon.glyphicon-calendar
13 + .row.form-group
14 + .col-md-4
15 + Until Date:
16 + .col-md-6
17 + .input-group.date
18 + = text_field_tag :until_datetime, nil, class: 'form-control'
19 + %span.input-group-addon
20 + %span.glyphicon.glyphicon-calendar
@@ -0,0 +1,5
1 + class AddIndexToSubmission < ActiveRecord::Migration[5.2]
2 + def change
3 + add_index :submissions, :submitted_at
4 + end
5 + end
@@ -0,0 +1,5
1 + class AddIdToGroupUser < ActiveRecord::Migration[5.2]
2 + def change
3 + add_column :groups_users, :id, :primary_key
4 + end
5 + end
@@ -47,38 +47,38
47 #in-place editor
47 #in-place editor
48 gem 'best_in_place', '~> 3.0.1'
48 gem 'best_in_place', '~> 3.0.1'
49
49
50 # jquery addition
50 # jquery addition
51 gem 'jquery-rails'
51 gem 'jquery-rails'
52 gem 'jquery-ui-rails'
52 gem 'jquery-ui-rails'
53 - gem 'jquery-timepicker-addon-rails'
53 + #gem 'jquery-timepicker-addon-rails'
54 gem 'jquery-tablesorter'
54 gem 'jquery-tablesorter'
55 gem 'jquery-countdown-rails'
55 gem 'jquery-countdown-rails'
56
56
57 #syntax highlighter
57 #syntax highlighter
58 gem 'rouge'
58 gem 'rouge'
59
59
60 #bootstrap add-ons
60 #bootstrap add-ons
61 gem 'bootstrap-sass', '~> 3.4.1'
61 gem 'bootstrap-sass', '~> 3.4.1'
62 gem 'bootstrap-switch-rails'
62 gem 'bootstrap-switch-rails'
63 gem 'bootstrap-toggle-rails'
63 gem 'bootstrap-toggle-rails'
64 gem 'autoprefixer-rails'
64 gem 'autoprefixer-rails'
65 - gem 'momentjs-rails'
65 + gem 'momentjs-rails', '>= 2.9.0'
66 gem 'rails_bootstrap_sortable'
66 gem 'rails_bootstrap_sortable'
67 - gem 'bootstrap-datepicker-rails'
67 + #gem 'bootstrap-datepicker-rails'
68 - gem 'bootstrap3-datetimepicker-rails'
68 + gem 'bootstrap3-datetimepicker-rails', '~> 4.17.47'
69 #gem 'jquery-datatables-rails'
69 #gem 'jquery-datatables-rails'
70
70
71 #----------- user interface -----------------
71 #----------- user interface -----------------
72 gem 'simple_form'
72 gem 'simple_form'
73 #select 2
73 #select 2
74 gem 'select2-rails'
74 gem 'select2-rails'
75 #ace editor
75 #ace editor
76 gem 'ace-rails-ap'
76 gem 'ace-rails-ap'
77 #paginator
77 #paginator
78 - gem 'will_paginate', '~> 3.0.7'
78 + #gem 'will_paginate', '~> 3.0.7'
79
79
80 gem 'mail'
80 gem 'mail'
81 gem 'rdiscount'
81 gem 'rdiscount'
82 gem 'dynamic_form'
82 gem 'dynamic_form'
83 gem 'in_place_editing'
83 gem 'in_place_editing'
84 #gem 'verification', :git => 'https://github.com/sikachu/verification.git'
84 #gem 'verification', :git => 'https://github.com/sikachu/verification.git'
@@ -61,14 +61,12
61 best_in_place (3.0.3)
61 best_in_place (3.0.3)
62 actionpack (>= 3.2)
62 actionpack (>= 3.2)
63 railties (>= 3.2)
63 railties (>= 3.2)
64 bindex (0.8.1)
64 bindex (0.8.1)
65 bootsnap (1.4.6)
65 bootsnap (1.4.6)
66 msgpack (~> 1.0)
66 msgpack (~> 1.0)
67 - bootstrap-datepicker-rails (1.8.0.1)
68 - railties (>= 3.0)
69 bootstrap-sass (3.4.1)
67 bootstrap-sass (3.4.1)
70 autoprefixer-rails (>= 5.2.1)
68 autoprefixer-rails (>= 5.2.1)
71 sassc (>= 2.0.0)
69 sassc (>= 2.0.0)
72 bootstrap-switch-rails (3.3.4)
70 bootstrap-switch-rails (3.3.4)
73 bootstrap-toggle-rails (2.2.1.0)
71 bootstrap-toggle-rails (2.2.1.0)
74 bootstrap3-datetimepicker-rails (4.17.47)
72 bootstrap3-datetimepicker-rails (4.17.47)
@@ -119,17 +117,12
119 i18n (1.8.2)
117 i18n (1.8.2)
120 concurrent-ruby (~> 1.0)
118 concurrent-ruby (~> 1.0)
121 in_place_editing (1.2.0)
119 in_place_editing (1.2.0)
122 jbuilder (2.10.0)
120 jbuilder (2.10.0)
123 activesupport (>= 5.0.0)
121 activesupport (>= 5.0.0)
124 jquery-countdown-rails (2.0.2)
122 jquery-countdown-rails (2.0.2)
125 - jquery-datatables-rails (3.4.0)
126 - actionpack (>= 3.1)
127 - jquery-rails
128 - railties (>= 3.1)
129 - sass-rails
130 jquery-rails (4.3.3)
123 jquery-rails (4.3.3)
131 rails-dom-testing (>= 1, < 3)
124 rails-dom-testing (>= 1, < 3)
132 railties (>= 4.2.0)
125 railties (>= 4.2.0)
133 thor (>= 0.14, < 2.0)
126 thor (>= 0.14, < 2.0)
134 jquery-tablesorter (1.26.1)
127 jquery-tablesorter (1.26.1)
135 railties (>= 3.2, < 6)
128 railties (>= 3.2, < 6)
@@ -211,23 +204,12
211 rouge (3.3.0)
204 rouge (3.3.0)
212 ruby-progressbar (1.10.0)
205 ruby-progressbar (1.10.0)
213 ruby_dep (1.5.0)
206 ruby_dep (1.5.0)
214 ruby_parser (3.13.1)
207 ruby_parser (3.13.1)
215 sexp_processor (~> 4.9)
208 sexp_processor (~> 4.9)
216 rubyzip (1.3.0)
209 rubyzip (1.3.0)
217 - sass (3.7.4)
218 - sass-listen (~> 4.0.0)
219 - sass-listen (4.0.0)
220 - rb-fsevent (~> 0.9, >= 0.9.4)
221 - rb-inotify (~> 0.9, >= 0.9.7)
222 - sass-rails (5.0.7)
223 - railties (>= 4.0.0, < 6)
224 - sass (~> 3.1)
225 - sprockets (>= 2.8, < 4.0)
226 - sprockets-rails (>= 2.0, < 4.0)
227 - tilt (>= 1.1, < 3)
228 sassc (2.2.1)
210 sassc (2.2.1)
229 ffi (~> 1.9)
211 ffi (~> 1.9)
230 sassc-rails (2.1.2)
212 sassc-rails (2.1.2)
231 railties (>= 4.0.0)
213 railties (>= 4.0.0)
232 sassc (>= 2.0)
214 sassc (>= 2.0)
233 sprockets (> 3.0)
215 sprockets (> 3.0)
@@ -269,13 +251,12
269 bindex (>= 0.4.0)
251 bindex (>= 0.4.0)
270 railties (>= 5.0)
252 railties (>= 5.0)
271 webdriver (0.5.0)
253 webdriver (0.5.0)
272 websocket-driver (0.7.1)
254 websocket-driver (0.7.1)
273 websocket-extensions (>= 0.1.0)
255 websocket-extensions (>= 0.1.0)
274 websocket-extensions (0.1.4)
256 websocket-extensions (0.1.4)
275 - will_paginate (3.0.12)
276 xpath (3.2.0)
257 xpath (3.2.0)
277 nokogiri (~> 1.8)
258 nokogiri (~> 1.8)
278 yaml_db (0.7.0)
259 yaml_db (0.7.0)
279 rails (>= 3.0)
260 rails (>= 3.0)
280 rake (>= 0.8.7)
261 rake (>= 0.8.7)
281
262
@@ -285,36 +266,34
285 DEPENDENCIES
266 DEPENDENCIES
286 ace-rails-ap
267 ace-rails-ap
287 activerecord-session_store
268 activerecord-session_store
288 autoprefixer-rails
269 autoprefixer-rails
289 best_in_place (~> 3.0.1)
270 best_in_place (~> 3.0.1)
290 bootsnap (>= 1.1.0)
271 bootsnap (>= 1.1.0)
291 - bootstrap-datepicker-rails
292 bootstrap-sass (~> 3.4.1)
272 bootstrap-sass (~> 3.4.1)
293 bootstrap-switch-rails
273 bootstrap-switch-rails
294 bootstrap-toggle-rails
274 bootstrap-toggle-rails
295 - bootstrap3-datetimepicker-rails
275 + bootstrap3-datetimepicker-rails (~> 4.17.47)
296 byebug
276 byebug
297 capybara (>= 2.15)
277 capybara (>= 2.15)
298 coffee-rails
278 coffee-rails
299 dynamic_form
279 dynamic_form
300 fuzzy-string-match
280 fuzzy-string-match
301 haml
281 haml
302 haml-rails
282 haml-rails
303 in_place_editing
283 in_place_editing
304 jbuilder (~> 2.5)
284 jbuilder (~> 2.5)
305 jquery-countdown-rails
285 jquery-countdown-rails
306 - jquery-datatables-rails
307 jquery-rails
286 jquery-rails
308 jquery-tablesorter
287 jquery-tablesorter
309 jquery-timepicker-addon-rails
288 jquery-timepicker-addon-rails
310 jquery-ui-rails
289 jquery-ui-rails
311 listen (>= 3.0.5, < 3.2)
290 listen (>= 3.0.5, < 3.2)
312 mail
291 mail
313 minitest-reporters
292 minitest-reporters
314 - momentjs-rails
293 + momentjs-rails (>= 2.9.0)
315 mysql2
294 mysql2
316 puma
295 puma
317 rails (~> 5.2)
296 rails (~> 5.2)
318 rails-controller-testing
297 rails-controller-testing
319 rails_bootstrap_sortable
298 rails_bootstrap_sortable
320 rdiscount
299 rdiscount
@@ -326,11 +305,10
326 spring
305 spring
327 spring-watcher-listen (~> 2.0.0)
306 spring-watcher-listen (~> 2.0.0)
328 sqlite3
307 sqlite3
329 uglifier
308 uglifier
330 web-console (>= 3.3.0)
309 web-console (>= 3.3.0)
331 webdriver
310 webdriver
332 - will_paginate (~> 3.0.7)
333 yaml_db
311 yaml_db
334
312
335 BUNDLED WITH
313 BUNDLED WITH
336 - 1.16.2
314 + 1.17.2
@@ -41,13 +41,13
41 //= require jquery.countdown
41 //= require jquery.countdown
42 //-------------- addition from local_jquery -----------
42 //-------------- addition from local_jquery -----------
43 //= require jquery-tablesorter
43 //= require jquery-tablesorter
44 //= require best_in_place
44 //= require best_in_place
45 //= require best_in_place.jquery-ui
45 //= require best_in_place.jquery-ui
46 //= require brython
46 //= require brython
47 - //= require bootstrap-datepicker
47 + //= re quire bootstrap-datepicker
48 //= require bootstrap-datetimepicker
48 //= require bootstrap-datetimepicker
49
49
50 // since this is after blank line, it is not downloaded
50 // since this is after blank line, it is not downloaded
51 //x= require prototype
51 //x= require prototype
52 //x= require prototype_ujs
52 //x= require prototype_ujs
53 //x= require effects
53 //x= require effects
@@ -9,13 +9,14
9 return
9 return
10
10
11
11
12 # document ready
12 # document ready
13
13
14 $ ->
14 $ ->
15 - $(".select2").select2()
15 + $(".select2").select2({
16 + })
16 #$(".bootstrap-switch").bootstrapSwitch()
17 #$(".bootstrap-switch").bootstrapSwitch()
17 #$(".bootstrap-toggle").bootstrapToggle()
18 #$(".bootstrap-toggle").bootstrapToggle()
18 $('.btn-file :file').on 'fileselect', (event, numFiles, label) ->
19 $('.btn-file :file').on 'fileselect', (event, numFiles, label) ->
19 input = $(this).parents('.input-group').find(':text')
20 input = $(this).parents('.input-group').find(':text')
20 log = if numFiles > 1 then numFiles + ' files selected' else label
21 log = if numFiles > 1 then numFiles + ' files selected' else label
21 if input.length
22 if input.length
@@ -16,27 +16,27
16
16
17 @import "jquery-ui";
17 @import "jquery-ui";
18 //@import "jquery.ui.core";
18 //@import "jquery.ui.core";
19 //@import "jquery.ui.theme";
19 //@import "jquery.ui.theme";
20 //@import "jquery.ui.datepicker";
20 //@import "jquery.ui.datepicker";
21 //@import "jquery.ui.slider";
21 //@import "jquery.ui.slider";
22 - @import "jquery-ui-timepicker-addon";
22 + //@import "jquery-ui-timepicker-addon";
23 - @import "jquery-tablesorter/theme.metro-dark";
23 + //@import "jquery-tablesorter/theme.metro-dark";
24 @import "jquery.countdown";
24 @import "jquery.countdown";
25 @import "tablesorter-theme.cafe";
25 @import "tablesorter-theme.cafe";
26
26
27 //bootstrap
27 //bootstrap
28 @import "bootstrap-sprockets";
28 @import "bootstrap-sprockets";
29 @import "bootstrap";
29 @import "bootstrap";
30 @import "select2";
30 @import "select2";
31 @import "select2-bootstrap";
31 @import "select2-bootstrap";
32
32
33 //@import bootstrap3-switch
33 //@import bootstrap3-switch
34 @import "bootstrap-toggle";
34 @import "bootstrap-toggle";
35 @import "bootstrap-sortable";
35 @import "bootstrap-sortable";
36 - @import "bootstrap-datepicker3";
36 + //@import "bootstrap-datepicker3";
37 @import "bootstrap-datetimepicker";
37 @import "bootstrap-datetimepicker";
38 @import "datatables.net-bs/css/dataTables.bootstrap.min";
38 @import "datatables.net-bs/css/dataTables.bootstrap.min";
39 @import "datatables.net-buttons-bs/css/buttons.bootstrap.min";
39 @import "datatables.net-buttons-bs/css/buttons.bootstrap.min";
40
40
41 //bootstrap navbar color (from)
41 //bootstrap navbar color (from)
42 $bgDefault: #19197b;
42 $bgDefault: #19197b;
@@ -164,18 +164,19
164 return true
164 return true
165 end
165 end
166
166
167 #function for datatable ajax query
167 #function for datatable ajax query
168 #return record,total_count,filter_count
168 #return record,total_count,filter_count
169 def process_query_record(record,
169 def process_query_record(record,
170 - total_count: nil,
170 + total_count: nil,
171 - select: '',
171 + select: '',
172 - global_search: [],
172 + global_search: [],
173 - no_search: false,
173 + no_search: false,
174 - force_order: '',
174 + force_order: '',
175 - date_filter: '', date_param_since: 'date_since',date_param_until: 'date_until')
175 + date_filter: '', date_param_since: 'date_since',date_param_until: 'date_until',
176 + hard_limit: nil)
176 arel_table = record.model.arel_table
177 arel_table = record.model.arel_table
177
178
178 if !no_search && params['search']
179 if !no_search && params['search']
179 global_value = record.model.sanitize_sql(params['search']['value'].strip.downcase)
180 global_value = record.model.sanitize_sql(params['search']['value'].strip.downcase)
180 if !global_value.blank?
181 if !global_value.blank?
181 global_value.split.each do |value|
182 global_value.split.each do |value|
@@ -189,15 +190,17
189 record = record.where(arel_table[col['name']].lower.matches("%#{col['search']['value'].strip.downcase}%"))
190 record = record.where(arel_table[col['name']].lower.matches("%#{col['search']['value'].strip.downcase}%"))
190 end
191 end
191 end
192 end
192 end
193 end
193
194
194 if !date_filter.blank?
195 if !date_filter.blank?
195 - date_since = Time.parse( params[:date_since] ) rescue Time.new(1,1,1)
196 + param_since = params[date_param_since]
196 - date_until = Time.parse( params[:date_until] ) rescue Time.zone.now()
197 + param_until = params[date_param_until]
197 - date_range = date_since..date_until
198 + date_since = Time.zone.parse( param_since ) || Time.new(1,1,1) rescue Time.new(1,1,1)
199 + date_until = Time.zone.parse( param_until ) || Time.zone.now() rescue Time.zone.now()
200 + date_range = date_since..(date_until.end_of_day)
198 record = record.where(date_filter.to_sym => date_range)
201 record = record.where(date_filter.to_sym => date_range)
199 end
202 end
200
203
201 if force_order.blank?
204 if force_order.blank?
202 if params['order']
205 if params['order']
203 params['order'].each do |i, o|
206 params['order'].each do |i, o|
@@ -214,13 +217,20
214 # if .group() is used, filterCount might be like {id_1: count_1, id_2: count_2, ...}
217 # if .group() is used, filterCount might be like {id_1: count_1, id_2: count_2, ...}
215 # so we should count the result again..
218 # so we should count the result again..
216 if filterCount.is_a? Hash
219 if filterCount.is_a? Hash
217 filterCount = filterCount.count
220 filterCount = filterCount.count
218 end
221 end
219
222
220 - record = record.offset(params['start'] || 0).limit(params['length'] || 100)
223 +
224 + record = record.offset(params['start'] || 0)
225 + record = record.limit(hard_limit)
226 + if (params['length'])
227 + limit = params['length'].to_i
228 + limit == hard_limit if (hard_limit && hard_limit < limit)
229 + record = record.limit(limit)
230 + end
221 if (!select.blank?)
231 if (!select.blank?)
222 record = record.select(select)
232 record = record.select(select)
223 end
233 end
224
234
225 return record, total_count || record.model.count, filterCount
235 return record, total_count || record.model.count, filterCount
226 end
236 end
@@ -1,13 +1,13
1 require 'csv'
1 require 'csv'
2
2
3 class ReportController < ApplicationController
3 class ReportController < ApplicationController
4
4
5 before_action :check_valid_login
5 before_action :check_valid_login
6
6
7 - before_action :admin_authorization, only: [:login_stat,:submission_stat, :stuck, :cheat_report, :cheat_scruntinize, :show_max_score, :current_score]
7 + before_action :admin_authorization, only: [:login_stat,:submission, :submission_query, :stuck, :cheat_report, :cheat_scruntinize, :show_max_score, :current_score]
8
8
9 before_action(only: [:problem_hof]) { |c|
9 before_action(only: [:problem_hof]) { |c|
10 return false unless check_valid_login
10 return false unless check_valid_login
11
11
12 admin_authorization unless GraderConfiguration["right.user_view_submission"]
12 admin_authorization unless GraderConfiguration["right.user_view_submission"]
13 }
13 }
@@ -140,40 +140,39
140
140
141 }
141 }
142 end
142 end
143 end
143 end
144
144
145 def submission
145 def submission
146 - date_and_time = '%Y-%m-%d %H:%M'
147 - begin
148 - @since_time = DateTime.strptime(params[:since_datetime],date_and_time)
149 - rescue
150 - @since_time = DateTime.new(1000,1,1)
151 - end
152 - begin
153 - @until_time = DateTime.strptime(params[:until_datetime],date_and_time)
154 - rescue
155 - @until_time = DateTime.new(3000,1,1)
156 - end
157 -
158 - @submissions = Submission
159 - .joins(:problem).joins(:user)
160 end
146 end
161
147
162 def submission_query
148 def submission_query
163 @submissions = Submission
149 @submissions = Submission
164 - .joins(:problem).joins(:user)
150 + .includes(:problem).includes(:user).includes(:language)
151 +
152 + if params[:problem]
153 + @submission = @submission.where(problem_id: params[:problem])
154 + end
155 +
156 + case params[:users]
157 + when 'enabled'
158 + @submissions = @submissions.where('user.enabled': true)
159 + when 'group'
160 + @submissions = @submissions.joins(user: :groups).where(user: {groups: {id: params[:groups]}}) if params[:groups]
161 + end
162 +
163 + #set default
164 + params[:since_datetime] = Date.today.to_s if params[:since_datetime].blank?
165
165
166 @submissions, @recordsTotal, @recordsFiltered = process_query_record( @submissions,
166 @submissions, @recordsTotal, @recordsFiltered = process_query_record( @submissions,
167 global_search: ['user.login','user.full_name','problem.name','problem.full_name','points'],
167 global_search: ['user.login','user.full_name','problem.name','problem.full_name','points'],
168 date_filter: 'submitted_at',
168 date_filter: 'submitted_at',
169 date_param_since: 'since_datetime',
169 date_param_since: 'since_datetime',
170 date_param_until: 'until_datetime',
170 date_param_until: 'until_datetime',
171 + hard_limit: 100_000
171 )
172 )
172 - puts '-------------------------------'
173 - puts @submissions
174 end
173 end
175
174
176 def problem_hof
175 def problem_hof
177 # gen problem list
176 # gen problem list
178 @user = User.find(session[:user_id])
177 @user = User.find(session[:user_id])
179 @problems = @user.available_problems
178 @problems = @user.available_problems
@@ -61,13 +61,13
61 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
61 %a.dropdown-toggle{href: '#', data: {toggle:'dropdown'}, aria: {haspopup:"true", expanded:"false"}, role: "button"}
62 Report
62 Report
63 %span.caret
63 %span.caret
64 %ul.dropdown-menu
64 %ul.dropdown-menu
65 = add_menu( 'Current Score', 'report', 'current_score')
65 = add_menu( 'Current Score', 'report', 'current_score')
66 = add_menu( 'Score Report', 'report', 'max_score')
66 = add_menu( 'Score Report', 'report', 'max_score')
67 - = add_menu( 'Report', 'report', 'multiple_login')
67 + = add_menu( 'Submission Report', 'report', 'submission')
68 - if (ungraded = Submission.where('graded_at is null').where('submitted_at < ?', 1.minutes.ago).count) > 0
68 - if (ungraded = Submission.where('graded_at is null').where('submitted_at < ?', 1.minutes.ago).count) > 0
69 =link_to "#{ungraded} backlogs!",
69 =link_to "#{ungraded} backlogs!",
70 grader_list_path,
70 grader_list_path,
71 class: 'navbar-btn btn btn-default btn-warning', data: {toggle: 'tooltip'},title: 'Number of ungraded submission'
71 class: 'navbar-btn btn btn-default btn-warning', data: {toggle: 'tooltip'},title: 'Number of ungraded submission'
72
72
73 %ul.nav.navbar-nav.navbar-right
73 %ul.nav.navbar-nav.navbar-right
@@ -4,64 +4,74
4 %h1 Submissions detail
4 %h1 Submissions detail
5
5
6 .row
6 .row
7 .col-md-4
7 .col-md-4
8 = render partial: 'shared/problem_select'
8 = render partial: 'shared/problem_select'
9 .col-md-4
9 .col-md-4
10 - = render partial: 'shared/problem_select'
10 + = render partial: 'shared/date_filter'
11 .col-md-4
11 .col-md-4
12 = render partial: 'shared/user_select'
12 = render partial: 'shared/user_select'
13
13
14 + .row
15 + .col-md-6
16 + .alert.alert-info
17 + %ul
18 + %li Display a maximum of 100,000 entries to save computation power
19 + %li You have to click refresh when changing the filter above
14
20
15 .row
21 .row
16 - .col-12
22 + .col-sm-12
17 - %table.table.table-hover.table-condense.datatable
23 + %table.table.table-hover.table-condense.datatable{style: 'width: 100%'}
18 - -#
19 - %thead
20 - %tr
21 - %th User
22 - %th Problem
23 - %th Subbmission ID
24 - %th Submit Time
25 - %th Score
26 - %th detail
27 - %tbody
28 - - @submissions.each do |s|
29 - %tr
30 - %td= s.user.login
31 - %td= s.problem.long_name
32 - %td= s.id
33 - %td= s.submitted_at
34 - %td= s.points
35 - %td= s.grader_comment
36
24
37
25
38 :javascript
26 :javascript
39 - $('.datatable').DataTable({
27 + $(function() {
40 - dom: 'Bfrtip',
28 + submission_table = $('.datatable').DataTable({
41 - buttons: [
29 + dom: "<'row'<'col-sm-3'B><'col-sm-3'l><'col-sm-6'f>>" + "<'row'<'col-sm-12'tr>>" + "<'row'<'col-sm-5'i><'col-sm-7'p>>",
42 - 'copy', 'excel', 'pdf'
30 + autoWidth: true,
43 - ],
31 + buttons: [
44 - columns: [
32 + {
45 - {title: 'Sub ID', data: 'id'},
33 + text: 'Refresh',
46 - {title: 'User', data: 'user.login'},
34 + action: (e,dt,node,config) => {
47 - {title: 'Problem', data: 'problem.long_name'},
35 + submission_table.clear().draw()
48 - {title: 'Language', data: 'language.pretty_name'},
36 + submission_table.ajax.reload( () => { submission_table.columns.adjust().draw() } )
49 - {title: 'Submit at', data: 'submitted_at'},
37 + }
50 - {title: 'Result', data: 'grader_comment'},
38 + },
51 - {title: 'Score', data: 'points'},
39 + 'copy', 'excel'
52 - {title: 'IP', data: 'ip_address'},
40 + ],
53 - ],
41 + columns: [
54 - ajax: {
42 + {title: 'Sub ID', data: 'id'},
55 - url: '#{submission_query_report_path}',
43 + {title: 'User', data: 'user.login'},
56 - type: 'POST',
44 + {title: 'Problem', data: 'problem.long_name'},
57 - data: (d) => {
45 + {title: 'Language', data: 'language.pretty_name'},
58 - d.since_datetime = '1123'
46 + {title: 'Submit at', data: 'submitted_at'},
59 - d.until_datetime = 'xxx'
47 + {title: 'Result', data: 'grader_comment'},
60 - },
48 + {title: 'Score', data: 'points'},
61 - dataType: 'json',
49 + {title: 'IP', data: 'ip_address'},
62 - beforeSend: (request) => {
50 + ],
63 - request.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
51 + ajax: {
64 - },
52 + url: '#{submission_query_report_path}',
65 - }, //end ajax
53 + type: 'POST',
66 - 'pageLength': 50
54 + data: (d) => {
55 + d.since_datetime = $('#since_datetime').val()
56 + d.until_datetime = $('#until_datetime').val()
57 + d.users = $("input[name='users']:checked").val()
58 + d.problems = $("#problem_id").select2('val')
59 + d.groups = $("#group_id").select2('val')
60 + },
61 + dataType: 'json',
62 + beforeSend: (request) => {
63 + request.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
64 + },
65 + }, //end ajax
66 + 'pageLength': 50,
67 + processing: true,
68 + });
69 +
70 + $('.input-group.date').datetimepicker({
71 + format: 'YYYY-MM-DD',
72 + showTodayButton: true,
73 + locale: 'en',
74 + widgetPositioning: {horizontal: 'auto', vertical: 'bottom'},
75 + defaultDate: moment()
76 + });
67 });
77 });
@@ -1,18 +1,20
1 json.draw params['draw']&.to_i
1 json.draw params['draw']&.to_i
2 json.recordsTotal @recordsTotal
2 json.recordsTotal @recordsTotal
3 json.recordsFiltered @recordsFiltered
3 json.recordsFiltered @recordsFiltered
4 json.data do
4 json.data do
5 json.array! @submissions do |sub|
5 json.array! @submissions do |sub|
6 - json.extract! sub, :id, :points, :grader_comment, :ip_address
6 + json.extract! sub, :grader_comment, :ip_address
7 - json.submitted_at sub.submitted_at.to_s(:db)
7 + json.id "<a href='#{submission_path(sub)}'>#{sub.id}</a>"
8 + json.submitted_at sub.submitted_at.strftime('%Y-%m-%d %H:%M')
9 + json.points "#{sub.points}/#{sub.problem&.full_score}"
8 json.problem do
10 json.problem do
9 - json.long_name sub.problem&.long_name
11 + json.long_name sub.problem ? sub.problem.long_name : '-- deleted problem --'
10 end
12 end
11 json.user do
13 json.user do
12 - json.login sub.user&.login
14 + json.login sub.user ? "<a href='#{stat_user_path(sub.user)}'>(#{sub.user&.login})</a> #{sub.user&.full_name}" : '-- deleted user --'
13 end
15 end
14 json.language do
16 json.language do
15 json.pretty_name sub.language&.pretty_name
17 json.pretty_name sub.language&.pretty_name
16 end
18 end
17 end
19 end
18 end
20 end
@@ -1,10 +1,10
1 .panel.panel-primary
1 .panel.panel-primary
2 .panel-heading
2 .panel-heading
3 Problems
3 Problems
4 .panel-body
4 .panel-body
5 %p
5 %p
6 - Select problem(s) that we wish to know the score.
6 + Select problem(s) to be included in the report
7 = label_tag :problem_id, "Problems"
7 = label_tag :problem_id, "Problems"
8 = select_tag 'problem_id[]',
8 = select_tag 'problem_id[]',
9 options_for_select(Problem.all.collect {|p| ["[#{p.name}] #{p.full_name}", p.id]},params[:problem_id]),
9 options_for_select(Problem.all.collect {|p| ["[#{p.name}] #{p.full_name}", p.id]},params[:problem_id]),
10 - { class: 'select2 form-control', multiple: "true" }
10 + { id: :problem_id, class: 'select2 form-control', multiple: "true" }
@@ -7,6 +7,13
7 = radio_button_tag 'users', 'all', (params[:users] == "all")
7 = radio_button_tag 'users', 'all', (params[:users] == "all")
8 All users
8 All users
9 .radio
9 .radio
10 %label
10 %label
11 = radio_button_tag 'users', 'enabled', (params[:users] == "enabled")
11 = radio_button_tag 'users', 'enabled', (params[:users] == "enabled")
12 Only enabled users
12 Only enabled users
13 + .radio
14 + %label
15 + = radio_button_tag 'users', 'group', (params[:users] == "group")
16 + Only these groups
17 + = select_tag 'group_id[]',
18 + options_for_select(Group.all.collect {|g| ["[#{g.name}] #{g.description}", g.id]}),
19 + { id: 'group_id', class: 'select2 form-control', multiple: "true"}
@@ -1,321 +1,308
1 - # encoding: UTF-8
2 # This file is auto-generated from the current state of the database. Instead
1 # 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
2 # of editing this file, please use the migrations feature of Active Record to
4 # incrementally modify your database, and then regenerate this schema definition.
3 # incrementally modify your database, and then regenerate this schema definition.
5 #
4 #
6 # Note that this schema.rb definition is the authoritative source for your
5 # 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
6 # 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
7 # 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
8 # 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).
9 # you'll amass, the slower it'll run and the greater likelihood for issues).
11 #
10 #
12 # It's strongly recommended that you check this file into your version control system.
11 # It's strongly recommended that you check this file into your version control system.
13
12
14 - ActiveRecord::Schema.define(version: 20180612102327) do
13 + ActiveRecord::Schema.define(version: 2020_04_04_142959) do
15
14
16 - create_table "announcements", force: :cascade do |t|
15 + create_table "announcements", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
17 - t.string "author", limit: 255
16 + t.string "author"
18 - t.text "body", limit: 65535
17 + t.text "body", limit: 16777215
19 - t.boolean "published"
18 + t.boolean "published"
20 - t.datetime "created_at"
19 + t.datetime "created_at", null: false
21 - t.datetime "updated_at"
20 + t.datetime "updated_at", null: false
22 - t.boolean "frontpage", default: false
21 + t.boolean "frontpage", default: false
23 - t.boolean "contest_only", default: false
22 + t.boolean "contest_only", default: false
24 - t.string "title", limit: 255
23 + t.string "title"
25 - t.string "notes", limit: 255
24 + t.string "notes"
26 end
25 end
27
26
28 - create_table "contests", force: :cascade do |t|
27 + create_table "contests", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
29 - t.string "title", limit: 255
28 + t.string "title"
30 - t.boolean "enabled"
29 + t.boolean "enabled"
31 - t.datetime "created_at"
30 + t.datetime "created_at", null: false
32 - t.datetime "updated_at"
31 + t.datetime "updated_at", null: false
33 - t.string "name", limit: 255
32 + t.string "name"
34 - end
35 -
36 - create_table "contests_problems", id: false, force: :cascade do |t|
37 - t.integer "contest_id", limit: 4
38 - t.integer "problem_id", limit: 4
39 - end
40 -
41 - create_table "contests_users", id: false, force: :cascade do |t|
42 - t.integer "contest_id", limit: 4
43 - t.integer "user_id", limit: 4
44 end
33 end
45
34
46 - create_table "countries", force: :cascade do |t|
35 + create_table "contests_problems", id: false, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
47 - t.string "name", limit: 255
36 + t.integer "contest_id"
48 - t.datetime "created_at"
37 + t.integer "problem_id"
49 - t.datetime "updated_at"
50 end
38 end
51
39
52 - create_table "descriptions", force: :cascade do |t|
40 + create_table "contests_users", id: false, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
53 - t.text "body", limit: 65535
41 + t.integer "contest_id"
54 - t.boolean "markdowned"
42 + t.integer "user_id"
55 - t.datetime "created_at"
56 - t.datetime "updated_at"
57 end
43 end
58
44
59 - create_table "grader_configurations", force: :cascade do |t|
45 + create_table "countries", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
60 - t.string "key", limit: 255
46 + t.string "name"
61 - t.string "value_type", limit: 255
47 + t.datetime "created_at", null: false
62 - t.string "value", limit: 255
48 + t.datetime "updated_at", null: false
63 - t.datetime "created_at"
64 - t.datetime "updated_at"
65 - t.text "description", limit: 65535
66 end
49 end
67
50
68 - create_table "grader_processes", force: :cascade do |t|
51 + create_table "descriptions", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
69 - t.string "host", limit: 255
52 + t.text "body", limit: 16777215
70 - t.integer "pid", limit: 4
53 + t.boolean "markdowned"
71 - t.string "mode", limit: 255
54 + t.datetime "created_at", null: false
72 - t.boolean "active"
55 + t.datetime "updated_at", null: false
73 - t.datetime "created_at"
56 + end
74 - t.datetime "updated_at"
57 +
75 - t.integer "task_id", limit: 4
58 + create_table "grader_configurations", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
76 - t.string "task_type", limit: 255
59 + t.string "key"
77 - t.boolean "terminated"
60 + t.string "value_type"
61 + t.string "value"
62 + t.datetime "created_at", null: false
63 + t.datetime "updated_at", null: false
64 + t.text "description", limit: 16777215
78 end
65 end
79
66
80 - add_index "grader_processes", ["host", "pid"], name: "index_grader_processes_on_host_and_pid", using: :btree
67 + create_table "grader_processes", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
81 -
68 + t.string "host"
82 - create_table "groups", force: :cascade do |t|
69 + t.integer "pid"
83 - t.string "name", limit: 255
70 + t.string "mode"
84 - t.string "description", limit: 255
71 + t.boolean "active"
85 - end
72 + t.datetime "created_at", null: false
86 -
73 + t.datetime "updated_at", null: false
87 - create_table "groups_problems", id: false, force: :cascade do |t|
74 + t.integer "task_id"
88 - t.integer "problem_id", limit: 4, null: false
75 + t.string "task_type"
89 - t.integer "group_id", limit: 4, null: false
76 + t.boolean "terminated"
77 + t.index ["host", "pid"], name: "index_grader_processes_on_ip_and_pid"
90 end
78 end
91
79
92 - add_index "groups_problems", ["group_id", "problem_id"], name: "index_groups_problems_on_group_id_and_problem_id", using: :btree
80 + create_table "groups", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
93 -
81 + t.string "name"
94 - create_table "groups_users", id: false, force: :cascade do |t|
82 + t.string "description"
95 - t.integer "group_id", limit: 4, null: false
96 - t.integer "user_id", limit: 4, null: false
97 end
83 end
98
84
99 - add_index "groups_users", ["user_id", "group_id"], name: "index_groups_users_on_user_id_and_group_id", using: :btree
85 + create_table "groups_problems", id: false, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
86 + t.integer "problem_id", null: false
87 + t.integer "group_id", null: false
88 + t.index ["group_id", "problem_id"], name: "index_groups_problems_on_group_id_and_problem_id"
89 + end
100
90
101 - create_table "heart_beats", force: :cascade do |t|
91 + create_table "groups_users", options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
102 - t.integer "user_id", limit: 4
92 + t.integer "group_id", null: false
103 - t.string "ip_address", limit: 255
93 + t.integer "user_id", null: false
104 - t.datetime "created_at"
94 + t.index ["user_id", "group_id"], name: "index_groups_users_on_user_id_and_group_id"
105 - t.datetime "updated_at"
106 - t.string "status", limit: 255
107 end
95 end
108
96
109 - add_index "heart_beats", ["updated_at"], name: "index_heart_beats_on_updated_at", using: :btree
97 + create_table "heart_beats", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
110 -
98 + t.integer "user_id"
111 - create_table "languages", force: :cascade do |t|
99 + t.string "ip_address"
112 - t.string "name", limit: 10
100 + t.datetime "created_at", null: false
113 - t.string "pretty_name", limit: 255
101 + t.datetime "updated_at", null: false
114 - t.string "ext", limit: 10
102 + t.string "status"
115 - t.string "common_ext", limit: 255
103 + t.index ["updated_at"], name: "index_heart_beats_on_updated_at"
116 end
104 end
117
105
118 - create_table "logins", force: :cascade do |t|
106 + create_table "languages", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
119 - t.integer "user_id", limit: 4
107 + t.string "name", limit: 10
120 - t.string "ip_address", limit: 255
108 + t.string "pretty_name"
121 - t.datetime "created_at"
109 + t.string "ext", limit: 10
122 - t.datetime "updated_at"
110 + t.string "common_ext"
123 end
111 end
124
112
125 - create_table "messages", force: :cascade do |t|
113 + create_table "logins", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
126 - t.integer "sender_id", limit: 4
114 + t.integer "user_id"
127 - t.integer "receiver_id", limit: 4
115 + t.string "ip_address"
128 - t.integer "replying_message_id", limit: 4
116 + t.datetime "created_at", null: false
129 - t.text "body", limit: 65535
117 + t.datetime "updated_at", null: false
130 - t.boolean "replied"
131 - t.datetime "created_at"
132 - t.datetime "updated_at"
133 end
118 end
134
119
135 - create_table "problems", force: :cascade do |t|
120 + create_table "messages", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
136 - t.string "name", limit: 30
121 + t.integer "sender_id"
137 - t.string "full_name", limit: 255
122 + t.integer "receiver_id"
138 - t.integer "full_score", limit: 4
123 + t.integer "replying_message_id"
139 - t.date "date_added"
124 + t.text "body", limit: 16777215
125 + t.boolean "replied"
126 + t.datetime "created_at", null: false
127 + t.datetime "updated_at", null: false
128 + end
129 +
130 + create_table "problems", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
131 + t.string "name", limit: 100
132 + t.string "full_name"
133 + t.integer "full_score"
134 + t.date "date_added"
140 t.boolean "available"
135 t.boolean "available"
141 - t.string "url", limit: 255
136 + t.string "url"
142 - t.integer "description_id", limit: 4
137 + t.integer "description_id"
143 t.boolean "test_allowed"
138 t.boolean "test_allowed"
144 t.boolean "output_only"
139 t.boolean "output_only"
145 - t.string "description_filename", limit: 255
140 + t.string "description_filename"
146 t.boolean "view_testcase"
141 t.boolean "view_testcase"
147 end
142 end
148
143
149 - create_table "problems_tags", force: :cascade do |t|
144 + create_table "problems_tags", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
150 - t.integer "problem_id", limit: 4
145 + t.integer "problem_id"
151 - t.integer "tag_id", limit: 4
146 + t.integer "tag_id"
147 + t.index ["problem_id", "tag_id"], name: "index_problems_tags_on_problem_id_and_tag_id", unique: true
148 + t.index ["problem_id"], name: "index_problems_tags_on_problem_id"
149 + t.index ["tag_id"], name: "index_problems_tags_on_tag_id"
152 end
150 end
153
151
154 - add_index "problems_tags", ["problem_id", "tag_id"], name: "index_problems_tags_on_problem_id_and_tag_id", unique: true, using: :btree
152 + create_table "rights", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
155 - add_index "problems_tags", ["problem_id"], name: "index_problems_tags_on_problem_id", using: :btree
153 + t.string "name"
156 - add_index "problems_tags", ["tag_id"], name: "index_problems_tags_on_tag_id", using: :btree
154 + t.string "controller"
157 -
155 + t.string "action"
158 - create_table "rights", force: :cascade do |t|
159 - t.string "name", limit: 255
160 - t.string "controller", limit: 255
161 - t.string "action", limit: 255
162 end
156 end
163
157
164 - create_table "rights_roles", id: false, force: :cascade do |t|
158 + create_table "rights_roles", id: false, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
165 - t.integer "right_id", limit: 4
159 + t.integer "right_id"
166 - t.integer "role_id", limit: 4
160 + t.integer "role_id"
161 + t.index ["role_id"], name: "index_rights_roles_on_role_id"
167 end
162 end
168
163
169 - add_index "rights_roles", ["role_id"], name: "index_rights_roles_on_role_id", using: :btree
164 + create_table "roles", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
170 -
165 + t.string "name"
171 - create_table "roles", force: :cascade do |t|
172 - t.string "name", limit: 255
173 end
166 end
174
167
175 - create_table "roles_users", id: false, force: :cascade do |t|
168 + create_table "roles_users", id: false, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
176 - t.integer "role_id", limit: 4
169 + t.integer "role_id"
177 - t.integer "user_id", limit: 4
170 + t.integer "user_id"
171 + t.index ["user_id"], name: "index_roles_users_on_user_id"
178 end
172 end
179
173
180 - add_index "roles_users", ["user_id"], name: "index_roles_users_on_user_id", using: :btree
174 + create_table "sessions", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
181 -
175 + t.string "session_id"
182 - create_table "sessions", force: :cascade do |t|
176 + t.text "data", limit: 16777215
183 - t.string "session_id", limit: 255
184 - t.text "data", limit: 65535
185 t.datetime "updated_at"
177 t.datetime "updated_at"
178 + t.index ["session_id"], name: "index_sessions_on_session_id"
179 + t.index ["updated_at"], name: "index_sessions_on_updated_at"
186 end
180 end
187
181
188 - add_index "sessions", ["session_id"], name: "index_sessions_on_session_id", using: :btree
182 + create_table "sites", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
189 - add_index "sessions", ["updated_at"], name: "index_sessions_on_updated_at", using: :btree
183 + t.string "name"
184 + t.boolean "started"
185 + t.datetime "start_time"
186 + t.datetime "created_at", null: false
187 + t.datetime "updated_at", null: false
188 + t.integer "country_id"
189 + t.string "password"
190 + end
190
191
191 - create_table "sites", force: :cascade do |t|
192 + create_table "submission_view_logs", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
192 - t.string "name", limit: 255
193 + t.integer "user_id"
193 - t.boolean "started"
194 + t.integer "submission_id"
194 - t.datetime "start_time"
195 + t.datetime "created_at", null: false
195 - t.datetime "created_at"
196 + t.datetime "updated_at", null: false
196 - t.datetime "updated_at"
197 - t.integer "country_id", limit: 4
198 - t.string "password", limit: 255
199 end
197 end
200
198
201 - create_table "submission_view_logs", force: :cascade do |t|
199 + create_table "submissions", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
202 - t.integer "user_id", limit: 4
200 + t.integer "user_id"
203 - t.integer "submission_id", limit: 4
201 + t.integer "problem_id"
204 - t.datetime "created_at"
202 + t.integer "language_id"
205 - t.datetime "updated_at"
203 + t.text "source", limit: 16777215
206 - end
204 + t.binary "binary"
207 -
208 - create_table "submissions", force: :cascade do |t|
209 - t.integer "user_id", limit: 4
210 - t.integer "problem_id", limit: 4
211 - t.integer "language_id", limit: 4
212 - t.text "source", limit: 16777215
213 - t.binary "binary", limit: 65535
214 t.datetime "submitted_at"
205 t.datetime "submitted_at"
215 t.datetime "compiled_at"
206 t.datetime "compiled_at"
216 - t.text "compiler_message", limit: 65535
207 + t.text "compiler_message", limit: 16777215
217 t.datetime "graded_at"
208 t.datetime "graded_at"
218 - t.integer "points", limit: 4
209 + t.integer "points"
219 - t.text "grader_comment", limit: 65535
210 + t.text "grader_comment", limit: 16777215
220 - t.integer "number", limit: 4
211 + t.integer "number"
221 - t.string "source_filename", limit: 255
212 + t.string "source_filename"
222 - t.float "max_runtime", limit: 24
213 + t.float "max_runtime"
223 - t.integer "peak_memory", limit: 4
214 + t.integer "peak_memory"
224 - t.integer "effective_code_length", limit: 4
215 + t.integer "effective_code_length"
225 - t.string "ip_address", limit: 255
216 + t.string "ip_address"
217 + t.index ["submitted_at"], name: "index_submissions_on_submitted_at"
218 + t.index ["user_id", "problem_id", "number"], name: "index_submissions_on_user_id_and_problem_id_and_number", unique: true
219 + t.index ["user_id", "problem_id"], name: "index_submissions_on_user_id_and_problem_id"
226 end
220 end
227
221
228 - add_index "submissions", ["user_id", "problem_id", "number"], name: "index_submissions_on_user_id_and_problem_id_and_number", unique: true, using: :btree
222 + create_table "tags", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
229 - add_index "submissions", ["user_id", "problem_id"], name: "index_submissions_on_user_id_and_problem_id", using: :btree
223 + t.string "name", null: false
230 -
224 + t.text "description"
231 - create_table "tags", force: :cascade do |t|
225 + t.boolean "public"
232 - t.string "name", limit: 255, null: false
226 + t.datetime "created_at", null: false
233 - t.text "description", limit: 65535
227 + t.datetime "updated_at", null: false
234 - t.boolean "public"
235 - t.datetime "created_at", null: false
236 - t.datetime "updated_at", null: false
237 end
228 end
238
229
239 - create_table "tasks", force: :cascade do |t|
230 + create_table "tasks", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
240 - t.integer "submission_id", limit: 4
231 + t.integer "submission_id"
241 t.datetime "created_at"
232 t.datetime "created_at"
242 - t.integer "status", limit: 4
233 + t.integer "status"
243 t.datetime "updated_at"
234 t.datetime "updated_at"
235 + t.index ["submission_id"], name: "index_tasks_on_submission_id"
244 end
236 end
245
237
246 - add_index "tasks", ["submission_id"], name: "index_tasks_on_submission_id", using: :btree
238 + create_table "test_pairs", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
247 -
239 + t.integer "problem_id"
248 - create_table "test_pairs", force: :cascade do |t|
240 + t.text "input", limit: 4294967295
249 - t.integer "problem_id", limit: 4
241 + t.text "solution", limit: 4294967295
250 - t.text "input", limit: 16777215
242 + t.datetime "created_at", null: false
251 - t.text "solution", limit: 16777215
243 + t.datetime "updated_at", null: false
252 - t.datetime "created_at"
253 - t.datetime "updated_at"
254 end
244 end
255
245
256 - create_table "test_requests", force: :cascade do |t|
246 + create_table "test_requests", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
257 - t.integer "user_id", limit: 4
247 + t.integer "user_id"
258 - t.integer "problem_id", limit: 4
248 + t.integer "problem_id"
259 - t.integer "submission_id", limit: 4
249 + t.integer "submission_id"
260 - t.string "input_file_name", limit: 255
250 + t.string "input_file_name"
261 - t.string "output_file_name", limit: 255
251 + t.string "output_file_name"
262 - t.string "running_stat", limit: 255
252 + t.string "running_stat"
263 - t.integer "status", limit: 4
253 + t.integer "status"
264 - t.datetime "updated_at"
254 + t.datetime "updated_at", null: false
265 t.datetime "submitted_at"
255 t.datetime "submitted_at"
266 t.datetime "compiled_at"
256 t.datetime "compiled_at"
267 - t.text "compiler_message", limit: 65535
257 + t.text "compiler_message", limit: 16777215
268 t.datetime "graded_at"
258 t.datetime "graded_at"
269 - t.string "grader_comment", limit: 255
259 + t.string "grader_comment"
270 - t.datetime "created_at"
260 + t.datetime "created_at", null: false
271 - t.float "running_time", limit: 24
261 + t.float "running_time"
272 - t.string "exit_status", limit: 255
262 + t.string "exit_status"
273 - t.integer "memory_usage", limit: 4
263 + t.integer "memory_usage"
264 + t.index ["user_id", "problem_id"], name: "index_test_requests_on_user_id_and_problem_id"
274 end
265 end
275
266
276 - add_index "test_requests", ["user_id", "problem_id"], name: "index_test_requests_on_user_id_and_problem_id", using: :btree
267 + create_table "testcases", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=latin1", force: :cascade do |t|
277 -
268 + t.integer "problem_id"
278 - create_table "testcases", force: :cascade do |t|
269 + t.integer "num"
279 - t.integer "problem_id", limit: 4
270 + t.integer "group"
280 - t.integer "num", limit: 4
271 + t.integer "score"
281 - t.integer "group", limit: 4
272 + t.text "input", limit: 4294967295
282 - t.integer "score", limit: 4
273 + t.text "sol", limit: 4294967295
283 - t.text "input", limit: 4294967295
274 + t.datetime "created_at", null: false
284 - t.text "sol", limit: 4294967295
275 + t.datetime "updated_at", null: false
285 - t.datetime "created_at"
276 + t.index ["problem_id"], name: "index_testcases_on_problem_id"
286 - t.datetime "updated_at"
287 end
277 end
288
278
289 - add_index "testcases", ["problem_id"], name: "index_testcases_on_problem_id", using: :btree
279 + create_table "user_contest_stats", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
290 -
280 + t.integer "user_id"
291 - create_table "user_contest_stats", force: :cascade do |t|
292 - t.integer "user_id", limit: 4
293 t.datetime "started_at"
281 t.datetime "started_at"
294 - t.datetime "created_at"
282 + t.datetime "created_at", null: false
295 - t.datetime "updated_at"
283 + t.datetime "updated_at", null: false
296 - t.boolean "forced_logout"
284 + t.boolean "forced_logout"
297 end
285 end
298
286
299 - create_table "users", force: :cascade do |t|
287 + create_table "users", id: :integer, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
300 - t.string "login", limit: 50
288 + t.string "login", limit: 50
301 - t.string "full_name", limit: 255
289 + t.string "full_name"
302 - t.string "hashed_password", limit: 255
290 + t.string "hashed_password"
303 - t.string "salt", limit: 5
291 + t.string "salt", limit: 5
304 - t.string "alias", limit: 255
292 + t.string "alias"
305 - t.string "email", limit: 255
293 + t.string "email"
306 - t.integer "site_id", limit: 4
294 + t.integer "site_id"
307 - t.integer "country_id", limit: 4
295 + t.integer "country_id"
308 - t.boolean "activated", default: false
296 + t.boolean "activated", default: false
309 t.datetime "created_at"
297 t.datetime "created_at"
310 t.datetime "updated_at"
298 t.datetime "updated_at"
311 - t.string "section", limit: 255
299 + t.string "section"
312 - t.boolean "enabled", default: true
300 + t.boolean "enabled", default: true
313 - t.string "remark", limit: 255
301 + t.string "remark"
314 - t.string "last_ip", limit: 255
302 + t.string "last_ip"
303 + t.index ["login"], name: "index_users_on_login", unique: true
315 end
304 end
316
305
317 - add_index "users", ["login"], name: "index_users_on_login", unique: true, using: :btree
318 -
319 add_foreign_key "problems_tags", "problems"
306 add_foreign_key "problems_tags", "problems"
320 add_foreign_key "problems_tags", "tags"
307 add_foreign_key "problems_tags", "tags"
321 end
308 end
You need to be logged in to leave comments. Login now