Description:
Merge pull request #25 from nattee/master update outdated gem
Commit status:
[Not Reviewed]
References:
merge default
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r769:6eb8c22c844a - - 13 files changed: 186 inserted, 158 deleted

@@ -0,0 +1,1
1 + grader
@@ -0,0 +1,1
1 + ruby-2.6.3
@@ -1,35 +1,35
1 # See http://help.github.com/ignore-files/ for more about ignoring files.
1 # See http://help.github.com/ignore-files/ for more about ignoring files.
2 #
2 #
3 # If you find yourself ignoring temporary files generated by your text editor
3 # If you find yourself ignoring temporary files generated by your text editor
4 # or operating system, you probably want to add a global ignore instead:
4 # or operating system, you probably want to add a global ignore instead:
5 # git config --global core.excludesfile ~/.gitignore_global
5 # git config --global core.excludesfile ~/.gitignore_global
6
6
7 # Ignore bundler config
7 # Ignore bundler config
8 /.bundle
8 /.bundle
9
9
10 # Ignore the default SQLite database.
10 # Ignore the default SQLite database.
11 /db/*.sqlite3
11 /db/*.sqlite3
12
12
13 # Ignore all logfiles and tempfiles.
13 # Ignore all logfiles and tempfiles.
14 /log/*.log
14 /log/*.log
15 /tmp
15 /tmp
16
16
17 *~
17 *~
18
18
19 /vendor/plugins/rails_upgrade
19 /vendor/plugins/rails_upgrade
20
20
21 #ignore public assets???
21 #ignore public assets???
22 /public/assets
22 /public/assets
23 /public
23 /public
24
24
25 /data
25 /data
26
26
27 #ignore .orig and .swp
27 #ignore .orig and .swp
28 *.orig
28 *.orig
29 *.swp
29 *.swp
30
30
31 #ignore rvm setting file
31 #ignore rvm setting file
32 - .ruby-gemset
32 + #.ruby-gemset
33 - .ruby-version
33 + #.ruby-version
34
34
35 /config/secrets.yml
35 /config/secrets.yml
@@ -1,92 +1,93
1 source 'https://rubygems.org'
1 source 'https://rubygems.org'
2
2
3 #rails
3 #rails
4 gem 'rails', '~>4.2.0'
4 gem 'rails', '~>4.2.0'
5 gem 'activerecord-session_store'
5 gem 'activerecord-session_store'
6
6
7
7
8 # Bundle edge Rails instead:
8 # Bundle edge Rails instead:
9 # gem 'rails', :git => 'git://github.com/rails/rails.git'
9 # gem 'rails', :git => 'git://github.com/rails/rails.git'
10
10
11 #---------------- database ---------------------
11 #---------------- database ---------------------
12 #the database
12 #the database
13 gem 'mysql2'
13 gem 'mysql2'
14 #for testing
14 #for testing
15 gem 'sqlite3'
15 gem 'sqlite3'
16 #for dumping database into yaml
16 #for dumping database into yaml
17 gem 'yaml_db'
17 gem 'yaml_db'
18
18
19 # Gems used only for assets and not required
19 # Gems used only for assets and not required
20 # in production environments by default.
20 # in production environments by default.
21 gem 'sass-rails'
21 gem 'sass-rails'
22 gem 'coffee-rails'
22 gem 'coffee-rails'
23
23
24 # See https://github.com/sstephenson/execjs#readme for more supported runtimes
24 # See https://github.com/sstephenson/execjs#readme for more supported runtimes
25 # gem 'therubyracer', :platforms => :ruby
25 # gem 'therubyracer', :platforms => :ruby
26
26
27 gem 'uglifier'
27 gem 'uglifier'
28
28
29 gem 'haml'
29 gem 'haml'
30 gem 'haml-rails'
30 gem 'haml-rails'
31 # gem 'prototype-rails'
31 # gem 'prototype-rails'
32
32
33 # To use ActiveModel has_secure_password
33 # To use ActiveModel has_secure_password
34 # gem 'bcrypt-ruby', '~> 3.0.0'
34 # gem 'bcrypt-ruby', '~> 3.0.0'
35
35
36 # To use Jbuilder templates for JSON
36 # To use Jbuilder templates for JSON
37 # gem 'jbuilder'
37 # gem 'jbuilder'
38
38
39 # Use unicorn as the app server
39 # Use unicorn as the app server
40 # gem 'unicorn'
40 # gem 'unicorn'
41
41
42 # Deploy with Capistrano
42 # Deploy with Capistrano
43 # gem 'capistrano'
43 # gem 'capistrano'
44
44
45 # To use debugger
45 # To use debugger
46 # gem 'debugger'
46 # gem 'debugger'
47 #
47 #
48
48
49 #in-place editor
49 #in-place editor
50 gem 'best_in_place', '~> 3.0.1'
50 gem 'best_in_place', '~> 3.0.1'
51
51
52 # jquery addition
52 # jquery addition
53 gem 'jquery-rails'
53 gem 'jquery-rails'
54 gem 'jquery-ui-rails'
54 gem 'jquery-ui-rails'
55 gem 'jquery-timepicker-addon-rails'
55 gem 'jquery-timepicker-addon-rails'
56 gem 'jquery-tablesorter'
56 gem 'jquery-tablesorter'
57 gem 'jquery-countdown-rails'
57 gem 'jquery-countdown-rails'
58
58
59 #syntax highlighter
59 #syntax highlighter
60 gem 'rouge'
60 gem 'rouge'
61
61
62 #bootstrap add-ons
62 #bootstrap add-ons
63 - gem 'bootstrap-sass', '~> 3.2.0'
63 + gem 'bootstrap-sass', '~> 3.4.1'
64 + gem 'sassc-rails', '>= 2.1.0'
64 gem 'bootstrap-switch-rails'
65 gem 'bootstrap-switch-rails'
65 gem 'bootstrap-toggle-rails'
66 gem 'bootstrap-toggle-rails'
66 gem 'autoprefixer-rails'
67 gem 'autoprefixer-rails'
67 gem 'momentjs-rails'
68 gem 'momentjs-rails'
68 gem 'rails_bootstrap_sortable'
69 gem 'rails_bootstrap_sortable'
69 gem 'bootstrap-datepicker-rails'
70 gem 'bootstrap-datepicker-rails'
70 gem 'bootstrap3-datetimepicker-rails'
71 gem 'bootstrap3-datetimepicker-rails'
71 gem 'jquery-datatables-rails'
72 gem 'jquery-datatables-rails'
72
73
73 #----------- user interface -----------------
74 #----------- user interface -----------------
74 #select 2
75 #select 2
75 gem 'select2-rails'
76 gem 'select2-rails'
76 #ace editor
77 #ace editor
77 gem 'ace-rails-ap'
78 gem 'ace-rails-ap'
78 #paginator
79 #paginator
79 gem 'will_paginate', '~> 3.0.7'
80 gem 'will_paginate', '~> 3.0.7'
80
81
81 gem 'mail'
82 gem 'mail'
82 gem 'rdiscount'
83 gem 'rdiscount'
83 gem 'dynamic_form'
84 gem 'dynamic_form'
84 gem 'in_place_editing'
85 gem 'in_place_editing'
85 gem 'verification', :git => 'https://github.com/sikachu/verification.git'
86 gem 'verification', :git => 'https://github.com/sikachu/verification.git'
86
87
87
88
88 #---------------- testiing -----------------------
89 #---------------- testiing -----------------------
89 gem 'minitest-reporters'
90 gem 'minitest-reporters'
90
91
91 #---------------- for console --------------------
92 #---------------- for console --------------------
92 gem 'fuzzy-string-match'
93 gem 'fuzzy-string-match'
@@ -1,247 +1,267
1 GIT
1 GIT
2 remote: https://github.com/sikachu/verification.git
2 remote: https://github.com/sikachu/verification.git
3 revision: ff31697b940d7b0e2ec65f08764215c96104e76d
3 revision: ff31697b940d7b0e2ec65f08764215c96104e76d
4 specs:
4 specs:
5 verification (1.0.3)
5 verification (1.0.3)
6 actionpack (>= 3.0.0, < 5.1)
6 actionpack (>= 3.0.0, < 5.1)
7 activesupport (>= 3.0.0, < 5.1)
7 activesupport (>= 3.0.0, < 5.1)
8
8
9 GEM
9 GEM
10 remote: https://rubygems.org/
10 remote: https://rubygems.org/
11 specs:
11 specs:
12 RubyInline (3.12.4)
12 RubyInline (3.12.4)
13 ZenTest (~> 4.3)
13 ZenTest (~> 4.3)
14 - ZenTest (4.11.1)
14 + ZenTest (4.11.2)
15 - ace-rails-ap (4.1.1)
15 + ace-rails-ap (4.2)
16 - actionmailer (4.2.7.1)
16 + actionmailer (4.2.11.1)
17 - actionpack (= 4.2.7.1)
17 + actionpack (= 4.2.11.1)
18 - actionview (= 4.2.7.1)
18 + actionview (= 4.2.11.1)
19 - activejob (= 4.2.7.1)
19 + activejob (= 4.2.11.1)
20 mail (~> 2.5, >= 2.5.4)
20 mail (~> 2.5, >= 2.5.4)
21 rails-dom-testing (~> 1.0, >= 1.0.5)
21 rails-dom-testing (~> 1.0, >= 1.0.5)
22 - actionpack (4.2.7.1)
22 + actionpack (4.2.11.1)
23 - actionview (= 4.2.7.1)
23 + actionview (= 4.2.11.1)
24 - activesupport (= 4.2.7.1)
24 + activesupport (= 4.2.11.1)
25 rack (~> 1.6)
25 rack (~> 1.6)
26 rack-test (~> 0.6.2)
26 rack-test (~> 0.6.2)
27 rails-dom-testing (~> 1.0, >= 1.0.5)
27 rails-dom-testing (~> 1.0, >= 1.0.5)
28 rails-html-sanitizer (~> 1.0, >= 1.0.2)
28 rails-html-sanitizer (~> 1.0, >= 1.0.2)
29 - actionview (4.2.7.1)
29 + actionview (4.2.11.1)
30 - activesupport (= 4.2.7.1)
30 + activesupport (= 4.2.11.1)
31 builder (~> 3.1)
31 builder (~> 3.1)
32 erubis (~> 2.7.0)
32 erubis (~> 2.7.0)
33 rails-dom-testing (~> 1.0, >= 1.0.5)
33 rails-dom-testing (~> 1.0, >= 1.0.5)
34 - rails-html-sanitizer (~> 1.0, >= 1.0.2)
34 + rails-html-sanitizer (~> 1.0, >= 1.0.3)
35 - activejob (4.2.7.1)
35 + activejob (4.2.11.1)
36 - activesupport (= 4.2.7.1)
36 + activesupport (= 4.2.11.1)
37 globalid (>= 0.3.0)
37 globalid (>= 0.3.0)
38 - activemodel (4.2.7.1)
38 + activemodel (4.2.11.1)
39 - activesupport (= 4.2.7.1)
39 + activesupport (= 4.2.11.1)
40 builder (~> 3.1)
40 builder (~> 3.1)
41 - activerecord (4.2.7.1)
41 + activerecord (4.2.11.1)
42 - activemodel (= 4.2.7.1)
42 + activemodel (= 4.2.11.1)
43 - activesupport (= 4.2.7.1)
43 + activesupport (= 4.2.11.1)
44 arel (~> 6.0)
44 arel (~> 6.0)
45 - activerecord-session_store (1.0.0)
45 + activerecord-session_store (1.1.3)
46 - actionpack (>= 4.0, < 5.1)
46 + actionpack (>= 4.0)
47 - activerecord (>= 4.0, < 5.1)
47 + activerecord (>= 4.0)
48 multi_json (~> 1.11, >= 1.11.2)
48 multi_json (~> 1.11, >= 1.11.2)
49 rack (>= 1.5.2, < 3)
49 rack (>= 1.5.2, < 3)
50 - railties (>= 4.0, < 5.1)
50 + railties (>= 4.0)
51 - activesupport (4.2.7.1)
51 + activesupport (4.2.11.1)
52 i18n (~> 0.7)
52 i18n (~> 0.7)
53 - json (~> 1.7, >= 1.7.7)
54 minitest (~> 5.1)
53 minitest (~> 5.1)
55 thread_safe (~> 0.3, >= 0.3.4)
54 thread_safe (~> 0.3, >= 0.3.4)
56 tzinfo (~> 1.1)
55 tzinfo (~> 1.1)
57 ansi (1.5.0)
56 ansi (1.5.0)
58 arel (6.0.4)
57 arel (6.0.4)
59 - autoprefixer-rails (6.6.0)
58 + autoprefixer-rails (9.5.1.1)
60 execjs
59 execjs
61 best_in_place (3.0.3)
60 best_in_place (3.0.3)
62 actionpack (>= 3.2)
61 actionpack (>= 3.2)
63 railties (>= 3.2)
62 railties (>= 3.2)
64 - bootstrap-datepicker-rails (1.7.1.1)
63 + bootstrap-datepicker-rails (1.8.0.1)
65 railties (>= 3.0)
64 railties (>= 3.0)
66 - bootstrap-sass (3.2.0.2)
65 + bootstrap-sass (3.4.1)
67 - sass (~> 3.2)
66 + autoprefixer-rails (>= 5.2.1)
68 - bootstrap-switch-rails (3.3.3)
67 + sassc (>= 2.0.0)
68 + bootstrap-switch-rails (3.3.4)
69 bootstrap-toggle-rails (2.2.1.0)
69 bootstrap-toggle-rails (2.2.1.0)
70 bootstrap3-datetimepicker-rails (4.17.47)
70 bootstrap3-datetimepicker-rails (4.17.47)
71 momentjs-rails (>= 2.8.1)
71 momentjs-rails (>= 2.8.1)
72 - builder (3.2.2)
72 + builder (3.2.3)
73 - coffee-rails (4.2.1)
73 + coffee-rails (4.2.2)
74 coffee-script (>= 2.2.0)
74 coffee-script (>= 2.2.0)
75 - railties (>= 4.0.0, < 5.2.x)
75 + railties (>= 4.0.0)
76 coffee-script (2.4.1)
76 coffee-script (2.4.1)
77 coffee-script-source
77 coffee-script-source
78 execjs
78 execjs
79 coffee-script-source (1.12.2)
79 coffee-script-source (1.12.2)
80 - concurrent-ruby (1.0.4)
80 + concurrent-ruby (1.1.5)
81 + crass (1.0.4)
81 dynamic_form (1.1.4)
82 dynamic_form (1.1.4)
82 erubis (2.7.0)
83 erubis (2.7.0)
83 execjs (2.7.0)
84 execjs (2.7.0)
84 - fuzzy-string-match (1.0.0)
85 + ffi (1.11.1)
86 + fuzzy-string-match (1.0.1)
85 RubyInline (>= 3.8.6)
87 RubyInline (>= 3.8.6)
86 - globalid (0.3.7)
88 + globalid (0.4.2)
87 - activesupport (>= 4.1.0)
89 + activesupport (>= 4.2.0)
88 - haml (4.0.7)
90 + haml (5.1.0)
91 + temple (>= 0.8.0)
89 tilt
92 tilt
90 - haml-rails (0.9.0)
93 + haml-rails (1.0.0)
91 actionpack (>= 4.0.1)
94 actionpack (>= 4.0.1)
92 activesupport (>= 4.0.1)
95 activesupport (>= 4.0.1)
93 - haml (>= 4.0.6, < 5.0)
96 + haml (>= 4.0.6, < 6.0)
94 html2haml (>= 1.0.1)
97 html2haml (>= 1.0.1)
95 railties (>= 4.0.1)
98 railties (>= 4.0.1)
96 - html2haml (2.0.0)
99 + html2haml (2.2.0)
97 erubis (~> 2.7.0)
100 erubis (~> 2.7.0)
98 - haml (~> 4.0.0)
101 + haml (>= 4.0, < 6)
99 - nokogiri (~> 1.6.0)
102 + nokogiri (>= 1.6.0)
100 ruby_parser (~> 3.5)
103 ruby_parser (~> 3.5)
101 - i18n (0.7.0)
104 + i18n (0.9.5)
105 + concurrent-ruby (~> 1.0)
102 in_place_editing (1.2.0)
106 in_place_editing (1.2.0)
103 jquery-countdown-rails (2.0.2)
107 jquery-countdown-rails (2.0.2)
104 jquery-datatables-rails (3.4.0)
108 jquery-datatables-rails (3.4.0)
105 actionpack (>= 3.1)
109 actionpack (>= 3.1)
106 jquery-rails
110 jquery-rails
107 railties (>= 3.1)
111 railties (>= 3.1)
108 sass-rails
112 sass-rails
109 - jquery-rails (4.2.1)
113 + jquery-rails (4.3.3)
110 rails-dom-testing (>= 1, < 3)
114 rails-dom-testing (>= 1, < 3)
111 railties (>= 4.2.0)
115 railties (>= 4.2.0)
112 thor (>= 0.14, < 2.0)
116 thor (>= 0.14, < 2.0)
113 - jquery-tablesorter (1.23.3)
117 + jquery-tablesorter (1.26.1)
114 railties (>= 3.2, < 6)
118 railties (>= 3.2, < 6)
115 jquery-timepicker-addon-rails (1.4.1)
119 jquery-timepicker-addon-rails (1.4.1)
116 railties (>= 3.1)
120 railties (>= 3.1)
117 jquery-ui-rails (6.0.1)
121 jquery-ui-rails (6.0.1)
118 railties (>= 3.2.16)
122 railties (>= 3.2.16)
119 - json (1.8.3)
123 + loofah (2.2.3)
120 - loofah (2.0.3)
124 + crass (~> 1.0.2)
121 nokogiri (>= 1.5.9)
125 nokogiri (>= 1.5.9)
122 - mail (2.6.4)
126 + mail (2.7.1)
123 - mime-types (>= 1.16, < 4)
127 + mini_mime (>= 0.1.1)
124 - mime-types (3.1)
128 + mini_mime (1.0.1)
125 - mime-types-data (~> 3.2015)
129 + mini_portile2 (2.4.0)
126 - mime-types-data (3.2016.0521)
130 + minitest (5.11.3)
127 - mini_portile2 (2.1.0)
131 + minitest-reporters (1.3.6)
128 - minitest (5.10.1)
129 - minitest-reporters (1.1.13)
130 ansi
132 ansi
131 builder
133 builder
132 minitest (>= 5.0)
134 minitest (>= 5.0)
133 ruby-progressbar
135 ruby-progressbar
134 - momentjs-rails (2.15.1)
136 + momentjs-rails (2.20.1)
135 railties (>= 3.1)
137 railties (>= 3.1)
136 - multi_json (1.12.1)
138 + multi_json (1.13.1)
137 - mysql2 (0.4.5)
139 + mysql2 (0.5.2)
138 - nokogiri (1.6.8.1)
140 + nokogiri (1.10.3)
139 - mini_portile2 (~> 2.1.0)
141 + mini_portile2 (~> 2.4.0)
140 - rack (1.6.5)
142 + rack (1.6.11)
141 rack-test (0.6.3)
143 rack-test (0.6.3)
142 rack (>= 1.0)
144 rack (>= 1.0)
143 - rails (4.2.7.1)
145 + rails (4.2.11.1)
144 - actionmailer (= 4.2.7.1)
146 + actionmailer (= 4.2.11.1)
145 - actionpack (= 4.2.7.1)
147 + actionpack (= 4.2.11.1)
146 - actionview (= 4.2.7.1)
148 + actionview (= 4.2.11.1)
147 - activejob (= 4.2.7.1)
149 + activejob (= 4.2.11.1)
148 - activemodel (= 4.2.7.1)
150 + activemodel (= 4.2.11.1)
149 - activerecord (= 4.2.7.1)
151 + activerecord (= 4.2.11.1)
150 - activesupport (= 4.2.7.1)
152 + activesupport (= 4.2.11.1)
151 bundler (>= 1.3.0, < 2.0)
153 bundler (>= 1.3.0, < 2.0)
152 - railties (= 4.2.7.1)
154 + railties (= 4.2.11.1)
153 sprockets-rails
155 sprockets-rails
154 rails-deprecated_sanitizer (1.0.3)
156 rails-deprecated_sanitizer (1.0.3)
155 activesupport (>= 4.2.0.alpha)
157 activesupport (>= 4.2.0.alpha)
156 - rails-dom-testing (1.0.8)
158 + rails-dom-testing (1.0.9)
157 - activesupport (>= 4.2.0.beta, < 5.0)
159 + activesupport (>= 4.2.0, < 5.0)
158 nokogiri (~> 1.6)
160 nokogiri (~> 1.6)
159 rails-deprecated_sanitizer (>= 1.0.1)
161 rails-deprecated_sanitizer (>= 1.0.1)
160 - rails-html-sanitizer (1.0.3)
162 + rails-html-sanitizer (1.0.4)
161 - loofah (~> 2.0)
163 + loofah (~> 2.2, >= 2.2.2)
162 - rails_bootstrap_sortable (2.0.1)
164 + rails_bootstrap_sortable (2.0.6)
163 momentjs-rails (>= 2.8.3)
165 momentjs-rails (>= 2.8.3)
164 - railties (4.2.7.1)
166 + railties (4.2.11.1)
165 - actionpack (= 4.2.7.1)
167 + actionpack (= 4.2.11.1)
166 - activesupport (= 4.2.7.1)
168 + activesupport (= 4.2.11.1)
167 rake (>= 0.8.7)
169 rake (>= 0.8.7)
168 thor (>= 0.18.1, < 2.0)
170 thor (>= 0.18.1, < 2.0)
169 - rake (12.0.0)
171 + rake (12.3.2)
172 + rb-fsevent (0.10.3)
173 + rb-inotify (0.10.0)
174 + ffi (~> 1.0)
170 rdiscount (2.2.0.1)
175 rdiscount (2.2.0.1)
171 - rouge (2.0.7)
176 + rouge (3.3.0)
172 - ruby-progressbar (1.8.1)
177 + ruby-progressbar (1.10.0)
173 - ruby_parser (3.8.3)
178 + ruby_parser (3.13.1)
174 - sexp_processor (~> 4.1)
179 + sexp_processor (~> 4.9)
175 - sass (3.4.23)
180 + sass (3.7.4)
176 - sass-rails (5.0.6)
181 + sass-listen (~> 4.0.0)
182 + sass-listen (4.0.0)
183 + rb-fsevent (~> 0.9, >= 0.9.4)
184 + rb-inotify (~> 0.9, >= 0.9.7)
185 + sass-rails (5.0.7)
177 railties (>= 4.0.0, < 6)
186 railties (>= 4.0.0, < 6)
178 sass (~> 3.1)
187 sass (~> 3.1)
179 sprockets (>= 2.8, < 4.0)
188 sprockets (>= 2.8, < 4.0)
180 sprockets-rails (>= 2.0, < 4.0)
189 sprockets-rails (>= 2.0, < 4.0)
181 tilt (>= 1.1, < 3)
190 tilt (>= 1.1, < 3)
191 + sassc (2.0.1)
192 + ffi (~> 1.9)
193 + rake
194 + sassc-rails (2.1.1)
195 + railties (>= 4.0.0)
196 + sassc (>= 2.0)
197 + sprockets (> 3.0)
198 + sprockets-rails
199 + tilt
182 select2-rails (4.0.3)
200 select2-rails (4.0.3)
183 thor (~> 0.14)
201 thor (~> 0.14)
184 - sexp_processor (4.7.0)
202 + sexp_processor (4.12.0)
185 - sprockets (3.7.1)
203 + sprockets (3.7.2)
186 concurrent-ruby (~> 1.0)
204 concurrent-ruby (~> 1.0)
187 rack (> 1, < 3)
205 rack (> 1, < 3)
188 - sprockets-rails (3.2.0)
206 + sprockets-rails (3.2.1)
189 actionpack (>= 4.0)
207 actionpack (>= 4.0)
190 activesupport (>= 4.0)
208 activesupport (>= 4.0)
191 sprockets (>= 3.0.0)
209 sprockets (>= 3.0.0)
192 - sqlite3 (1.3.12)
210 + sqlite3 (1.4.1)
193 - thor (0.19.4)
211 + temple (0.8.1)
194 - thread_safe (0.3.5)
212 + thor (0.20.3)
195 - tilt (2.0.5)
213 + thread_safe (0.3.6)
196 - tzinfo (1.2.2)
214 + tilt (2.0.9)
215 + tzinfo (1.2.5)
197 thread_safe (~> 0.1)
216 thread_safe (~> 0.1)
198 - uglifier (3.0.4)
217 + uglifier (4.1.20)
199 execjs (>= 0.3.0, < 3)
218 execjs (>= 0.3.0, < 3)
200 will_paginate (3.0.12)
219 will_paginate (3.0.12)
201 - yaml_db (0.4.2)
220 + yaml_db (0.7.0)
202 - rails (>= 3.0, < 5.1)
221 + rails (>= 3.0)
203 rake (>= 0.8.7)
222 rake (>= 0.8.7)
204
223
205 PLATFORMS
224 PLATFORMS
206 ruby
225 ruby
207
226
208 DEPENDENCIES
227 DEPENDENCIES
209 ace-rails-ap
228 ace-rails-ap
210 activerecord-session_store
229 activerecord-session_store
211 autoprefixer-rails
230 autoprefixer-rails
212 best_in_place (~> 3.0.1)
231 best_in_place (~> 3.0.1)
213 bootstrap-datepicker-rails
232 bootstrap-datepicker-rails
214 - bootstrap-sass (~> 3.2.0)
233 + bootstrap-sass (~> 3.4.1)
215 bootstrap-switch-rails
234 bootstrap-switch-rails
216 bootstrap-toggle-rails
235 bootstrap-toggle-rails
217 bootstrap3-datetimepicker-rails
236 bootstrap3-datetimepicker-rails
218 coffee-rails
237 coffee-rails
219 dynamic_form
238 dynamic_form
220 fuzzy-string-match
239 fuzzy-string-match
221 haml
240 haml
222 haml-rails
241 haml-rails
223 in_place_editing
242 in_place_editing
224 jquery-countdown-rails
243 jquery-countdown-rails
225 jquery-datatables-rails
244 jquery-datatables-rails
226 jquery-rails
245 jquery-rails
227 jquery-tablesorter
246 jquery-tablesorter
228 jquery-timepicker-addon-rails
247 jquery-timepicker-addon-rails
229 jquery-ui-rails
248 jquery-ui-rails
230 mail
249 mail
231 minitest-reporters
250 minitest-reporters
232 momentjs-rails
251 momentjs-rails
233 mysql2
252 mysql2
234 rails (~> 4.2.0)
253 rails (~> 4.2.0)
235 rails_bootstrap_sortable
254 rails_bootstrap_sortable
236 rdiscount
255 rdiscount
237 rouge
256 rouge
238 sass-rails
257 sass-rails
258 + sassc-rails (>= 2.1.0)
239 select2-rails
259 select2-rails
240 sqlite3
260 sqlite3
241 uglifier
261 uglifier
242 verification!
262 verification!
243 will_paginate (~> 3.0.7)
263 will_paginate (~> 3.0.7)
244 yaml_db
264 yaml_db
245
265
246 BUNDLED WITH
266 BUNDLED WITH
247 - 1.15.4
267 + 1.17.2
@@ -1,147 +1,145
1 == Installation
1 == Installation
2
2
3 Installing cafe-grader can be done in the following steps.
3 Installing cafe-grader can be done in the following steps.
4
4
5 1. Set up database. We need MySQL 5 database name, username and password.
5 1. Set up database. We need MySQL 5 database name, username and password.
6 2. Install RVM. cafe-grader runs on Ruby on Rails and the best way to install it is to use RVM.
6 2. Install RVM. cafe-grader runs on Ruby on Rails and the best way to install it is to use RVM.
7 3. Install necessary package for the system
7 3. Install necessary package for the system
8 4. Install cafe-grader from github
8 4. Install cafe-grader from github
9 5. Deploy cafe-grader on apache with Phusion Passenger
9 5. Deploy cafe-grader on apache with Phusion Passenger
10
10
11 Very important!!! All commands should be run from a normal user.
11 Very important!!! All commands should be run from a normal user.
12
12
13 The detail of each step are provided as follows.
13 The detail of each step are provided as follows.
14
14
15 === 1. Install MySQL 5
15 === 1. Install MySQL 5
16
16
17 Install MySQL server for the server.
17 Install MySQL server for the server.
18
18
19 cafe@grader:~$ sudo apt install mysql-server
19 cafe@grader:~$ sudo apt install mysql-server
20
20
21 Next, we will connect to mysql as root and set up the database. You can choose your DATABASENAME, USERNAME and PASSWORD as you wish.
21 Next, we will connect to mysql as root and set up the database. You can choose your DATABASENAME, USERNAME and PASSWORD as you wish.
22
22
23 cafe@grader:~$ sudo mysql -u root
23 cafe@grader:~$ sudo mysql -u root
24
24
25 mysql> create database DATABASENAME;
25 mysql> create database DATABASENAME;
26 Query OK, 1 row affected (0.00 sec)
26 Query OK, 1 row affected (0.00 sec)
27
27
28 mysql> grant all privileges on DATABASENAME.* to USERNAME@localhost identified by 'PASSWORD';
28 mysql> grant all privileges on DATABASENAME.* to USERNAME@localhost identified by 'PASSWORD';
29 Query OK, 0 rows affected, 1 warning (0.00 sec)
29 Query OK, 0 rows affected, 1 warning (0.00 sec)
30
30
31 mysql> flush privileges;
31 mysql> flush privileges;
32 Query OK, 0 rows affected (0.00 sec)
32 Query OK, 0 rows affected (0.00 sec)
33
33
34 === 2. Install RVM
34 === 2. Install RVM
35
35
36 Since Ubuntu has dedicated package for RVM we will use that. Just follow instruction given in https://github.com/rvm/ubuntu_rvm. For your convenience, the step are reproduced here.
36 Since Ubuntu has dedicated package for RVM we will use that. Just follow instruction given in https://github.com/rvm/ubuntu_rvm. For your convenience, the step are reproduced here.
37
37
38 First, we install necessary package for installing RVM.
38 First, we install necessary package for installing RVM.
39
39
40 cafe@grader:~$ sudo apt install software-properties-common
40 cafe@grader:~$ sudo apt install software-properties-common
41
41
42 Second, we add the custom PPA, update the system and install RVM.
42 Second, we add the custom PPA, update the system and install RVM.
43
43
44 cafe@grader:~$ sudo apt-add-repository -y ppa:rael-gc/rvm
44 cafe@grader:~$ sudo apt-add-repository -y ppa:rael-gc/rvm
45 cafe@grader:~$ sudo apt-get update
45 cafe@grader:~$ sudo apt-get update
46 cafe@grader:~$ sudo apt-get install rvm
46 cafe@grader:~$ sudo apt-get install rvm
47
47
48 This is very important. You have to logout and login again since RVM change a lots of system.
48 This is very important. You have to logout and login again since RVM change a lots of system.
49
49
50 If you are using GUI version of Ubuntu, be sure to have Gnome Terminal (or any other terminal you are using) perform login every time. This can be done by mark the check box "Run command as a login shell" in Gnome terminal or by adding --login to bash.
50 If you are using GUI version of Ubuntu, be sure to have Gnome Terminal (or any other terminal you are using) perform login every time. This can be done by mark the check box "Run command as a login shell" in Gnome terminal or by adding --login to bash.
51
51
52 === 3. Install necessary package
52 === 3. Install necessary package
53
53
54 - cafe@grader:~$ sudo apt install libmysqlclient-dev default-jdk unzip nodejs php7.2-cli apache2 dirmngr gnupg apache2-dev
54 + cafe@grader:~$ sudo apt install libmysqlclient-dev default-jdk unzip nodejs php-cli apache2 dirmngr gnupg apache2-dev
55 -
56 - curl build-essential
57
55
58 === 4. Install cafe-grader
56 === 4. Install cafe-grader
59
57
60 First, ensure that RVM is installed correctly.
58 First, ensure that RVM is installed correctly.
61
59
62 cafe@grader:~$ rvm
60 cafe@grader:~$ rvm
63
61
64 If you get a result similar to this.
62 If you get a result similar to this.
65
63
66 Command 'rvm' not found, but there are 21 similar ones.
64 Command 'rvm' not found, but there are 21 similar ones.
67
65
68 It is very likely that you have not re-login or you are using bash without --login. Please do so and re-read the installation of RVM on Ubuntu https://github.com/rvm/ubuntu_rvm again.
66 It is very likely that you have not re-login or you are using bash without --login. Please do so and re-read the installation of RVM on Ubuntu https://github.com/rvm/ubuntu_rvm again.
69
67
70 Next, we will let the install script do the work of installing cafe-grader. Please prepare the DATABASENAME, USERNAME and PASSWORD as the script will ask for that. Make sure that you run the script from the home directory of the user.
68 Next, we will let the install script do the work of installing cafe-grader. Please prepare the DATABASENAME, USERNAME and PASSWORD as the script will ask for that. Make sure that you run the script from the home directory of the user.
71
69
72 cafe@grader:~$ wget https://github.com/cafe-grader-team/cafe-grader-judge-scripts/raw/master/installer/install.sh
70 cafe@grader:~$ wget https://github.com/cafe-grader-team/cafe-grader-judge-scripts/raw/master/installer/install.sh
73 cafe@grader:~$ . ./install.sh
71 cafe@grader:~$ . ./install.sh
74
72
75 After installation is finished, grader is ready to run in development mode via WEBrick. We will try that by the following command which will start a grader accessible via http://localhost:3000/. You can try logging in to the system and verify that it is actually work.
73 After installation is finished, grader is ready to run in development mode via WEBrick. We will try that by the following command which will start a grader accessible via http://localhost:3000/. You can try logging in to the system and verify that it is actually work.
76
74
77 cafe@grader:~/cafe_grader/web$ rails s
75 cafe@grader:~/cafe_grader/web$ rails s
78
76
79 If Everything is OK, stop the WEBrick by Ctrl-C.
77 If Everything is OK, stop the WEBrick by Ctrl-C.
80
78
81 We are almost done. The last step is to set up apache and Phusion so that cafe-grader is served by apache.
79 We are almost done. The last step is to set up apache and Phusion so that cafe-grader is served by apache.
82
80
83 === 5. Deploy cafe-grader on Phusion passenger via apache
81 === 5. Deploy cafe-grader on Phusion passenger via apache
84
82
85 This will install a Passenger mod for apache. You can start by visiting https://www.phusionpassenger.com/library/walkthroughs/deploy/ruby/ownserver/apache/oss/install_passenger_main.html and fllow through the guide. We have reproduce the step here for Ubuntu 18.04. For other version, please select the appropriate one on the previous link.
83 This will install a Passenger mod for apache. You can start by visiting https://www.phusionpassenger.com/library/walkthroughs/deploy/ruby/ownserver/apache/oss/install_passenger_main.html and fllow through the guide. We have reproduce the step here for Ubuntu 18.04. For other version, please select the appropriate one on the previous link.
86
84
87 The deploy is divided into two parts: Installing Passenger and deploying the app.
85 The deploy is divided into two parts: Installing Passenger and deploying the app.
88
86
89 ==== 5.1. Installing Passenger as a mod for apache via PPA and enable it.
87 ==== 5.1. Installing Passenger as a mod for apache via PPA and enable it.
90
88
91 cafe@grader:~$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
89 cafe@grader:~$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
92 cafe@grader:~$ sudo apt-get install -y apt-transport-https ca-certificates
90 cafe@grader:~$ sudo apt-get install -y apt-transport-https ca-certificates
93 cafe@grader:~$ sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger bionic main > /etc/apt/sources.list.d/passenger.list'
91 cafe@grader:~$ sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger bionic main > /etc/apt/sources.list.d/passenger.list'
94 cafe@grader:~$ sudo apt-get update
92 cafe@grader:~$ sudo apt-get update
95 cafe@grader:~$ sudo apt-get install -y libapache2-mod-passenger
93 cafe@grader:~$ sudo apt-get install -y libapache2-mod-passenger
96 cafe@grader:~$ sudo a2enmod passenger
94 cafe@grader:~$ sudo a2enmod passenger
97
95
98
96
99 cafe@grader:~$ sudo apache2ctl restart
97 cafe@grader:~$ sudo apache2ctl restart
100
98
101 Finally, we should check that passenger is installed correctly. Run the following command and fix anything as suggested by the command.
99 Finally, we should check that passenger is installed correctly. Run the following command and fix anything as suggested by the command.
102
100
103 cafe@grader:~$ sudo /usr/bin/passenger-config validate-install
101 cafe@grader:~$ sudo /usr/bin/passenger-config validate-install
104
102
105 ==== 5.2. Deploying the app. First, we determine the exact location of our ruby that is installed via RVM.
103 ==== 5.2. Deploying the app. First, we determine the exact location of our ruby that is installed via RVM.
106
104
107 cafe@grader:~$ passenger-config about ruby-command
105 cafe@grader:~$ passenger-config about ruby-command
108 passenger-config was invoked through the following Ruby interpreter:
106 passenger-config was invoked through the following Ruby interpreter:
109 Command: /home/cafe/.rvm/gems/ruby-2.3.7/wrappers/ruby
107 Command: /home/cafe/.rvm/gems/ruby-2.3.7/wrappers/ruby
110 Version: ruby 2.3.7p456 (2018-03-28 revision 63024) [x86_64-linux]
108 Version: ruby 2.3.7p456 (2018-03-28 revision 63024) [x86_64-linux]
111 To use in Apache: PassengerRuby /home/cafe/.rvm/gems/ruby-2.3.7/wrappers/ruby
109 To use in Apache: PassengerRuby /home/cafe/.rvm/gems/ruby-2.3.7/wrappers/ruby
112 To use in Nginx : passenger_ruby /home/cafe/.rvm/gems/ruby-2.3.7/wrappers/ruby
110 To use in Nginx : passenger_ruby /home/cafe/.rvm/gems/ruby-2.3.7/wrappers/ruby
113 To use with Standalone: /home/cafe/.rvm/gems/ruby-2.3.7/wrappers/ruby /usr/bin/passenger start
111 To use with Standalone: /home/cafe/.rvm/gems/ruby-2.3.7/wrappers/ruby /usr/bin/passenger start
114
112
115 Then, take note of the path after "Command". For this guide, it is /home/cafe/.rvm/gems/ruby-2.3.7/wrappers/ruby
113 Then, take note of the path after "Command". For this guide, it is /home/cafe/.rvm/gems/ruby-2.3.7/wrappers/ruby
116
114
117 Assuming that cafe-grader is installed at /home/cafe/cafe_grader, we will edit the Apache's site config file /etc/apache2/site-enabled/000-default.conf as follow.
115 Assuming that cafe-grader is installed at /home/cafe/cafe_grader, we will edit the Apache's site config file /etc/apache2/site-enabled/000-default.conf as follow.
118
116
119 <VirtualHost *:80>
117 <VirtualHost *:80>
120 #ServerName www.example.com
118 #ServerName www.example.com
121
119
122 ServerAdmin webmaster@localhost
120 ServerAdmin webmaster@localhost
123 # dont forget to change the document root
121 # dont forget to change the document root
124 DocumentRoot /home/cafe/cafe_grader/web/public
122 DocumentRoot /home/cafe/cafe_grader/web/public
125
123
126 ErrorLog ${APACHE_LOG_DIR}/error.log
124 ErrorLog ${APACHE_LOG_DIR}/error.log
127 CustomLog ${APACHE_LOG_DIR}/access.log combined
125 CustomLog ${APACHE_LOG_DIR}/access.log combined
128
126
129 # add Passenger
127 # add Passenger
130 PassengerRuby /home/cafe/.rvm/gems/ruby-2.3.7/wrappers/ruby
128 PassengerRuby /home/cafe/.rvm/gems/ruby-2.3.7/wrappers/ruby
131
129
132 # our cafe-grader app
130 # our cafe-grader app
133 <Directory /home/cafe/cafe_grader/web/public>
131 <Directory /home/cafe/cafe_grader/web/public>
134 Allow from all
132 Allow from all
135 Options -MultiViews
133 Options -MultiViews
136 Require all granted
134 Require all granted
137 </Directory>
135 </Directory>
138 </VirtualHost>
136 </VirtualHost>
139
137
140
138
141 Be noted that we make 3 modifications: 1) change DocumentRoot, 2) add PassengerRuby option and add 3) Directory directive
139 Be noted that we make 3 modifications: 1) change DocumentRoot, 2) add PassengerRuby option and add 3) Directory directive
142 As the last step, we restart apache again and the site is ready to be used.
140 As the last step, we restart apache again and the site is ready to be used.
143
141
144 cafe@grader:~$ sudo apache2ctl restart
142 cafe@grader:~$ sudo apache2ctl restart
145
143
146 Now it is done, you can login to the grader with user 'root' and password 'ioionrails'
144 Now it is done, you can login to the grader with user 'root' and password 'ioionrails'
147
145
@@ -115,196 +115,196
115 end
115 end
116
116
117 def destroy
117 def destroy
118 p = Problem.find(params[:id]).destroy
118 p = Problem.find(params[:id]).destroy
119 redirect_to action: :index
119 redirect_to action: :index
120 end
120 end
121
121
122 def toggle
122 def toggle
123 @problem = Problem.find(params[:id])
123 @problem = Problem.find(params[:id])
124 @problem.update_attributes(available: !(@problem.available) )
124 @problem.update_attributes(available: !(@problem.available) )
125 respond_to do |format|
125 respond_to do |format|
126 format.js { }
126 format.js { }
127 end
127 end
128 end
128 end
129
129
130 def toggle_test
130 def toggle_test
131 @problem = Problem.find(params[:id])
131 @problem = Problem.find(params[:id])
132 @problem.update_attributes(test_allowed: !(@problem.test_allowed?) )
132 @problem.update_attributes(test_allowed: !(@problem.test_allowed?) )
133 respond_to do |format|
133 respond_to do |format|
134 format.js { }
134 format.js { }
135 end
135 end
136 end
136 end
137
137
138 def toggle_view_testcase
138 def toggle_view_testcase
139 @problem = Problem.find(params[:id])
139 @problem = Problem.find(params[:id])
140 @problem.update_attributes(view_testcase: !(@problem.view_testcase?) )
140 @problem.update_attributes(view_testcase: !(@problem.view_testcase?) )
141 respond_to do |format|
141 respond_to do |format|
142 format.js { }
142 format.js { }
143 end
143 end
144 end
144 end
145
145
146 def turn_all_off
146 def turn_all_off
147 Problem.available.all.each do |problem|
147 Problem.available.all.each do |problem|
148 problem.available = false
148 problem.available = false
149 problem.save
149 problem.save
150 end
150 end
151 redirect_to action: :index
151 redirect_to action: :index
152 end
152 end
153
153
154 def turn_all_on
154 def turn_all_on
155 Problem.where.not(available: true).each do |problem|
155 Problem.where.not(available: true).each do |problem|
156 problem.available = true
156 problem.available = true
157 problem.save
157 problem.save
158 end
158 end
159 redirect_to action: :index
159 redirect_to action: :index
160 end
160 end
161
161
162 def stat
162 def stat
163 @problem = Problem.find(params[:id])
163 @problem = Problem.find(params[:id])
164 unless @problem.available or session[:admin]
164 unless @problem.available or session[:admin]
165 redirect_to :controller => 'main', :action => 'list'
165 redirect_to :controller => 'main', :action => 'list'
166 return
166 return
167 end
167 end
168 @submissions = Submission.includes(:user).includes(:language).where(problem_id: params[:id]).order(:user_id,:id)
168 @submissions = Submission.includes(:user).includes(:language).where(problem_id: params[:id]).order(:user_id,:id)
169
169
170 #stat summary
170 #stat summary
171 range =65
171 range =65
172 @histogram = { data: Array.new(range,0), summary: {} }
172 @histogram = { data: Array.new(range,0), summary: {} }
173 user = Hash.new(0)
173 user = Hash.new(0)
174 @submissions.find_each do |sub|
174 @submissions.find_each do |sub|
175 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
175 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
176 @histogram[:data][d.to_i] += 1 if d < range
176 @histogram[:data][d.to_i] += 1 if d < range
177 user[sub.user_id] = [user[sub.user_id], ((sub.try(:points) || 0) >= @problem.full_score) ? 1 : 0].max
177 user[sub.user_id] = [user[sub.user_id], ((sub.try(:points) || 0) >= @problem.full_score) ? 1 : 0].max
178 end
178 end
179 @histogram[:summary][:max] = [@histogram[:data].max,1].max
179 @histogram[:summary][:max] = [@histogram[:data].max,1].max
180
180
181 @summary = { attempt: user.count, solve: 0 }
181 @summary = { attempt: user.count, solve: 0 }
182 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
182 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
183 end
183 end
184
184
185 def manage
185 def manage
186 @problems = Problem.order(date_added: :desc)
186 @problems = Problem.order(date_added: :desc)
187 end
187 end
188
188
189 def do_manage
189 def do_manage
190 if params.has_key? 'change_date_added' and params[:date_added].strip.empty? == false
190 if params.has_key? 'change_date_added' and params[:date_added].strip.empty? == false
191 change_date_added
191 change_date_added
192 elsif params.has_key? 'add_to_contest'
192 elsif params.has_key? 'add_to_contest'
193 add_to_contest
193 add_to_contest
194 elsif params.has_key? 'enable_problem'
194 elsif params.has_key? 'enable_problem'
195 set_available(true)
195 set_available(true)
196 elsif params.has_key? 'disable_problem'
196 elsif params.has_key? 'disable_problem'
197 set_available(false)
197 set_available(false)
198 elsif params.has_key? 'add_group'
198 elsif params.has_key? 'add_group'
199 group = Group.find(params[:group_id])
199 group = Group.find(params[:group_id])
200 ok = []
200 ok = []
201 failed = []
201 failed = []
202 get_problems_from_params.each do |p|
202 get_problems_from_params.each do |p|
203 begin
203 begin
204 group.problems << p
204 group.problems << p
205 ok << p.full_name
205 ok << p.full_name
206 rescue => e
206 rescue => e
207 failed << p.full_name
207 failed << p.full_name
208 end
208 end
209 end
209 end
210 flash[:success] = "The following problems are added to the group #{group.name}: " + ok.join(', ') if ok.count > 0
210 flash[:success] = "The following problems are added to the group #{group.name}: " + ok.join(', ') if ok.count > 0
211 flash[:alert] = "The following problems are already in the group #{group.name}: " + failed.join(', ') if failed.count > 0
211 flash[:alert] = "The following problems are already in the group #{group.name}: " + failed.join(', ') if failed.count > 0
212 elsif params.has_key? 'add_tags'
212 elsif params.has_key? 'add_tags'
213 get_problems_from_params.each do |p|
213 get_problems_from_params.each do |p|
214 p.tag_ids += params[:tag_ids]
214 p.tag_ids += params[:tag_ids]
215 end
215 end
216 end
216 end
217
217
218 redirect_to :action => 'manage'
218 redirect_to :action => 'manage'
219 end
219 end
220
220
221 def import
221 def import
222 @allow_test_pair_import = allow_test_pair_import?
222 @allow_test_pair_import = allow_test_pair_import?
223 end
223 end
224
224
225 def do_import
225 def do_import
226 old_problem = Problem.find_by_name(params[:name])
226 old_problem = Problem.find_by_name(params[:name])
227 if !allow_test_pair_import? and params.has_key? :import_to_db
227 if !allow_test_pair_import? and params.has_key? :import_to_db
228 params.delete :import_to_db
228 params.delete :import_to_db
229 end
229 end
230 @problem, import_log = Problem.create_from_import_form_params(params,
230 @problem, import_log = Problem.create_from_import_form_params(params,
231 old_problem)
231 old_problem)
232
232
233 if !@problem.errors.empty?
233 if !@problem.errors.empty?
234 render :action => 'import' and return
234 render :action => 'import' and return
235 end
235 end
236
236
237 if old_problem!=nil
237 if old_problem!=nil
238 flash[:notice] = "The test data has been replaced for problem #{@problem.name}"
238 flash[:notice] = "The test data has been replaced for problem #{@problem.name}"
239 end
239 end
240 @log = import_log
240 @log = import_log
241 end
241 end
242
242
243 def remove_contest
243 def remove_contest
244 problem = Problem.find(params[:id])
244 problem = Problem.find(params[:id])
245 contest = Contest.find(params[:contest_id])
245 contest = Contest.find(params[:contest_id])
246 if problem!=nil and contest!=nil
246 if problem!=nil and contest!=nil
247 problem.contests.delete(contest)
247 problem.contests.delete(contest)
248 end
248 end
249 redirect_to :action => 'manage'
249 redirect_to :action => 'manage'
250 end
250 end
251
251
252 ##################################
252 ##################################
253 protected
253 protected
254
254
255 def allow_test_pair_import?
255 def allow_test_pair_import?
256 if defined? ALLOW_TEST_PAIR_IMPORT
256 if defined? ALLOW_TEST_PAIR_IMPORT
257 return ALLOW_TEST_PAIR_IMPORT
257 return ALLOW_TEST_PAIR_IMPORT
258 else
258 else
259 return false
259 return false
260 end
260 end
261 end
261 end
262
262
263 def change_date_added
263 def change_date_added
264 problems = get_problems_from_params
264 problems = get_problems_from_params
265 date = Date.parse(params[:date_added])
265 date = Date.parse(params[:date_added])
266 problems.each do |p|
266 problems.each do |p|
267 p.date_added = date
267 p.date_added = date
268 p.save
268 p.save
269 end
269 end
270 end
270 end
271
271
272 def add_to_contest
272 def add_to_contest
273 problems = get_problems_from_params
273 problems = get_problems_from_params
274 contest = Contest.find(params[:contest][:id])
274 contest = Contest.find(params[:contest][:id])
275 if contest!=nil and contest.enabled
275 if contest!=nil and contest.enabled
276 problems.each do |p|
276 problems.each do |p|
277 p.contests << contest
277 p.contests << contest
278 end
278 end
279 end
279 end
280 end
280 end
281
281
282 def set_available(avail)
282 def set_available(avail)
283 problems = get_problems_from_params
283 problems = get_problems_from_params
284 problems.each do |p|
284 problems.each do |p|
285 p.available = avail
285 p.available = avail
286 p.save
286 p.save
287 end
287 end
288 end
288 end
289
289
290 def get_problems_from_params
290 def get_problems_from_params
291 problems = []
291 problems = []
292 params.keys.each do |k|
292 params.keys.each do |k|
293 if k.index('prob-')==0
293 if k.index('prob-')==0
294 name, id, order = k.split('-')
294 name, id, order = k.split('-')
295 problems << Problem.find(id)
295 problems << Problem.find(id)
296 end
296 end
297 end
297 end
298 problems
298 problems
299 end
299 end
300
300
301 def get_problems_stat
301 def get_problems_stat
302 end
302 end
303
303
304 private
304 private
305
305
306 def problem_params
306 def problem_params
307 - params.require(:problem).permit(:name, :full_name, :full_score, :date_added, :available, :test_allowed,:output_only, :url, :description, tag_ids:[])
307 + params.require(:problem).permit(:name, :full_name, :full_score, :change_date_added, :date_added, :available, :test_allowed,:output_only, :url, :description, tag_ids:[])
308 end
308 end
309
309
310 end
310 end
@@ -1,144 +1,146
1 class Problem < ActiveRecord::Base
1 class Problem < ActiveRecord::Base
2
2
3 belongs_to :description
3 belongs_to :description
4 has_and_belongs_to_many :contests, :uniq => true
4 has_and_belongs_to_many :contests, :uniq => true
5
5
6 #has_and_belongs_to_many :groups
6 #has_and_belongs_to_many :groups
7 has_many :groups_problems, class_name: GroupProblem
7 has_many :groups_problems, class_name: GroupProblem
8 has_many :groups, :through => :groups_problems
8 has_many :groups, :through => :groups_problems
9
9
10 has_many :problems_tags, class_name: ProblemTag
10 has_many :problems_tags, class_name: ProblemTag
11 has_many :tags, through: :problems_tags
11 has_many :tags, through: :problems_tags
12
12
13 has_many :test_pairs, :dependent => :delete_all
13 has_many :test_pairs, :dependent => :delete_all
14 has_many :testcases, :dependent => :destroy
14 has_many :testcases, :dependent => :destroy
15
15
16 + has_many :submissions
17 +
16 validates_presence_of :name
18 validates_presence_of :name
17 validates_format_of :name, :with => /\A\w+\z/
19 validates_format_of :name, :with => /\A\w+\z/
18 validates_presence_of :full_name
20 validates_presence_of :full_name
19
21
20 scope :available, -> { where(available: true) }
22 scope :available, -> { where(available: true) }
21
23
22 DEFAULT_TIME_LIMIT = 1
24 DEFAULT_TIME_LIMIT = 1
23 DEFAULT_MEMORY_LIMIT = 32
25 DEFAULT_MEMORY_LIMIT = 32
24
26
25 def self.available_problems
27 def self.available_problems
26 available.order(date_added: :desc).order(:name)
28 available.order(date_added: :desc).order(:name)
27 #Problem.available.all(:order => "date_added DESC, name ASC")
29 #Problem.available.all(:order => "date_added DESC, name ASC")
28 end
30 end
29
31
30 def self.create_from_import_form_params(params, old_problem=nil)
32 def self.create_from_import_form_params(params, old_problem=nil)
31 org_problem = old_problem || Problem.new
33 org_problem = old_problem || Problem.new
32 import_params, problem = Problem.extract_params_and_check(params,
34 import_params, problem = Problem.extract_params_and_check(params,
33 org_problem)
35 org_problem)
34
36
35 if !problem.errors.empty?
37 if !problem.errors.empty?
36 return problem, 'Error importing'
38 return problem, 'Error importing'
37 end
39 end
38
40
39 problem.full_score = 100
41 problem.full_score = 100
40 problem.date_added = Time.new
42 problem.date_added = Time.new
41 problem.test_allowed = true
43 problem.test_allowed = true
42 problem.output_only = false
44 problem.output_only = false
43 problem.available = false
45 problem.available = false
44
46
45 if not problem.save
47 if not problem.save
46 return problem, 'Error importing'
48 return problem, 'Error importing'
47 end
49 end
48
50
49 import_to_db = params.has_key? :import_to_db
51 import_to_db = params.has_key? :import_to_db
50
52
51 importer = TestdataImporter.new(problem)
53 importer = TestdataImporter.new(problem)
52
54
53 if not importer.import_from_file(import_params[:file],
55 if not importer.import_from_file(import_params[:file],
54 import_params[:time_limit],
56 import_params[:time_limit],
55 import_params[:memory_limit],
57 import_params[:memory_limit],
56 import_params[:checker_name],
58 import_params[:checker_name],
57 import_to_db)
59 import_to_db)
58 problem.errors.add(:base,'Import error.')
60 problem.errors.add(:base,'Import error.')
59 end
61 end
60
62
61 return problem, importer.log_msg
63 return problem, importer.log_msg
62 end
64 end
63
65
64 def self.download_file_basedir
66 def self.download_file_basedir
65 return "#{Rails.root}/data/tasks"
67 return "#{Rails.root}/data/tasks"
66 end
68 end
67
69
68 def get_submission_stat
70 def get_submission_stat
69 result = Hash.new
71 result = Hash.new
70 #total number of submission
72 #total number of submission
71 result[:total_sub] = Submission.where(problem_id: self.id).count
73 result[:total_sub] = Submission.where(problem_id: self.id).count
72 result[:attempted_user] = Submission.where(problem_id: self.id).group(:user_id)
74 result[:attempted_user] = Submission.where(problem_id: self.id).group(:user_id)
73 result[:pass] = Submission.where(problem_id: self.id).where("points >= ?",self.full_score).count
75 result[:pass] = Submission.where(problem_id: self.id).where("points >= ?",self.full_score).count
74 return result
76 return result
75 end
77 end
76
78
77 def long_name
79 def long_name
78 "[#{name}] #{full_name}"
80 "[#{name}] #{full_name}"
79 end
81 end
80
82
81 protected
83 protected
82
84
83 def self.to_i_or_default(st, default)
85 def self.to_i_or_default(st, default)
84 if st!=''
86 if st!=''
85 result = st.to_i
87 result = st.to_i
86 end
88 end
87 result ||= default
89 result ||= default
88 end
90 end
89
91
90 def self.to_f_or_default(st, default)
92 def self.to_f_or_default(st, default)
91 if st!=''
93 if st!=''
92 result = st.to_f
94 result = st.to_f
93 end
95 end
94 result ||= default
96 result ||= default
95 end
97 end
96
98
97 def self.extract_params_and_check(params, problem)
99 def self.extract_params_and_check(params, problem)
98 time_limit = Problem.to_f_or_default(params[:time_limit],
100 time_limit = Problem.to_f_or_default(params[:time_limit],
99 DEFAULT_TIME_LIMIT)
101 DEFAULT_TIME_LIMIT)
100 memory_limit = Problem.to_i_or_default(params[:memory_limit],
102 memory_limit = Problem.to_i_or_default(params[:memory_limit],
101 DEFAULT_MEMORY_LIMIT)
103 DEFAULT_MEMORY_LIMIT)
102
104
103 if time_limit<=0 or time_limit >60
105 if time_limit<=0 or time_limit >60
104 problem.errors.add(:base,'Time limit out of range.')
106 problem.errors.add(:base,'Time limit out of range.')
105 end
107 end
106
108
107 if memory_limit==0 and params[:memory_limit]!='0'
109 if memory_limit==0 and params[:memory_limit]!='0'
108 problem.errors.add(:base,'Memory limit format errors.')
110 problem.errors.add(:base,'Memory limit format errors.')
109 elsif memory_limit<=0 or memory_limit >512
111 elsif memory_limit<=0 or memory_limit >512
110 problem.errors.add(:base,'Memory limit out of range.')
112 problem.errors.add(:base,'Memory limit out of range.')
111 end
113 end
112
114
113 if params[:file]==nil or params[:file]==''
115 if params[:file]==nil or params[:file]==''
114 problem.errors.add(:base,'No testdata file.')
116 problem.errors.add(:base,'No testdata file.')
115 end
117 end
116
118
117 checker_name = 'text'
119 checker_name = 'text'
118 if ['text','float'].include? params[:checker]
120 if ['text','float'].include? params[:checker]
119 checker_name = params[:checker]
121 checker_name = params[:checker]
120 end
122 end
121
123
122 file = params[:file]
124 file = params[:file]
123
125
124 if !problem.errors.empty?
126 if !problem.errors.empty?
125 return nil, problem
127 return nil, problem
126 end
128 end
127
129
128 problem.name = params[:name]
130 problem.name = params[:name]
129 if params[:full_name]!=''
131 if params[:full_name]!=''
130 problem.full_name = params[:full_name]
132 problem.full_name = params[:full_name]
131 else
133 else
132 problem.full_name = params[:name]
134 problem.full_name = params[:name]
133 end
135 end
134
136
135 return [{
137 return [{
136 :time_limit => time_limit,
138 :time_limit => time_limit,
137 :memory_limit => memory_limit,
139 :memory_limit => memory_limit,
138 :file => file,
140 :file => file,
139 :checker_name => checker_name
141 :checker_name => checker_name
140 },
142 },
141 problem]
143 problem]
142 end
144 end
143
145
144 end
146 end
@@ -1,28 +1,30
1 - if submission.nil?
1 - if submission.nil?
2 = "-"
2 = "-"
3 - else
3 - else
4 %strong= "Submission ID:"
4 %strong= "Submission ID:"
5 = submission.id
5 = submission.id
6 %br
6 %br
7 - unless submission.graded_at
7 - unless submission.graded_at
8 %strong= t 'main.submitted_at:'
8 %strong= t 'main.submitted_at:'
9 = format_full_time_ago(submission.submitted_at.localtime)
9 = format_full_time_ago(submission.submitted_at.localtime)
10 - else
10 - else
11 %strong= t 'main.graded_at:'
11 %strong= t 'main.graded_at:'
12 = format_full_time_ago(submission.graded_at.localtime)
12 = format_full_time_ago(submission.graded_at.localtime)
13 %br
13 %br
14 - if GraderConfiguration['ui.show_score']
14 - if GraderConfiguration['ui.show_score']
15 %strong=t 'main.score'
15 %strong=t 'main.score'
16 = "#{(submission.points*100/submission.problem.full_score).to_i} "
16 = "#{(submission.points*100/submission.problem.full_score).to_i} "
17 = " ["
17 = " ["
18 %tt
18 %tt
19 = submission.grader_comment
19 = submission.grader_comment
20 = "]"
20 = "]"
21 %br
21 %br
22 %strong View:
22 %strong View:
23 - if GraderConfiguration.show_grading_result
23 - if GraderConfiguration.show_grading_result
24 = link_to '[detailed result]', :action => 'result', :id => submission.id
24 = link_to '[detailed result]', :action => 'result', :id => submission.id
25 - = link_to "#{t 'main.cmp_msg'}", {:action => 'compiler_msg', :id => submission.id}, {popup: true,class: 'btn btn-xs btn-info'} if submission.graded_at
25 + - if submission.graded_at
26 + %button.btn.btn-info.btn-xs{type: 'button', data: {toggle: 'modal', target: '#compiler'}}
27 + =t 'main.cmp_msg'
26 = link_to "#{t 'main.src_link'}", download_submission_path(submission.id), class: 'btn btn-xs btn-info'
28 = link_to "#{t 'main.src_link'}", download_submission_path(submission.id), class: 'btn btn-xs btn-info'
27 = link_to "#{t 'main.submissions_link'}", problem_submissions_path(problem_id), class: 'btn btn-xs btn-info'
29 = link_to "#{t 'main.submissions_link'}", problem_submissions_path(problem_id), class: 'btn btn-xs btn-info'
28
30
@@ -1,245 +1,257
1 %h2 Live submit
1 %h2 Live submit
2 %br
2 %br
3
3
4 %textarea#text_sourcecode{style: "display:none"}~ @source
4 %textarea#text_sourcecode{style: "display:none"}~ @source
5 .container
5 .container
6 .row
6 .row
7 .col-md-12
7 .col-md-12
8 .alert.alert-info
8 .alert.alert-info
9 Write your code in the following box, choose language, and click submit button when finished
9 Write your code in the following box, choose language, and click submit button when finished
10 .row
10 .row
11 .col-md-8
11 .col-md-8
12 %div#editor{style: 'height: 500px; border-radius: 7px; font-size: 14px;'}
12 %div#editor{style: 'height: 500px; border-radius: 7px; font-size: 14px;'}
13 .col-md-4
13 .col-md-4
14 - # submission form
14 - # submission form
15 = form_tag({controller: :main, :action => 'submit'}, :multipart => true, class: 'form') do
15 = form_tag({controller: :main, :action => 'submit'}, :multipart => true, class: 'form') do
16
16
17 = hidden_field_tag 'editor_text', @source
17 = hidden_field_tag 'editor_text', @source
18 = hidden_field_tag 'submission[problem_id]', @problem.id
18 = hidden_field_tag 'submission[problem_id]', @problem.id
19 .form-group
19 .form-group
20 = label_tag "Task:"
20 = label_tag "Task:"
21 = text_field_tag 'asdf', "#{@problem.long_name}", class: 'form-control', disabled: true
21 = text_field_tag 'asdf', "#{@problem.long_name}", class: 'form-control', disabled: true
22 .form-group
22 .form-group
23 = label_tag "Description:"
23 = label_tag "Description:"
24 = link_to_description_if_any "[download] <span class='glyphicon glyphicon-file'></span>".html_safe, @problem
24 = link_to_description_if_any "[download] <span class='glyphicon glyphicon-file'></span>".html_safe, @problem
25
25
26 .form-group
26 .form-group
27 = label_tag 'Language:'
27 = label_tag 'Language:'
28 = select_tag 'language_id', options_from_collection_for_select(Language.all, 'id', 'pretty_name', @lang_id || Language.find_by_pretty_name("Python").id || Language.first.id), class: 'form-control select', style: "width: 100px"
28 = select_tag 'language_id', options_from_collection_for_select(Language.all, 'id', 'pretty_name', @lang_id || Language.find_by_pretty_name("Python").id || Language.first.id), class: 'form-control select', style: "width: 100px"
29 .form-group
29 .form-group
30 .input-group
30 .input-group
31 %span.input-group-btn
31 %span.input-group-btn
32 %span.btn.btn-default.btn-file
32 %span.btn.btn-default.btn-file
33 Browse
33 Browse
34 = file_field_tag 'load_file'
34 = file_field_tag 'load_file'
35 = text_field_tag '' , nil, {readonly: true, class: 'form-control'}
35 = text_field_tag '' , nil, {readonly: true, class: 'form-control'}
36 .form-group
36 .form-group
37 = submit_tag 'Submit', class: 'btn btn-success', id: 'live_submit',
37 = submit_tag 'Submit', class: 'btn btn-success', id: 'live_submit',
38 data: {confirm: "Submitting this source code for task #{@problem.long_name}?"}
38 data: {confirm: "Submitting this source code for task #{@problem.long_name}?"}
39 - # latest submission status
39 - # latest submission status
40 .panel{class: (@submission && @submission.graded_at) ? "panel-info" : "panel-warning"}
40 .panel{class: (@submission && @submission.graded_at) ? "panel-info" : "panel-warning"}
41 .panel-heading
41 .panel-heading
42 Latest Submission Status
42 Latest Submission Status
43 = link_to "Refresh",get_latest_submission_status_submissions_path(@submission.user,@problem), class: "btn btn-default btn-sm", remote: true if @submission
43 = link_to "Refresh",get_latest_submission_status_submissions_path(@submission.user,@problem), class: "btn btn-default btn-sm", remote: true if @submission
44 .panel-body
44 .panel-body
45 %div#latest_status
45 %div#latest_status
46 - if @submission
46 - if @submission
47 = render :partial => 'submission_short',
47 = render :partial => 'submission_short',
48 :locals => {submission: @submission, problem_name: @problem.name, problem_id: @problem.id }
48 :locals => {submission: @submission, problem_name: @problem.name, problem_id: @problem.id }
49 .row
49 .row
50 .col-md-12
50 .col-md-12
51 %h2 Console
51 %h2 Console
52 %textarea#console{style: 'height: 100%; width: 100%;background-color:#000;color:#fff;font-family: consolas, monaco, "Droid Sans Mono";',rows: 20}
52 %textarea#console{style: 'height: 100%; width: 100%;background-color:#000;color:#fff;font-family: consolas, monaco, "Droid Sans Mono";',rows: 20}
53
53
54 + .modal.fade#compiler{tabindex: -1,role: 'dialog'}
55 + .modal-dialog.modal-lg{role:'document'}
56 + .modal-content
57 + .modal-header
58 + %button.close{type: 'button', data: {dismissed: :modal}, aria: {label: 'close'}}
59 + %span{aria: {hidden: 'true'}, data: {dismiss: 'modal'}} &times;
60 + %h4 Compiler message
61 + .modal-body
62 + %pre#compiler_msg= @submission.compiler_message
63 + .modal-footer
64 + %button.btn.btn-default{type: 'button', data: {dismiss: 'modal'}} Close
65 +
54 :javascript
66 :javascript
55 $(document).ready(function() {
67 $(document).ready(function() {
56 e = ace.edit("editor")
68 e = ace.edit("editor")
57 e.setValue($("#text_sourcecode").val());
69 e.setValue($("#text_sourcecode").val());
58 e.gotoLine(1);
70 e.gotoLine(1);
59 $("#language_id").trigger('change');
71 $("#language_id").trigger('change');
60
72
61 $("#load_file").on('change',function(evt) {
73 $("#load_file").on('change',function(evt) {
62 var file = evt.target.files[0];
74 var file = evt.target.files[0];
63 var reader = new FileReader();
75 var reader = new FileReader();
64 reader.onload = function(theFile) {
76 reader.onload = function(theFile) {
65 var e = ace.edit("editor")
77 var e = ace.edit("editor")
66 e.setValue(theFile.target.result);
78 e.setValue(theFile.target.result);
67 e.gotoLine(1);
79 e.gotoLine(1);
68 };
80 };
69 reader.readAsText(file)
81 reader.readAsText(file)
70 });
82 });
71
83
72 //brython();
84 //brython();
73 });
85 });
74
86
75
87
76
88
77
89
78
90
79 %script#__main__{type:'text/python3'}
91 %script#__main__{type:'text/python3'}
80 :plain
92 :plain
81 import sys
93 import sys
82 import traceback
94 import traceback
83
95
84 from browser import document as doc
96 from browser import document as doc
85 from browser import window, alert, console
97 from browser import window, alert, console
86
98
87 _credits = """ Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
99 _credits = """ Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands
88 for supporting Python development. See www.python.org for more information."""
100 for supporting Python development. See www.python.org for more information."""
89
101
90 _copyright = """Copyright (c) 2012, Pierre Quentel pierre.quentel@gmail.com
102 _copyright = """Copyright (c) 2012, Pierre Quentel pierre.quentel@gmail.com
91 All Rights Reserved.
103 All Rights Reserved.
92
104
93 Copyright (c) 2001-2013 Python Software Foundation.
105 Copyright (c) 2001-2013 Python Software Foundation.
94 All Rights Reserved.
106 All Rights Reserved.
95
107
96 Copyright (c) 2000 BeOpen.com.
108 Copyright (c) 2000 BeOpen.com.
97 All Rights Reserved.
109 All Rights Reserved.
98
110
99 Copyright (c) 1995-2001 Corporation for National Research Initiatives.
111 Copyright (c) 1995-2001 Corporation for National Research Initiatives.
100 All Rights Reserved.
112 All Rights Reserved.
101
113
102 Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.
114 Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.
103 All Rights Reserved."""
115 All Rights Reserved."""
104
116
105 _license = """Copyright (c) 2012, Pierre Quentel pierre.quentel@gmail.com
117 _license = """Copyright (c) 2012, Pierre Quentel pierre.quentel@gmail.com
106 All rights reserved.
118 All rights reserved.
107
119
108 Redistribution and use in source and binary forms, with or without
120 Redistribution and use in source and binary forms, with or without
109 modification, are permitted provided that the following conditions are met:
121 modification, are permitted provided that the following conditions are met:
110
122
111 Redistributions of source code must retain the above copyright notice, this
123 Redistributions of source code must retain the above copyright notice, this
112 list of conditions and the following disclaimer. Redistributions in binary
124 list of conditions and the following disclaimer. Redistributions in binary
113 form must reproduce the above copyright notice, this list of conditions and
125 form must reproduce the above copyright notice, this list of conditions and
114 the following disclaimer in the documentation and/or other materials provided
126 the following disclaimer in the documentation and/or other materials provided
115 with the distribution.
127 with the distribution.
116 Neither the name of the <ORGANIZATION> nor the names of its contributors may
128 Neither the name of the <ORGANIZATION> nor the names of its contributors may
117 be used to endorse or promote products derived from this software without
129 be used to endorse or promote products derived from this software without
118 specific prior written permission.
130 specific prior written permission.
119
131
120 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
132 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
121 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
133 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
122 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
134 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
123 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
135 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
124 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
136 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
125 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
137 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
126 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
138 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
127 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
139 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
128 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
140 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
129 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
141 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
130 POSSIBILITY OF SUCH DAMAGE.
142 POSSIBILITY OF SUCH DAMAGE.
131 """
143 """
132
144
133 def credits():
145 def credits():
134 print(_credits)
146 print(_credits)
135 credits.__repr__ = lambda:_credits
147 credits.__repr__ = lambda:_credits
136
148
137 def copyright():
149 def copyright():
138 print(_copyright)
150 print(_copyright)
139 copyright.__repr__ = lambda:_copyright
151 copyright.__repr__ = lambda:_copyright
140
152
141 def license():
153 def license():
142 print(_license)
154 print(_license)
143 license.__repr__ = lambda:_license
155 license.__repr__ = lambda:_license
144
156
145 def write(data):
157 def write(data):
146 doc['console'].value += str(data)
158 doc['console'].value += str(data)
147
159
148
160
149 sys.stdout.write = sys.stderr.write = write
161 sys.stdout.write = sys.stderr.write = write
150 history = []
162 history = []
151 current = 0
163 current = 0
152 _status = "main" # or "block" if typing inside a block
164 _status = "main" # or "block" if typing inside a block
153
165
154 # execution namespace
166 # execution namespace
155 editor_ns = {'credits':credits,
167 editor_ns = {'credits':credits,
156 'copyright':copyright,
168 'copyright':copyright,
157 'license':license,
169 'license':license,
158 '__name__':'__main__'}
170 '__name__':'__main__'}
159
171
160 def cursorToEnd(*args):
172 def cursorToEnd(*args):
161 pos = len(doc['console'].value)
173 pos = len(doc['console'].value)
162 doc['console'].setSelectionRange(pos, pos)
174 doc['console'].setSelectionRange(pos, pos)
163 doc['console'].scrollTop = doc['console'].scrollHeight
175 doc['console'].scrollTop = doc['console'].scrollHeight
164
176
165 def get_col(area):
177 def get_col(area):
166 # returns the column num of cursor
178 # returns the column num of cursor
167 sel = doc['console'].selectionStart
179 sel = doc['console'].selectionStart
168 lines = doc['console'].value.split('\n')
180 lines = doc['console'].value.split('\n')
169 for line in lines[:-1]:
181 for line in lines[:-1]:
170 sel -= len(line) + 1
182 sel -= len(line) + 1
171 return sel
183 return sel
172
184
173
185
174 def myKeyPress(event):
186 def myKeyPress(event):
175 global _status, current
187 global _status, current
176 if event.keyCode == 9: # tab key
188 if event.keyCode == 9: # tab key
177 event.preventDefault()
189 event.preventDefault()
178 doc['console'].value += " "
190 doc['console'].value += " "
179 elif event.keyCode == 13: # return
191 elif event.keyCode == 13: # return
180 src = doc['console'].value
192 src = doc['console'].value
181 if _status == "main":
193 if _status == "main":
182 currentLine = src[src.rfind('>>>') + 4:]
194 currentLine = src[src.rfind('>>>') + 4:]
183 elif _status == "3string":
195 elif _status == "3string":
184 currentLine = src[src.rfind('>>>') + 4:]
196 currentLine = src[src.rfind('>>>') + 4:]
185 currentLine = currentLine.replace('\n... ', '\n')
197 currentLine = currentLine.replace('\n... ', '\n')
186 else:
198 else:
187 currentLine = src[src.rfind('...') + 4:]
199 currentLine = src[src.rfind('...') + 4:]
188 if _status == 'main' and not currentLine.strip():
200 if _status == 'main' and not currentLine.strip():
189 doc['console'].value += '\n>>> '
201 doc['console'].value += '\n>>> '
190 event.preventDefault()
202 event.preventDefault()
191 return
203 return
192 doc['console'].value += '\n'
204 doc['console'].value += '\n'
193 history.append(currentLine)
205 history.append(currentLine)
194 current = len(history)
206 current = len(history)
195 if _status == "main" or _status == "3string":
207 if _status == "main" or _status == "3string":
196 try:
208 try:
197 _ = editor_ns['_'] = eval(currentLine, editor_ns)
209 _ = editor_ns['_'] = eval(currentLine, editor_ns)
198 if _ is not None:
210 if _ is not None:
199 write(repr(_)+'\n')
211 write(repr(_)+'\n')
200 doc['console'].value += '>>> '
212 doc['console'].value += '>>> '
201 _status = "main"
213 _status = "main"
202 except IndentationError:
214 except IndentationError:
203 doc['console'].value += '... '
215 doc['console'].value += '... '
204 _status = "block"
216 _status = "block"
205 except SyntaxError as msg:
217 except SyntaxError as msg:
206 if str(msg) == 'invalid syntax : triple string end not found' or \
218 if str(msg) == 'invalid syntax : triple string end not found' or \
207 str(msg).startswith('Unbalanced bracket'):
219 str(msg).startswith('Unbalanced bracket'):
208 doc['console'].value += '... '
220 doc['console'].value += '... '
209 _status = "3string"
221 _status = "3string"
210 elif str(msg) == 'eval() argument must be an expression':
222 elif str(msg) == 'eval() argument must be an expression':
211 try:
223 try:
212 exec(currentLine, editor_ns)
224 exec(currentLine, editor_ns)
213 except:
225 except:
214 traceback.print_exc()
226 traceback.print_exc()
215 doc['console'].value += '>>> '
227 doc['console'].value += '>>> '
216 _status = "main"
228 _status = "main"
217 elif str(msg) == 'decorator expects function':
229 elif str(msg) == 'decorator expects function':
218 doc['console'].value += '... '
230 doc['console'].value += '... '
219 _status = "block"
231 _status = "block"
220 else:
232 else:
221 traceback.print_exc()
233 traceback.print_exc()
222 doc['console'].value += '>>> '
234 doc['console'].value += '>>> '
223 _status = "main"
235 _status = "main"
224 except:
236 except:
225 traceback.print_exc()
237 traceback.print_exc()
226 doc['console'].value += '>>> '
238 doc['console'].value += '>>> '
227 _status = "main"
239 _status = "main"
228 elif currentLine == "": # end of block
240 elif currentLine == "": # end of block
229 block = src[src.rfind('>>>') + 4:].splitlines()
241 block = src[src.rfind('>>>') + 4:].splitlines()
230 block = [block[0]] + [b[4:] for b in block[1:]]
242 block = [block[0]] + [b[4:] for b in block[1:]]
231 block_src = '\n'.join(block)
243 block_src = '\n'.join(block)
232 # status must be set before executing code in globals()
244 # status must be set before executing code in globals()
233 _status = "main"
245 _status = "main"
234 try:
246 try:
235 _ = exec(block_src, editor_ns)
247 _ = exec(block_src, editor_ns)
236 if _ is not None:
248 if _ is not None:
237 print(repr(_))
249 print(repr(_))
238 except:
250 except:
239 traceback.print_exc()
251 traceback.print_exc()
240 doc['console'].value += '>>> '
252 doc['console'].value += '>>> '
241 else:
253 else:
242 doc['console'].value += '... '
254 doc['console'].value += '... '
243
255
244 cursorToEnd()
256 cursorToEnd()
245 event.preventDefault()
257 event.preventDefault()
@@ -1,35 +1,36
1 = user_title_bar(@user)
1 = user_title_bar(@user)
2
2
3 %h1 Your account settings
3 %h1 Your account settings
4
4
5 -#%p
5 -#%p
6 -#You can edit your alias and e-mails. Just click on the text and edit it.
6 -#You can edit your alias and e-mails. Just click on the text and edit it.
7
7
8 - %table.uinfo
8 + %table.table.table-bordered{:style => "width:30%"}
9 %tr
9 %tr
10 - %th.uinfo Login
10 + %th Login
11 - %td.uinfo= @user.login
11 + %td= @user.login
12 %tr
12 %tr
13 - %th.uinfo Full name
13 + %th Full name
14 - %td.uinfo= @user.full_name
14 + %td= @user.full_name
15 -#%tr
15 -#%tr
16 -#%th.uinfo Alias
16 -#%th.uinfo Alias
17 -#%td.uinfo= in_place_editor_field :user, 'alias_for_editing', {}, :rows => 1
17 -#%td.uinfo= in_place_editor_field :user, 'alias_for_editing', {}, :rows => 1
18 -#%tr
18 -#%tr
19 -#%th.uinfo E-mail
19 -#%th.uinfo E-mail
20 -#%td.uinfo= in_place_editor_field :user, 'email_for_editing', {}, :rows => 1
20 -#%td.uinfo= in_place_editor_field :user, 'email_for_editing', {}, :rows => 1
21 %tr
21 %tr
22 - %th.uinfo Password
22 + %th Password
23 - %td.uinfo
23 + %td
24 = form_tag :action => 'chg_passwd', :method => 'post' do
24 = form_tag :action => 'chg_passwd', :method => 'post' do
25 %table
25 %table
26 %tr
26 %tr
27 - %td= password_field_tag 'passwd'
27 + %td
28 + %input{:type => "password", :class => "form-control", :name => "passwd", :id => "passwd"}
28 %td (new)
29 %td (new)
29 %tr
30 %tr
30 - %td= password_field_tag 'passwd_verify'
31 + %td
32 + %input{:type => "password", :class => "form-control", :name => "passwd_verify", :id => "passwd_verify"}
31 %td (verify)
33 %td (verify)
32 %tr
34 %tr
33 %td{:colspan => "2"}
35 %td{:colspan => "2"}
34 - = submit_tag 'change password'
36 + %input{:type => "button", :class => "btn btn-default", :name => "commit", :value => "Change Password"}
35 -
@@ -1,321 +1,321
1 # encoding: UTF-8
1 # encoding: UTF-8
2 # This file is auto-generated from the current state of the database. Instead
2 # This file is auto-generated from the current state of the database. Instead
3 # of editing this file, please use the migrations feature of Active Record to
3 # of editing this file, please use the migrations feature of Active Record to
4 # incrementally modify your database, and then regenerate this schema definition.
4 # incrementally modify your database, and then regenerate this schema definition.
5 #
5 #
6 # Note that this schema.rb definition is the authoritative source for your
6 # Note that this schema.rb definition is the authoritative source for your
7 # database schema. If you need to create the application database on another
7 # database schema. If you need to create the application database on another
8 # system, you should be using db:schema:load, not running all the migrations
8 # system, you should be using db:schema:load, not running all the migrations
9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10 # you'll amass, the slower it'll run and the greater likelihood for issues).
10 # you'll amass, the slower it'll run and the greater likelihood for issues).
11 #
11 #
12 # It's strongly recommended that you check this file into your version control system.
12 # It's strongly recommended that you check this file into your version control system.
13
13
14 ActiveRecord::Schema.define(version: 20180612102327) do
14 ActiveRecord::Schema.define(version: 20180612102327) do
15
15
16 create_table "announcements", force: :cascade do |t|
16 create_table "announcements", force: :cascade do |t|
17 t.string "author", limit: 255
17 t.string "author", limit: 255
18 t.text "body", limit: 65535
18 t.text "body", limit: 65535
19 t.boolean "published"
19 t.boolean "published"
20 - t.datetime "created_at", null: false
20 + t.datetime "created_at"
21 - t.datetime "updated_at", null: false
21 + t.datetime "updated_at"
22 t.boolean "frontpage", default: false
22 t.boolean "frontpage", default: false
23 t.boolean "contest_only", default: false
23 t.boolean "contest_only", default: false
24 t.string "title", limit: 255
24 t.string "title", limit: 255
25 t.string "notes", limit: 255
25 t.string "notes", limit: 255
26 end
26 end
27
27
28 create_table "contests", force: :cascade do |t|
28 create_table "contests", force: :cascade do |t|
29 t.string "title", limit: 255
29 t.string "title", limit: 255
30 t.boolean "enabled"
30 t.boolean "enabled"
31 - t.datetime "created_at", null: false
31 + t.datetime "created_at"
32 - t.datetime "updated_at", null: false
32 + t.datetime "updated_at"
33 t.string "name", limit: 255
33 t.string "name", limit: 255
34 end
34 end
35
35
36 create_table "contests_problems", id: false, force: :cascade do |t|
36 create_table "contests_problems", id: false, force: :cascade do |t|
37 t.integer "contest_id", limit: 4
37 t.integer "contest_id", limit: 4
38 t.integer "problem_id", limit: 4
38 t.integer "problem_id", limit: 4
39 end
39 end
40
40
41 create_table "contests_users", id: false, force: :cascade do |t|
41 create_table "contests_users", id: false, force: :cascade do |t|
42 t.integer "contest_id", limit: 4
42 t.integer "contest_id", limit: 4
43 t.integer "user_id", limit: 4
43 t.integer "user_id", limit: 4
44 end
44 end
45
45
46 create_table "countries", force: :cascade do |t|
46 create_table "countries", force: :cascade do |t|
47 t.string "name", limit: 255
47 t.string "name", limit: 255
48 - t.datetime "created_at", null: false
48 + t.datetime "created_at"
49 - t.datetime "updated_at", null: false
49 + t.datetime "updated_at"
50 end
50 end
51
51
52 create_table "descriptions", force: :cascade do |t|
52 create_table "descriptions", force: :cascade do |t|
53 t.text "body", limit: 65535
53 t.text "body", limit: 65535
54 t.boolean "markdowned"
54 t.boolean "markdowned"
55 - t.datetime "created_at", null: false
55 + t.datetime "created_at"
56 - t.datetime "updated_at", null: false
56 + t.datetime "updated_at"
57 end
57 end
58
58
59 create_table "grader_configurations", force: :cascade do |t|
59 create_table "grader_configurations", force: :cascade do |t|
60 t.string "key", limit: 255
60 t.string "key", limit: 255
61 t.string "value_type", limit: 255
61 t.string "value_type", limit: 255
62 t.string "value", limit: 255
62 t.string "value", limit: 255
63 - t.datetime "created_at", null: false
63 + t.datetime "created_at"
64 - t.datetime "updated_at", null: false
64 + t.datetime "updated_at"
65 t.text "description", limit: 65535
65 t.text "description", limit: 65535
66 end
66 end
67
67
68 create_table "grader_processes", force: :cascade do |t|
68 create_table "grader_processes", force: :cascade do |t|
69 t.string "host", limit: 255
69 t.string "host", limit: 255
70 t.integer "pid", limit: 4
70 t.integer "pid", limit: 4
71 t.string "mode", limit: 255
71 t.string "mode", limit: 255
72 t.boolean "active"
72 t.boolean "active"
73 - t.datetime "created_at", null: false
73 + t.datetime "created_at"
74 - t.datetime "updated_at", null: false
74 + t.datetime "updated_at"
75 t.integer "task_id", limit: 4
75 t.integer "task_id", limit: 4
76 t.string "task_type", limit: 255
76 t.string "task_type", limit: 255
77 t.boolean "terminated"
77 t.boolean "terminated"
78 end
78 end
79
79
80 - add_index "grader_processes", ["host", "pid"], name: "index_grader_processes_on_ip_and_pid", using: :btree
80 + add_index "grader_processes", ["host", "pid"], name: "index_grader_processes_on_host_and_pid", using: :btree
81
81
82 create_table "groups", force: :cascade do |t|
82 create_table "groups", force: :cascade do |t|
83 t.string "name", limit: 255
83 t.string "name", limit: 255
84 t.string "description", limit: 255
84 t.string "description", limit: 255
85 end
85 end
86
86
87 create_table "groups_problems", id: false, force: :cascade do |t|
87 create_table "groups_problems", id: false, force: :cascade do |t|
88 t.integer "problem_id", limit: 4, null: false
88 t.integer "problem_id", limit: 4, null: false
89 t.integer "group_id", limit: 4, null: false
89 t.integer "group_id", limit: 4, null: false
90 end
90 end
91
91
92 add_index "groups_problems", ["group_id", "problem_id"], name: "index_groups_problems_on_group_id_and_problem_id", using: :btree
92 add_index "groups_problems", ["group_id", "problem_id"], name: "index_groups_problems_on_group_id_and_problem_id", using: :btree
93
93
94 create_table "groups_users", id: false, force: :cascade do |t|
94 create_table "groups_users", id: false, force: :cascade do |t|
95 t.integer "group_id", limit: 4, null: false
95 t.integer "group_id", limit: 4, null: false
96 t.integer "user_id", limit: 4, null: false
96 t.integer "user_id", limit: 4, null: false
97 end
97 end
98
98
99 add_index "groups_users", ["user_id", "group_id"], name: "index_groups_users_on_user_id_and_group_id", using: :btree
99 add_index "groups_users", ["user_id", "group_id"], name: "index_groups_users_on_user_id_and_group_id", using: :btree
100
100
101 create_table "heart_beats", force: :cascade do |t|
101 create_table "heart_beats", force: :cascade do |t|
102 t.integer "user_id", limit: 4
102 t.integer "user_id", limit: 4
103 t.string "ip_address", limit: 255
103 t.string "ip_address", limit: 255
104 - t.datetime "created_at", null: false
104 + t.datetime "created_at"
105 - t.datetime "updated_at", null: false
105 + t.datetime "updated_at"
106 t.string "status", limit: 255
106 t.string "status", limit: 255
107 end
107 end
108
108
109 add_index "heart_beats", ["updated_at"], name: "index_heart_beats_on_updated_at", using: :btree
109 add_index "heart_beats", ["updated_at"], name: "index_heart_beats_on_updated_at", using: :btree
110
110
111 create_table "languages", force: :cascade do |t|
111 create_table "languages", force: :cascade do |t|
112 t.string "name", limit: 10
112 t.string "name", limit: 10
113 t.string "pretty_name", limit: 255
113 t.string "pretty_name", limit: 255
114 t.string "ext", limit: 10
114 t.string "ext", limit: 10
115 t.string "common_ext", limit: 255
115 t.string "common_ext", limit: 255
116 end
116 end
117
117
118 create_table "logins", force: :cascade do |t|
118 create_table "logins", force: :cascade do |t|
119 t.integer "user_id", limit: 4
119 t.integer "user_id", limit: 4
120 t.string "ip_address", limit: 255
120 t.string "ip_address", limit: 255
121 - t.datetime "created_at", null: false
121 + t.datetime "created_at"
122 - t.datetime "updated_at", null: false
122 + t.datetime "updated_at"
123 end
123 end
124
124
125 create_table "messages", force: :cascade do |t|
125 create_table "messages", force: :cascade do |t|
126 t.integer "sender_id", limit: 4
126 t.integer "sender_id", limit: 4
127 t.integer "receiver_id", limit: 4
127 t.integer "receiver_id", limit: 4
128 t.integer "replying_message_id", limit: 4
128 t.integer "replying_message_id", limit: 4
129 t.text "body", limit: 65535
129 t.text "body", limit: 65535
130 t.boolean "replied"
130 t.boolean "replied"
131 - t.datetime "created_at", null: false
131 + t.datetime "created_at"
132 - t.datetime "updated_at", null: false
132 + t.datetime "updated_at"
133 end
133 end
134
134
135 create_table "problems", force: :cascade do |t|
135 create_table "problems", force: :cascade do |t|
136 t.string "name", limit: 30
136 t.string "name", limit: 30
137 t.string "full_name", limit: 255
137 t.string "full_name", limit: 255
138 t.integer "full_score", limit: 4
138 t.integer "full_score", limit: 4
139 t.date "date_added"
139 t.date "date_added"
140 t.boolean "available"
140 t.boolean "available"
141 t.string "url", limit: 255
141 t.string "url", limit: 255
142 t.integer "description_id", limit: 4
142 t.integer "description_id", limit: 4
143 t.boolean "test_allowed"
143 t.boolean "test_allowed"
144 t.boolean "output_only"
144 t.boolean "output_only"
145 t.string "description_filename", limit: 255
145 t.string "description_filename", limit: 255
146 t.boolean "view_testcase"
146 t.boolean "view_testcase"
147 end
147 end
148
148
149 create_table "problems_tags", force: :cascade do |t|
149 create_table "problems_tags", force: :cascade do |t|
150 t.integer "problem_id", limit: 4
150 t.integer "problem_id", limit: 4
151 t.integer "tag_id", limit: 4
151 t.integer "tag_id", limit: 4
152 end
152 end
153
153
154 add_index "problems_tags", ["problem_id", "tag_id"], name: "index_problems_tags_on_problem_id_and_tag_id", unique: true, using: :btree
154 add_index "problems_tags", ["problem_id", "tag_id"], name: "index_problems_tags_on_problem_id_and_tag_id", unique: true, using: :btree
155 add_index "problems_tags", ["problem_id"], name: "index_problems_tags_on_problem_id", using: :btree
155 add_index "problems_tags", ["problem_id"], name: "index_problems_tags_on_problem_id", using: :btree
156 add_index "problems_tags", ["tag_id"], name: "index_problems_tags_on_tag_id", using: :btree
156 add_index "problems_tags", ["tag_id"], name: "index_problems_tags_on_tag_id", using: :btree
157
157
158 create_table "rights", force: :cascade do |t|
158 create_table "rights", force: :cascade do |t|
159 t.string "name", limit: 255
159 t.string "name", limit: 255
160 t.string "controller", limit: 255
160 t.string "controller", limit: 255
161 t.string "action", limit: 255
161 t.string "action", limit: 255
162 end
162 end
163
163
164 create_table "rights_roles", id: false, force: :cascade do |t|
164 create_table "rights_roles", id: false, force: :cascade do |t|
165 t.integer "right_id", limit: 4
165 t.integer "right_id", limit: 4
166 t.integer "role_id", limit: 4
166 t.integer "role_id", limit: 4
167 end
167 end
168
168
169 add_index "rights_roles", ["role_id"], name: "index_rights_roles_on_role_id", using: :btree
169 add_index "rights_roles", ["role_id"], name: "index_rights_roles_on_role_id", using: :btree
170
170
171 create_table "roles", force: :cascade do |t|
171 create_table "roles", force: :cascade do |t|
172 t.string "name", limit: 255
172 t.string "name", limit: 255
173 end
173 end
174
174
175 create_table "roles_users", id: false, force: :cascade do |t|
175 create_table "roles_users", id: false, force: :cascade do |t|
176 t.integer "role_id", limit: 4
176 t.integer "role_id", limit: 4
177 t.integer "user_id", limit: 4
177 t.integer "user_id", limit: 4
178 end
178 end
179
179
180 add_index "roles_users", ["user_id"], name: "index_roles_users_on_user_id", using: :btree
180 add_index "roles_users", ["user_id"], name: "index_roles_users_on_user_id", using: :btree
181
181
182 create_table "sessions", force: :cascade do |t|
182 create_table "sessions", force: :cascade do |t|
183 t.string "session_id", limit: 255
183 t.string "session_id", limit: 255
184 t.text "data", limit: 65535
184 t.text "data", limit: 65535
185 t.datetime "updated_at"
185 t.datetime "updated_at"
186 end
186 end
187
187
188 add_index "sessions", ["session_id"], name: "index_sessions_on_session_id", using: :btree
188 add_index "sessions", ["session_id"], name: "index_sessions_on_session_id", using: :btree
189 add_index "sessions", ["updated_at"], name: "index_sessions_on_updated_at", using: :btree
189 add_index "sessions", ["updated_at"], name: "index_sessions_on_updated_at", using: :btree
190
190
191 create_table "sites", force: :cascade do |t|
191 create_table "sites", force: :cascade do |t|
192 t.string "name", limit: 255
192 t.string "name", limit: 255
193 t.boolean "started"
193 t.boolean "started"
194 t.datetime "start_time"
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
197 t.integer "country_id", limit: 4
198 t.string "password", limit: 255
198 t.string "password", limit: 255
199 end
199 end
200
200
201 create_table "submission_view_logs", force: :cascade do |t|
201 create_table "submission_view_logs", force: :cascade do |t|
202 t.integer "user_id", limit: 4
202 t.integer "user_id", limit: 4
203 t.integer "submission_id", limit: 4
203 t.integer "submission_id", limit: 4
204 - t.datetime "created_at", null: false
204 + t.datetime "created_at"
205 - t.datetime "updated_at", null: false
205 + t.datetime "updated_at"
206 end
206 end
207
207
208 create_table "submissions", force: :cascade do |t|
208 create_table "submissions", force: :cascade do |t|
209 t.integer "user_id", limit: 4
209 t.integer "user_id", limit: 4
210 t.integer "problem_id", limit: 4
210 t.integer "problem_id", limit: 4
211 t.integer "language_id", limit: 4
211 t.integer "language_id", limit: 4
212 t.text "source", limit: 16777215
212 t.text "source", limit: 16777215
213 t.binary "binary", limit: 65535
213 t.binary "binary", limit: 65535
214 t.datetime "submitted_at"
214 t.datetime "submitted_at"
215 t.datetime "compiled_at"
215 t.datetime "compiled_at"
216 t.text "compiler_message", limit: 65535
216 t.text "compiler_message", limit: 65535
217 t.datetime "graded_at"
217 t.datetime "graded_at"
218 t.integer "points", limit: 4
218 t.integer "points", limit: 4
219 t.text "grader_comment", limit: 65535
219 t.text "grader_comment", limit: 65535
220 t.integer "number", limit: 4
220 t.integer "number", limit: 4
221 t.string "source_filename", limit: 255
221 t.string "source_filename", limit: 255
222 t.float "max_runtime", limit: 24
222 t.float "max_runtime", limit: 24
223 t.integer "peak_memory", limit: 4
223 t.integer "peak_memory", limit: 4
224 t.integer "effective_code_length", limit: 4
224 t.integer "effective_code_length", limit: 4
225 t.string "ip_address", limit: 255
225 t.string "ip_address", limit: 255
226 end
226 end
227
227
228 add_index "submissions", ["user_id", "problem_id", "number"], name: "index_submissions_on_user_id_and_problem_id_and_number", unique: true, using: :btree
228 add_index "submissions", ["user_id", "problem_id", "number"], name: "index_submissions_on_user_id_and_problem_id_and_number", unique: true, using: :btree
229 add_index "submissions", ["user_id", "problem_id"], name: "index_submissions_on_user_id_and_problem_id", using: :btree
229 add_index "submissions", ["user_id", "problem_id"], name: "index_submissions_on_user_id_and_problem_id", using: :btree
230
230
231 create_table "tags", force: :cascade do |t|
231 create_table "tags", force: :cascade do |t|
232 t.string "name", limit: 255, null: false
232 t.string "name", limit: 255, null: false
233 t.text "description", limit: 65535
233 t.text "description", limit: 65535
234 t.boolean "public"
234 t.boolean "public"
235 t.datetime "created_at", null: false
235 t.datetime "created_at", null: false
236 t.datetime "updated_at", null: false
236 t.datetime "updated_at", null: false
237 end
237 end
238
238
239 create_table "tasks", force: :cascade do |t|
239 create_table "tasks", force: :cascade do |t|
240 t.integer "submission_id", limit: 4
240 t.integer "submission_id", limit: 4
241 t.datetime "created_at"
241 t.datetime "created_at"
242 t.integer "status", limit: 4
242 t.integer "status", limit: 4
243 t.datetime "updated_at"
243 t.datetime "updated_at"
244 end
244 end
245
245
246 add_index "tasks", ["submission_id"], name: "index_tasks_on_submission_id", using: :btree
246 add_index "tasks", ["submission_id"], name: "index_tasks_on_submission_id", using: :btree
247
247
248 create_table "test_pairs", force: :cascade do |t|
248 create_table "test_pairs", force: :cascade do |t|
249 t.integer "problem_id", limit: 4
249 t.integer "problem_id", limit: 4
250 t.text "input", limit: 16777215
250 t.text "input", limit: 16777215
251 t.text "solution", limit: 16777215
251 t.text "solution", limit: 16777215
252 - t.datetime "created_at", null: false
252 + t.datetime "created_at"
253 - t.datetime "updated_at", null: false
253 + t.datetime "updated_at"
254 end
254 end
255
255
256 create_table "test_requests", force: :cascade do |t|
256 create_table "test_requests", force: :cascade do |t|
257 t.integer "user_id", limit: 4
257 t.integer "user_id", limit: 4
258 t.integer "problem_id", limit: 4
258 t.integer "problem_id", limit: 4
259 t.integer "submission_id", limit: 4
259 t.integer "submission_id", limit: 4
260 t.string "input_file_name", limit: 255
260 t.string "input_file_name", limit: 255
261 t.string "output_file_name", limit: 255
261 t.string "output_file_name", limit: 255
262 t.string "running_stat", limit: 255
262 t.string "running_stat", limit: 255
263 t.integer "status", limit: 4
263 t.integer "status", limit: 4
264 - t.datetime "updated_at", null: false
264 + t.datetime "updated_at"
265 t.datetime "submitted_at"
265 t.datetime "submitted_at"
266 t.datetime "compiled_at"
266 t.datetime "compiled_at"
267 t.text "compiler_message", limit: 65535
267 t.text "compiler_message", limit: 65535
268 t.datetime "graded_at"
268 t.datetime "graded_at"
269 t.string "grader_comment", limit: 255
269 t.string "grader_comment", limit: 255
270 - t.datetime "created_at", null: false
270 + t.datetime "created_at"
271 t.float "running_time", limit: 24
271 t.float "running_time", limit: 24
272 t.string "exit_status", limit: 255
272 t.string "exit_status", limit: 255
273 t.integer "memory_usage", limit: 4
273 t.integer "memory_usage", limit: 4
274 end
274 end
275
275
276 add_index "test_requests", ["user_id", "problem_id"], name: "index_test_requests_on_user_id_and_problem_id", using: :btree
276 add_index "test_requests", ["user_id", "problem_id"], name: "index_test_requests_on_user_id_and_problem_id", using: :btree
277
277
278 create_table "testcases", force: :cascade do |t|
278 create_table "testcases", force: :cascade do |t|
279 t.integer "problem_id", limit: 4
279 t.integer "problem_id", limit: 4
280 t.integer "num", limit: 4
280 t.integer "num", limit: 4
281 t.integer "group", limit: 4
281 t.integer "group", limit: 4
282 t.integer "score", limit: 4
282 t.integer "score", limit: 4
283 t.text "input", limit: 4294967295
283 t.text "input", limit: 4294967295
284 t.text "sol", limit: 4294967295
284 t.text "sol", limit: 4294967295
285 t.datetime "created_at"
285 t.datetime "created_at"
286 t.datetime "updated_at"
286 t.datetime "updated_at"
287 end
287 end
288
288
289 add_index "testcases", ["problem_id"], name: "index_testcases_on_problem_id", using: :btree
289 add_index "testcases", ["problem_id"], name: "index_testcases_on_problem_id", using: :btree
290
290
291 create_table "user_contest_stats", force: :cascade do |t|
291 create_table "user_contest_stats", force: :cascade do |t|
292 t.integer "user_id", limit: 4
292 t.integer "user_id", limit: 4
293 t.datetime "started_at"
293 t.datetime "started_at"
294 - t.datetime "created_at", null: false
294 + t.datetime "created_at"
295 - t.datetime "updated_at", null: false
295 + t.datetime "updated_at"
296 t.boolean "forced_logout"
296 t.boolean "forced_logout"
297 end
297 end
298
298
299 create_table "users", force: :cascade do |t|
299 create_table "users", force: :cascade do |t|
300 t.string "login", limit: 50
300 t.string "login", limit: 50
301 t.string "full_name", limit: 255
301 t.string "full_name", limit: 255
302 t.string "hashed_password", limit: 255
302 t.string "hashed_password", limit: 255
303 t.string "salt", limit: 5
303 t.string "salt", limit: 5
304 t.string "alias", limit: 255
304 t.string "alias", limit: 255
305 t.string "email", limit: 255
305 t.string "email", limit: 255
306 t.integer "site_id", limit: 4
306 t.integer "site_id", limit: 4
307 t.integer "country_id", limit: 4
307 t.integer "country_id", limit: 4
308 t.boolean "activated", default: false
308 t.boolean "activated", default: false
309 t.datetime "created_at"
309 t.datetime "created_at"
310 t.datetime "updated_at"
310 t.datetime "updated_at"
311 + t.string "section", limit: 255
311 t.boolean "enabled", default: true
312 t.boolean "enabled", default: true
312 t.string "remark", limit: 255
313 t.string "remark", limit: 255
313 t.string "last_ip", limit: 255
314 t.string "last_ip", limit: 255
314 - t.string "section", limit: 255
315 end
315 end
316
316
317 add_index "users", ["login"], name: "index_users_on_login", unique: true, using: :btree
317 add_index "users", ["login"], name: "index_users_on_login", unique: true, using: :btree
318
318
319 add_foreign_key "problems_tags", "problems"
319 add_foreign_key "problems_tags", "problems"
320 add_foreign_key "problems_tags", "tags"
320 add_foreign_key "problems_tags", "tags"
321 end
321 end
You need to be logged in to leave comments. Login now