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
@@ -41,50 +41,50
41 # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
41 # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
42 #gem 'turbolinks', '~> 5'
42 #gem 'turbolinks', '~> 5'
43 # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
43 # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
44 gem 'jbuilder', '~> 2.5'
44 gem 'jbuilder', '~> 2.5'
45
45
46
46
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'
85
85
86
86
87 #---------------- testiing -----------------------
87 #---------------- testiing -----------------------
88 gem 'minitest-reporters'
88 gem 'minitest-reporters'
89
89
90 #---------------- for console --------------------
90 #---------------- for console --------------------
@@ -55,26 +55,24
55 addressable (2.7.0)
55 addressable (2.7.0)
56 public_suffix (>= 2.0.2, < 5.0)
56 public_suffix (>= 2.0.2, < 5.0)
57 ansi (1.5.0)
57 ansi (1.5.0)
58 arel (9.0.0)
58 arel (9.0.0)
59 autoprefixer-rails (9.5.1)
59 autoprefixer-rails (9.5.1)
60 execjs
60 execjs
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)
75 momentjs-rails (>= 2.8.1)
73 momentjs-rails (>= 2.8.1)
76 builder (3.2.4)
74 builder (3.2.4)
77 byebug (11.0.1)
75 byebug (11.0.1)
78 capybara (3.15.1)
76 capybara (3.15.1)
79 addressable
77 addressable
80 mini_mime (>= 0.1.3)
78 mini_mime (>= 0.1.3)
@@ -113,29 +111,24
113 railties (>= 4.0.1)
111 railties (>= 4.0.1)
114 html2haml (2.2.0)
112 html2haml (2.2.0)
115 erubis (~> 2.7.0)
113 erubis (~> 2.7.0)
116 haml (>= 4.0, < 6)
114 haml (>= 4.0, < 6)
117 nokogiri (>= 1.6.0)
115 nokogiri (>= 1.6.0)
118 ruby_parser (~> 3.5)
116 ruby_parser (~> 3.5)
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)
136 jquery-timepicker-addon-rails (1.4.1)
129 jquery-timepicker-addon-rails (1.4.1)
137 railties (>= 3.1)
130 railties (>= 3.1)
138 jquery-ui-rails (6.0.1)
131 jquery-ui-rails (6.0.1)
139 railties (>= 3.2.16)
132 railties (>= 3.2.16)
140 listen (3.1.5)
133 listen (3.1.5)
141 rb-fsevent (~> 0.9, >= 0.9.4)
134 rb-fsevent (~> 0.9, >= 0.9.4)
@@ -205,35 +198,24
205 rake (13.0.1)
198 rake (13.0.1)
206 rb-fsevent (0.10.3)
199 rb-fsevent (0.10.3)
207 rb-inotify (0.10.0)
200 rb-inotify (0.10.0)
208 ffi (~> 1.0)
201 ffi (~> 1.0)
209 rdiscount (2.2.0.1)
202 rdiscount (2.2.0.1)
210 regexp_parser (1.7.0)
203 regexp_parser (1.7.0)
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)
234 sprockets-rails
216 sprockets-rails
235 tilt
217 tilt
236 select2-rails (4.0.3)
218 select2-rails (4.0.3)
237 thor (~> 0.14)
219 thor (~> 0.14)
238 selenium-webdriver (3.142.7)
220 selenium-webdriver (3.142.7)
239 childprocess (>= 0.5, < 4.0)
221 childprocess (>= 0.5, < 4.0)
@@ -263,74 +245,70
263 thread_safe (~> 0.1)
245 thread_safe (~> 0.1)
264 uglifier (4.1.20)
246 uglifier (4.1.20)
265 execjs (>= 0.3.0, < 3)
247 execjs (>= 0.3.0, < 3)
266 web-console (3.7.0)
248 web-console (3.7.0)
267 actionview (>= 5.0)
249 actionview (>= 5.0)
268 activemodel (>= 5.0)
250 activemodel (>= 5.0)
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
282 PLATFORMS
263 PLATFORMS
283 ruby
264 ruby
284
265
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
321 rouge
300 rouge
322 sassc-rails
301 sassc-rails
323 select2-rails
302 select2-rails
324 selenium-webdriver
303 selenium-webdriver
325 simple_form
304 simple_form
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
@@ -35,21 +35,21
35 //= require ace/mode-ruby
35 //= require ace/mode-ruby
36 //= require ace/mode-pascal
36 //= require ace/mode-pascal
37 //= require ace/mode-javascript
37 //= require ace/mode-javascript
38 //= require ace/mode-java
38 //= require ace/mode-java
39 //= require ace/theme-merbivore
39 //= require ace/theme-merbivore
40 //= require custom
40 //= require custom
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
54 //x= require dragdrop
54 //x= require dragdrop
55 //x= require controls
55 //x= require controls
@@ -3,25 +3,26
3 numFiles = if input.get(0).files then input.get(0).files.length else 1
3 numFiles = if input.get(0).files then input.get(0).files.length else 1
4 label = input.val().replace(/\\/g, '/').replace(/.*\//, '')
4 label = input.val().replace(/\\/g, '/').replace(/.*\//, '')
5 input.trigger 'fileselect', [
5 input.trigger 'fileselect', [
6 numFiles
6 numFiles
7 label
7 label
8 ]
8 ]
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
22 input.val log
23 input.val log
23 else
24 else
24 if log
25 if log
25 alert log
26 alert log
26 return
27 return
27 $(".go-button").on 'click', (event) ->
28 $(".go-button").on 'click', (event) ->
@@ -10,39 +10,39
10 * file per style scope.
10 * file per style scope.
11 *
11 *
12 * // bootstrap says that we should not do this, but @import each file instead
12 * // bootstrap says that we should not do this, but @import each file instead
13 * # *= require_tree .
13 * # *= require_tree .
14 * # *= require_self
14 * # *= require_self
15 */
15 */
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;
43 $bgHighlight: #06064b;
43 $bgHighlight: #06064b;
44 $colDefault: #8e8eb4;
44 $colDefault: #8e8eb4;
45 $colHighlight: #ffffff;
45 $colHighlight: #ffffff;
46 $dropDown: false;
46 $dropDown: false;
47
47
48 @font-face {
48 @font-face {
@@ -158,71 +158,81
158 if allow_ips.include?(user_ip)
158 if allow_ips.include?(user_ip)
159 return true
159 return true
160 end
160 end
161 end
161 end
162 return false
162 return false
163 end
163 end
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|
182 global_where = global_search.map{|f| "LOWER(#{f}) like '%#{value}%'"}.join(' OR ')
183 global_where = global_search.map{|f| "LOWER(#{f}) like '%#{value}%'"}.join(' OR ')
183 record = record.where(global_where)
184 record = record.where(global_where)
184 end
185 end
185 end
186 end
186
187
187 params['columns'].each do |i, col|
188 params['columns'].each do |i, col|
188 if !col['search']['value'].blank?
189 if !col['search']['value'].blank?
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|
204 colName = params['columns'][o['column']]['name']
207 colName = params['columns'][o['column']]['name']
205 colName = "#{record.model.table_name}.#{colName}" if colName.upcase == 'ID'
208 colName = "#{record.model.table_name}.#{colName}" if colName.upcase == 'ID'
206 record = record.order("#{colName} #{o['dir'].casecmp('desc') != 0 ? 'ASC' : 'DESC'}") unless colName.blank?
209 record = record.order("#{colName} #{o['dir'].casecmp('desc') != 0 ? 'ASC' : 'DESC'}") unless colName.blank?
207 end
210 end
208 end
211 end
209 else
212 else
210 record = record.order(force_order)
213 record = record.order(force_order)
211 end
214 end
212
215
213 filterCount = record.count(record.model.primary_key)
216 filterCount = record.count(record.model.primary_key)
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
227
237
228 end
238 end
@@ -1,19 +1,19
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 }
14
14
15 def max_score
15 def max_score
16 end
16 end
17
17
18 def current_score
18 def current_score
19 @problems = Problem.available_problems
19 @problems = Problem.available_problems
@@ -134,52 +134,51
134 max: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
134 max: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
135 user.id,@since_time,@until_time)
135 user.id,@since_time,@until_time)
136 .maximum(:created_at),
136 .maximum(:created_at),
137 ip: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
137 ip: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
138 user.id,@since_time,@until_time)
138 user.id,@since_time,@until_time)
139 .select(:ip_address).uniq
139 .select(:ip_address).uniq
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
180
179
181 # get selected problems or the default
180 # get selected problems or the default
182 if params[:id]
181 if params[:id]
183 begin
182 begin
184 @problem = Problem.available.find(params[:id])
183 @problem = Problem.available.find(params[:id])
185 rescue
184 rescue
@@ -55,25 +55,25
55 = add_menu( 'System config', 'configurations', 'index')
55 = add_menu( 'System config', 'configurations', 'index')
56 %li.divider{role: 'separator'}
56 %li.divider{role: 'separator'}
57 = add_menu( 'Sites', 'sites', 'index')
57 = add_menu( 'Sites', 'sites', 'index')
58 = add_menu( 'Contests', 'contest_management', 'index')
58 = add_menu( 'Contests', 'contest_management', 'index')
59 / report
59 / report
60 %li.dropdown
60 %li.dropdown
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
74 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-question-sign')}".html_safe, 'main', 'help')
74 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-question-sign')}".html_safe, 'main', 'help')
75 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-comment')}".html_safe, 'messages', 'index', {title: I18n.t('menu.messages'), data: {toggle: 'tooltip'}})
75 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-comment')}".html_safe, 'messages', 'index', {title: I18n.t('menu.messages'), data: {toggle: 'tooltip'}})
76 - if GraderConfiguration['system.user_setting_enabled']
76 - if GraderConfiguration['system.user_setting_enabled']
77 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-cog', id: 'user_profile')}".html_safe, 'users', 'profile', {title: I18n.t('menu.settings'), data: {toggle: 'tooltip'}})
77 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-cog', id: 'user_profile')}".html_safe, 'users', 'profile', {title: I18n.t('menu.settings'), data: {toggle: 'tooltip'}})
78 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-log-out')} #{@current_user.full_name}".html_safe, 'main', 'login', {title: I18n.t('menu.log_out'), data: {toggle: 'tooltip'}})
78 = add_menu("#{content_tag(:span,'',class: 'glyphicon glyphicon-log-out')} #{@current_user.full_name}".html_safe, 'main', 'login', {title: I18n.t('menu.log_out'), data: {toggle: 'tooltip'}})
79
79
@@ -1,67 +1,77
1 - content_for :header do
1 - content_for :header do
2 = javascript_include_tag 'local_jquery'
2 = javascript_include_tag 'local_jquery'
3
3
4 %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" }
@@ -1,12 +1,19
1 .panel.panel-primary
1 .panel.panel-primary
2 .panel-heading
2 .panel-heading
3 Users
3 Users
4 .panel-body
4 .panel-body
5 .radio
5 .radio
6 %label
6 %label
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