Description:
change find(:xxx) to correct syntax for rails 4
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r619:35d86016ce86 - - 26 files changed: 108 inserted, 147 deleted

@@ -1,51 +1,51
1 source 'https://rubygems.org'
1 source 'https://rubygems.org'
2
2
3 - gem 'rails', '~>4.0.0'
3 + gem 'rails', '~>4.1.0'
4 gem 'activerecord-session_store'
4 gem 'activerecord-session_store'
5
5
6 gem 'select2-rails'
6 gem 'select2-rails'
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 gem 'mysql2', '~> 0.3.0'
11 gem 'mysql2', '~> 0.3.0'
12
12
13 # Gems used only for assets and not required
13 # Gems used only for assets and not required
14 # in production environments by default.
14 # in production environments by default.
15 group :assets do
15 group :assets do
16 gem 'sass-rails'
16 gem 'sass-rails'
17 gem 'coffee-rails'
17 gem 'coffee-rails'
18
18
19 # See https://github.com/sstephenson/execjs#readme for more supported runtimes
19 # See https://github.com/sstephenson/execjs#readme for more supported runtimes
20 # gem 'therubyracer', :platforms => :ruby
20 # gem 'therubyracer', :platforms => :ruby
21
21
22 gem 'uglifier'
22 gem 'uglifier'
23 end
23 end
24
24
25 # gem 'prototype-rails'
25 # gem 'prototype-rails'
26
26
27 # To use ActiveModel has_secure_password
27 # To use ActiveModel has_secure_password
28 # gem 'bcrypt-ruby', '~> 3.0.0'
28 # gem 'bcrypt-ruby', '~> 3.0.0'
29
29
30 # To use Jbuilder templates for JSON
30 # To use Jbuilder templates for JSON
31 # gem 'jbuilder'
31 # gem 'jbuilder'
32
32
33 # Use unicorn as the app server
33 # Use unicorn as the app server
34 # gem 'unicorn'
34 # gem 'unicorn'
35
35
36 # Deploy with Capistrano
36 # Deploy with Capistrano
37 # gem 'capistrano'
37 # gem 'capistrano'
38
38
39 # To use debugger
39 # To use debugger
40 # gem 'debugger'
40 # gem 'debugger'
41 #
41 #
42
42
43 #in-place editor
43 #in-place editor
44 gem 'best_in_place', '~> 3.0.1'
44 gem 'best_in_place', '~> 3.0.1'
45
45
46 # jquery addition
46 # jquery addition
47 gem 'jquery-rails'
47 gem 'jquery-rails'
48 gem 'jquery-ui-sass-rails'
48 gem 'jquery-ui-sass-rails'
49 gem 'jquery-timepicker-addon-rails'
49 gem 'jquery-timepicker-addon-rails'
50 gem 'jquery-tablesorter'
50 gem 'jquery-tablesorter'
51 gem 'jquery-countdown-rails'
51 gem 'jquery-countdown-rails'
@@ -1,212 +1,218
1 GIT
1 GIT
2 remote: https://github.com/sikachu/verification.git
2 remote: https://github.com/sikachu/verification.git
3 revision: e6fe084ce16b7b5a4b1cdfca5374d125fd034a0f
3 revision: e6fe084ce16b7b5a4b1cdfca5374d125fd034a0f
4 specs:
4 specs:
5 verification (1.0.3)
5 verification (1.0.3)
6 actionpack (>= 3.0.0, < 5.0)
6 actionpack (>= 3.0.0, < 5.0)
7 activesupport (>= 3.0.0, < 5.0)
7 activesupport (>= 3.0.0, < 5.0)
8
8
9 GEM
9 GEM
10 remote: https://rubygems.org/
10 remote: https://rubygems.org/
11 specs:
11 specs:
12 ace-rails-ap (4.1.1)
12 ace-rails-ap (4.1.1)
13 - actionmailer (4.0.13)
13 + actionmailer (4.1.16)
14 - actionpack (= 4.0.13)
14 + actionpack (= 4.1.16)
15 + actionview (= 4.1.16)
15 mail (~> 2.5, >= 2.5.4)
16 mail (~> 2.5, >= 2.5.4)
16 - actionpack (4.0.13)
17 + actionpack (4.1.16)
17 - activesupport (= 4.0.13)
18 + actionview (= 4.1.16)
18 - builder (~> 3.1.0)
19 + activesupport (= 4.1.16)
19 - erubis (~> 2.7.0)
20 rack (~> 1.5.2)
20 rack (~> 1.5.2)
21 rack-test (~> 0.6.2)
21 rack-test (~> 0.6.2)
22 - activemodel (4.0.13)
22 + actionview (4.1.16)
23 - activesupport (= 4.0.13)
23 + activesupport (= 4.1.16)
24 - builder (~> 3.1.0)
24 + builder (~> 3.1)
25 - activerecord (4.0.13)
25 + erubis (~> 2.7.0)
26 - activemodel (= 4.0.13)
26 + activemodel (4.1.16)
27 - activerecord-deprecated_finders (~> 1.0.2)
27 + activesupport (= 4.1.16)
28 - activesupport (= 4.0.13)
28 + builder (~> 3.1)
29 - arel (~> 4.0.0)
29 + activerecord (4.1.16)
30 - activerecord-deprecated_finders (1.0.4)
30 + activemodel (= 4.1.16)
31 + activesupport (= 4.1.16)
32 + arel (~> 5.0.0)
31 activerecord-session_store (1.0.0)
33 activerecord-session_store (1.0.0)
32 actionpack (>= 4.0, < 5.1)
34 actionpack (>= 4.0, < 5.1)
33 activerecord (>= 4.0, < 5.1)
35 activerecord (>= 4.0, < 5.1)
34 multi_json (~> 1.11, >= 1.11.2)
36 multi_json (~> 1.11, >= 1.11.2)
35 rack (>= 1.5.2, < 3)
37 rack (>= 1.5.2, < 3)
36 railties (>= 4.0, < 5.1)
38 railties (>= 4.0, < 5.1)
37 - activesupport (4.0.13)
39 + activesupport (4.1.16)
38 i18n (~> 0.6, >= 0.6.9)
40 i18n (~> 0.6, >= 0.6.9)
39 - minitest (~> 4.2)
41 + json (~> 1.7, >= 1.7.7)
40 - multi_json (~> 1.3)
42 + minitest (~> 5.1)
41 thread_safe (~> 0.1)
43 thread_safe (~> 0.1)
42 - tzinfo (~> 0.3.37)
44 + tzinfo (~> 1.1)
43 - arel (4.0.2)
45 + arel (5.0.1.20140414130214)
44 - autoprefixer-rails (6.5.2)
46 + autoprefixer-rails (6.5.3.1)
45 execjs
47 execjs
46 best_in_place (3.0.3)
48 best_in_place (3.0.3)
47 actionpack (>= 3.2)
49 actionpack (>= 3.2)
48 railties (>= 3.2)
50 railties (>= 3.2)
49 bootstrap-sass (3.2.0.2)
51 bootstrap-sass (3.2.0.2)
50 sass (~> 3.2)
52 sass (~> 3.2)
51 bootstrap-switch-rails (3.3.3)
53 bootstrap-switch-rails (3.3.3)
52 bootstrap-toggle-rails (2.2.1.0)
54 bootstrap-toggle-rails (2.2.1.0)
53 - builder (3.1.4)
55 + builder (3.2.2)
54 coffee-rails (4.2.1)
56 coffee-rails (4.2.1)
55 coffee-script (>= 2.2.0)
57 coffee-script (>= 2.2.0)
56 railties (>= 4.0.0, < 5.2.x)
58 railties (>= 4.0.0, < 5.2.x)
57 coffee-script (2.4.1)
59 coffee-script (2.4.1)
58 coffee-script-source
60 coffee-script-source
59 execjs
61 execjs
60 - coffee-script-source (1.10.0)
62 + coffee-script-source (1.11.1)
61 concurrent-ruby (1.0.2)
63 concurrent-ruby (1.0.2)
62 diff-lcs (1.2.5)
64 diff-lcs (1.2.5)
63 dynamic_form (1.1.4)
65 dynamic_form (1.1.4)
64 erubis (2.7.0)
66 erubis (2.7.0)
65 execjs (2.7.0)
67 execjs (2.7.0)
66 haml (4.0.7)
68 haml (4.0.7)
67 tilt
69 tilt
68 haml-rails (0.9.0)
70 haml-rails (0.9.0)
69 actionpack (>= 4.0.1)
71 actionpack (>= 4.0.1)
70 activesupport (>= 4.0.1)
72 activesupport (>= 4.0.1)
71 haml (>= 4.0.6, < 5.0)
73 haml (>= 4.0.6, < 5.0)
72 html2haml (>= 1.0.1)
74 html2haml (>= 1.0.1)
73 railties (>= 4.0.1)
75 railties (>= 4.0.1)
74 html2haml (2.0.0)
76 html2haml (2.0.0)
75 erubis (~> 2.7.0)
77 erubis (~> 2.7.0)
76 haml (~> 4.0.0)
78 haml (~> 4.0.0)
77 nokogiri (~> 1.6.0)
79 nokogiri (~> 1.6.0)
78 ruby_parser (~> 3.5)
80 ruby_parser (~> 3.5)
79 i18n (0.7.0)
81 i18n (0.7.0)
80 in_place_editing (1.2.0)
82 in_place_editing (1.2.0)
81 jquery-countdown-rails (2.0.2)
83 jquery-countdown-rails (2.0.2)
82 jquery-rails (3.1.4)
84 jquery-rails (3.1.4)
83 railties (>= 3.0, < 5.0)
85 railties (>= 3.0, < 5.0)
84 thor (>= 0.14, < 2.0)
86 thor (>= 0.14, < 2.0)
85 - jquery-tablesorter (1.22.7)
87 + jquery-tablesorter (1.23.1)
86 railties (>= 3.2, < 6)
88 railties (>= 3.2, < 6)
87 jquery-timepicker-addon-rails (1.4.1)
89 jquery-timepicker-addon-rails (1.4.1)
88 railties (>= 3.1)
90 railties (>= 3.1)
89 jquery-ui-rails (4.0.3)
91 jquery-ui-rails (4.0.3)
90 jquery-rails
92 jquery-rails
91 railties (>= 3.1.0)
93 railties (>= 3.1.0)
92 jquery-ui-sass-rails (4.0.3.0)
94 jquery-ui-sass-rails (4.0.3.0)
93 jquery-rails
95 jquery-rails
94 jquery-ui-rails (= 4.0.3)
96 jquery-ui-rails (= 4.0.3)
95 railties (>= 3.1.0)
97 railties (>= 3.1.0)
98 + json (1.8.3)
96 mail (2.6.4)
99 mail (2.6.4)
97 mime-types (>= 1.16, < 4)
100 mime-types (>= 1.16, < 4)
98 mime-types (3.1)
101 mime-types (3.1)
99 mime-types-data (~> 3.2015)
102 mime-types-data (~> 3.2015)
100 mime-types-data (3.2016.0521)
103 mime-types-data (3.2016.0521)
101 mini_portile2 (2.1.0)
104 mini_portile2 (2.1.0)
102 - minitest (4.7.5)
105 + minitest (5.10.1)
103 momentjs-rails (2.15.1)
106 momentjs-rails (2.15.1)
104 railties (>= 3.1)
107 railties (>= 3.1)
105 multi_json (1.12.1)
108 multi_json (1.12.1)
106 mysql2 (0.3.21)
109 mysql2 (0.3.21)
107 nokogiri (1.6.8.1)
110 nokogiri (1.6.8.1)
108 mini_portile2 (~> 2.1.0)
111 mini_portile2 (~> 2.1.0)
109 - power_assert (0.3.1)
112 + power_assert (0.4.1)
110 rack (1.5.5)
113 rack (1.5.5)
111 rack-test (0.6.3)
114 rack-test (0.6.3)
112 rack (>= 1.0)
115 rack (>= 1.0)
113 - rails (4.0.13)
116 + rails (4.1.16)
114 - actionmailer (= 4.0.13)
117 + actionmailer (= 4.1.16)
115 - actionpack (= 4.0.13)
118 + actionpack (= 4.1.16)
116 - activerecord (= 4.0.13)
119 + actionview (= 4.1.16)
117 - activesupport (= 4.0.13)
120 + activemodel (= 4.1.16)
121 + activerecord (= 4.1.16)
122 + activesupport (= 4.1.16)
118 bundler (>= 1.3.0, < 2.0)
123 bundler (>= 1.3.0, < 2.0)
119 - railties (= 4.0.13)
124 + railties (= 4.1.16)
120 sprockets-rails (~> 2.0)
125 sprockets-rails (~> 2.0)
121 rails_bootstrap_sortable (2.0.1)
126 rails_bootstrap_sortable (2.0.1)
122 momentjs-rails (>= 2.8.3)
127 momentjs-rails (>= 2.8.3)
123 - railties (4.0.13)
128 + railties (4.1.16)
124 - actionpack (= 4.0.13)
129 + actionpack (= 4.1.16)
125 - activesupport (= 4.0.13)
130 + activesupport (= 4.1.16)
126 rake (>= 0.8.7)
131 rake (>= 0.8.7)
127 thor (>= 0.18.1, < 2.0)
132 thor (>= 0.18.1, < 2.0)
128 - rake (11.3.0)
133 + rake (12.0.0)
129 rdiscount (2.2.0.1)
134 rdiscount (2.2.0.1)
130 - rouge (2.0.6)
135 + rouge (2.0.7)
131 rspec-collection_matchers (1.1.2)
136 rspec-collection_matchers (1.1.2)
132 rspec-expectations (>= 2.99.0.beta1)
137 rspec-expectations (>= 2.99.0.beta1)
133 rspec-core (2.99.2)
138 rspec-core (2.99.2)
134 rspec-expectations (2.99.2)
139 rspec-expectations (2.99.2)
135 diff-lcs (>= 1.1.3, < 2.0)
140 diff-lcs (>= 1.1.3, < 2.0)
136 rspec-mocks (2.99.4)
141 rspec-mocks (2.99.4)
137 rspec-rails (2.99.0)
142 rspec-rails (2.99.0)
138 actionpack (>= 3.0)
143 actionpack (>= 3.0)
139 activemodel (>= 3.0)
144 activemodel (>= 3.0)
140 activesupport (>= 3.0)
145 activesupport (>= 3.0)
141 railties (>= 3.0)
146 railties (>= 3.0)
142 rspec-collection_matchers
147 rspec-collection_matchers
143 rspec-core (~> 2.99.0)
148 rspec-core (~> 2.99.0)
144 rspec-expectations (~> 2.99.0)
149 rspec-expectations (~> 2.99.0)
145 rspec-mocks (~> 2.99.0)
150 rspec-mocks (~> 2.99.0)
146 ruby_parser (3.8.3)
151 ruby_parser (3.8.3)
147 sexp_processor (~> 4.1)
152 sexp_processor (~> 4.1)
148 sass (3.4.22)
153 sass (3.4.22)
149 sass-rails (5.0.6)
154 sass-rails (5.0.6)
150 railties (>= 4.0.0, < 6)
155 railties (>= 4.0.0, < 6)
151 sass (~> 3.1)
156 sass (~> 3.1)
152 sprockets (>= 2.8, < 4.0)
157 sprockets (>= 2.8, < 4.0)
153 sprockets-rails (>= 2.0, < 4.0)
158 sprockets-rails (>= 2.0, < 4.0)
154 tilt (>= 1.1, < 3)
159 tilt (>= 1.1, < 3)
155 select2-rails (4.0.3)
160 select2-rails (4.0.3)
156 thor (~> 0.14)
161 thor (~> 0.14)
157 sexp_processor (4.7.0)
162 sexp_processor (4.7.0)
158 sprockets (3.7.0)
163 sprockets (3.7.0)
159 concurrent-ruby (~> 1.0)
164 concurrent-ruby (~> 1.0)
160 rack (> 1, < 3)
165 rack (> 1, < 3)
161 sprockets-rails (2.3.3)
166 sprockets-rails (2.3.3)
162 actionpack (>= 3.0)
167 actionpack (>= 3.0)
163 activesupport (>= 3.0)
168 activesupport (>= 3.0)
164 sprockets (>= 2.8, < 4.0)
169 sprockets (>= 2.8, < 4.0)
165 - test-unit (3.2.2)
170 + test-unit (3.2.3)
166 power_assert
171 power_assert
167 - thor (0.19.1)
172 + thor (0.19.4)
168 thread_safe (0.3.5)
173 thread_safe (0.3.5)
169 tilt (2.0.5)
174 tilt (2.0.5)
170 - tzinfo (0.3.52)
175 + tzinfo (1.2.2)
171 - uglifier (3.0.3)
176 + thread_safe (~> 0.1)
177 + uglifier (3.0.4)
172 execjs (>= 0.3.0, < 3)
178 execjs (>= 0.3.0, < 3)
173 will_paginate (3.0.12)
179 will_paginate (3.0.12)
174
180
175 PLATFORMS
181 PLATFORMS
176 ruby
182 ruby
177
183
178 DEPENDENCIES
184 DEPENDENCIES
179 ace-rails-ap
185 ace-rails-ap
180 activerecord-session_store
186 activerecord-session_store
181 autoprefixer-rails
187 autoprefixer-rails
182 best_in_place (~> 3.0.1)
188 best_in_place (~> 3.0.1)
183 bootstrap-sass (~> 3.2.0)
189 bootstrap-sass (~> 3.2.0)
184 bootstrap-switch-rails
190 bootstrap-switch-rails
185 bootstrap-toggle-rails
191 bootstrap-toggle-rails
186 coffee-rails
192 coffee-rails
187 dynamic_form
193 dynamic_form
188 haml
194 haml
189 haml-rails
195 haml-rails
190 in_place_editing
196 in_place_editing
191 jquery-countdown-rails
197 jquery-countdown-rails
192 jquery-rails
198 jquery-rails
193 jquery-tablesorter
199 jquery-tablesorter
194 jquery-timepicker-addon-rails
200 jquery-timepicker-addon-rails
195 jquery-ui-sass-rails
201 jquery-ui-sass-rails
196 mail
202 mail
197 momentjs-rails
203 momentjs-rails
198 mysql2 (~> 0.3.0)
204 mysql2 (~> 0.3.0)
199 - rails (~> 4.0.0)
205 + rails (~> 4.1.0)
200 rails_bootstrap_sortable
206 rails_bootstrap_sortable
201 rdiscount
207 rdiscount
202 rouge
208 rouge
203 rspec-rails (~> 2.99.0)
209 rspec-rails (~> 2.99.0)
204 sass-rails
210 sass-rails
205 select2-rails
211 select2-rails
206 test-unit
212 test-unit
207 uglifier
213 uglifier
208 verification!
214 verification!
209 will_paginate (~> 3.0.7)
215 will_paginate (~> 3.0.7)
210
216
211 BUNDLED WITH
217 BUNDLED WITH
212 1.13.6
218 1.13.6
@@ -1,59 +1,58
1 class AnnouncementsController < ApplicationController
1 class AnnouncementsController < ApplicationController
2
2
3 before_filter :admin_authorization
3 before_filter :admin_authorization
4
4
5 in_place_edit_for :announcement, :published
5 in_place_edit_for :announcement, :published
6
6
7 # GET /announcements
7 # GET /announcements
8 # GET /announcements.xml
8 # GET /announcements.xml
9 def index
9 def index
10 - @announcements = Announcement.find(:all,
10 + @announcements = Announcement.order(created_at: :desc)
11 - :order => "created_at DESC")
12
11
13 respond_to do |format|
12 respond_to do |format|
14 format.html # index.html.erb
13 format.html # index.html.erb
15 format.xml { render :xml => @announcements }
14 format.xml { render :xml => @announcements }
16 end
15 end
17 end
16 end
18
17
19 # GET /announcements/1
18 # GET /announcements/1
20 # GET /announcements/1.xml
19 # GET /announcements/1.xml
21 def show
20 def show
22 @announcement = Announcement.find(params[:id])
21 @announcement = Announcement.find(params[:id])
23
22
24 respond_to do |format|
23 respond_to do |format|
25 format.html # show.html.erb
24 format.html # show.html.erb
26 format.xml { render :xml => @announcement }
25 format.xml { render :xml => @announcement }
27 end
26 end
28 end
27 end
29
28
30 # GET /announcements/new
29 # GET /announcements/new
31 # GET /announcements/new.xml
30 # GET /announcements/new.xml
32 def new
31 def new
33 @announcement = Announcement.new
32 @announcement = Announcement.new
34
33
35 respond_to do |format|
34 respond_to do |format|
36 format.html # new.html.erb
35 format.html # new.html.erb
37 format.xml { render :xml => @announcement }
36 format.xml { render :xml => @announcement }
38 end
37 end
39 end
38 end
40
39
41 # GET /announcements/1/edit
40 # GET /announcements/1/edit
42 def edit
41 def edit
43 @announcement = Announcement.find(params[:id])
42 @announcement = Announcement.find(params[:id])
44 end
43 end
45
44
46 # POST /announcements
45 # POST /announcements
47 # POST /announcements.xml
46 # POST /announcements.xml
48 def create
47 def create
49 @announcement = Announcement.new(params[:announcement])
48 @announcement = Announcement.new(params[:announcement])
50
49
51 respond_to do |format|
50 respond_to do |format|
52 if @announcement.save
51 if @announcement.save
53 flash[:notice] = 'Announcement was successfully created.'
52 flash[:notice] = 'Announcement was successfully created.'
54 format.html { redirect_to(@announcement) }
53 format.html { redirect_to(@announcement) }
55 format.xml { render :xml => @announcement, :status => :created, :location => @announcement }
54 format.xml { render :xml => @announcement, :status => :created, :location => @announcement }
56 else
55 else
57 format.html { render :action => "new" }
56 format.html { render :action => "new" }
58 format.xml { render :xml => @announcement.errors, :status => :unprocessable_entity }
57 format.xml { render :xml => @announcement.errors, :status => :unprocessable_entity }
59 end
58 end
@@ -1,71 +1,71
1 class ApplicationController < ActionController::Base
1 class ApplicationController < ActionController::Base
2 protect_from_forgery
2 protect_from_forgery
3
3
4 before_filter :current_user
4 before_filter :current_user
5
5
6 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
6 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
7 MULTIPLE_IP_LOGIN_CONF_KEY = 'right.multiple_ip_login'
7 MULTIPLE_IP_LOGIN_CONF_KEY = 'right.multiple_ip_login'
8
8
9 #report and redirect for unauthorized activities
9 #report and redirect for unauthorized activities
10 def unauthorized_redirect
10 def unauthorized_redirect
11 flash[:notice] = 'You are not authorized to view the page you requested'
11 flash[:notice] = 'You are not authorized to view the page you requested'
12 redirect_to :controller => 'main', :action => 'login'
12 redirect_to :controller => 'main', :action => 'login'
13 end
13 end
14
14
15 # Returns the current logged-in user (if any).
15 # Returns the current logged-in user (if any).
16 def current_user
16 def current_user
17 return nil unless session[:user_id]
17 return nil unless session[:user_id]
18 @current_user ||= User.find(session[:user_id])
18 @current_user ||= User.find(session[:user_id])
19 end
19 end
20
20
21 def admin_authorization
21 def admin_authorization
22 return false unless authenticate
22 return false unless authenticate
23 - user = User.find(session[:user_id], :include => ['roles'])
23 + user = User.includes(:roles).find(session[:user_id])
24 unless user.admin?
24 unless user.admin?
25 unauthorized_redirect
25 unauthorized_redirect
26 return false
26 return false
27 end
27 end
28 return true
28 return true
29 end
29 end
30
30
31 def authorization_by_roles(allowed_roles)
31 def authorization_by_roles(allowed_roles)
32 return false unless authenticate
32 return false unless authenticate
33 user = User.find(session[:user_id])
33 user = User.find(session[:user_id])
34 unless user.roles.detect { |role| allowed_roles.member?(role.name) }
34 unless user.roles.detect { |role| allowed_roles.member?(role.name) }
35 unauthorized_redirect
35 unauthorized_redirect
36 return false
36 return false
37 end
37 end
38 end
38 end
39
39
40 protected
40 protected
41
41
42 def authenticate
42 def authenticate
43 unless session[:user_id]
43 unless session[:user_id]
44 flash[:notice] = 'You need to login'
44 flash[:notice] = 'You need to login'
45 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
45 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
46 flash[:notice] = 'You need to login but you cannot log in at this time'
46 flash[:notice] = 'You need to login but you cannot log in at this time'
47 end
47 end
48 redirect_to :controller => 'main', :action => 'login'
48 redirect_to :controller => 'main', :action => 'login'
49 return false
49 return false
50 end
50 end
51
51
52 # check if run in single user mode
52 # check if run in single user mode
53 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
53 if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
54 user = User.find_by_id(session[:user_id])
54 user = User.find_by_id(session[:user_id])
55 if user==nil or (not user.admin?)
55 if user==nil or (not user.admin?)
56 flash[:notice] = 'You cannot log in at this time'
56 flash[:notice] = 'You cannot log in at this time'
57 redirect_to :controller => 'main', :action => 'login'
57 redirect_to :controller => 'main', :action => 'login'
58 return false
58 return false
59 end
59 end
60 unless user.enabled?
60 unless user.enabled?
61 flash[:notice] = 'Your account is disabled'
61 flash[:notice] = 'Your account is disabled'
62 redirect_to :controller => 'main', :action => 'login'
62 redirect_to :controller => 'main', :action => 'login'
63 return false
63 return false
64 end
64 end
65 return true
65 return true
66 end
66 end
67
67
68 if GraderConfiguration.multicontests?
68 if GraderConfiguration.multicontests?
69 user = User.find(session[:user_id])
69 user = User.find(session[:user_id])
70 return true if user.admin?
70 return true if user.admin?
71 begin
71 begin
@@ -1,35 +1,34
1 class ConfigurationsController < ApplicationController
1 class ConfigurationsController < ApplicationController
2
2
3 before_filter :authenticate
3 before_filter :authenticate
4 before_filter { |controller| controller.authorization_by_roles(['admin'])}
4 before_filter { |controller| controller.authorization_by_roles(['admin'])}
5
5
6
6
7 def index
7 def index
8 - @configurations = GraderConfiguration.find(:all,
8 + @configurations = GraderConfiguration.order(:key)
9 - :order => '`key`')
10 @group = GraderConfiguration.pluck("grader_configurations.key").map{ |x| x[0...(x.index('.'))] }.uniq.sort
9 @group = GraderConfiguration.pluck("grader_configurations.key").map{ |x| x[0...(x.index('.'))] }.uniq.sort
11 end
10 end
12
11
13 def reload
12 def reload
14 GraderConfiguration.reload
13 GraderConfiguration.reload
15 redirect_to :action => 'index'
14 redirect_to :action => 'index'
16 end
15 end
17
16
18 def update
17 def update
19 @config = GraderConfiguration.find(params[:id])
18 @config = GraderConfiguration.find(params[:id])
20 User.clear_last_login if @config.key == GraderConfiguration::MULTIPLE_IP_LOGIN_KEY and @config.value == 'true' and params[:grader_configuration][:value] == 'false'
19 User.clear_last_login if @config.key == GraderConfiguration::MULTIPLE_IP_LOGIN_KEY and @config.value == 'true' and params[:grader_configuration][:value] == 'false'
21 respond_to do |format|
20 respond_to do |format|
22 if @config.update_attributes(configuration_params)
21 if @config.update_attributes(configuration_params)
23 format.json { head :ok }
22 format.json { head :ok }
24 else
23 else
25 format.json { respond_with_bip(@config) }
24 format.json { respond_with_bip(@config) }
26 end
25 end
27 end
26 end
28 end
27 end
29
28
30 private
29 private
31 def configuration_params
30 def configuration_params
32 params.require(:grader_configuration).permit(:key,:value_type,:value,:description)
31 params.require(:grader_configuration).permit(:key,:value_type,:value,:description)
33 end
32 end
34
33
35 end
34 end
@@ -1,50 +1,50
1 class ContestManagementController < ApplicationController
1 class ContestManagementController < ApplicationController
2
2
3 before_filter :admin_authorization
3 before_filter :admin_authorization
4
4
5 def index
5 def index
6 @num_contests = Contest.count()
6 @num_contests = Contest.count()
7 end
7 end
8
8
9 def user_stat
9 def user_stat
10 if not GraderConfiguration.indv_contest_mode?
10 if not GraderConfiguration.indv_contest_mode?
11 redirect_to :action => 'index' and return
11 redirect_to :action => 'index' and return
12 end
12 end
13
13
14 - @users = User.find(:all)
14 + @users = User.all
15 @start_times = {}
15 @start_times = {}
16 - UserContestStat.find(:all).each do |stat|
16 + UserContestStat.all.each do |stat|
17 @start_times[stat.user_id] = stat.started_at
17 @start_times[stat.user_id] = stat.started_at
18 end
18 end
19 end
19 end
20
20
21 def clear_stat
21 def clear_stat
22 user = User.find(params[:id])
22 user = User.find(params[:id])
23 if user.contest_stat!=nil
23 if user.contest_stat!=nil
24 user.contest_stat.destroy
24 user.contest_stat.destroy
25 end
25 end
26 redirect_to :action => 'user_stat'
26 redirect_to :action => 'user_stat'
27 end
27 end
28
28
29 def clear_all_stat
29 def clear_all_stat
30 if not GraderConfiguration.indv_contest_mode?
30 if not GraderConfiguration.indv_contest_mode?
31 redirect_to :action => 'index' and return
31 redirect_to :action => 'index' and return
32 end
32 end
33
33
34 UserContestStat.delete_all()
34 UserContestStat.delete_all()
35 flash[:notice] = 'All start time statistic cleared.'
35 flash[:notice] = 'All start time statistic cleared.'
36 redirect_to :action => 'index'
36 redirect_to :action => 'index'
37 end
37 end
38
38
39 def change_contest_mode
39 def change_contest_mode
40 if ['standard', 'contest', 'indv-contest', 'analysis'].include? params[:id]
40 if ['standard', 'contest', 'indv-contest', 'analysis'].include? params[:id]
41 config = GraderConfiguration.find_by_key('system.mode')
41 config = GraderConfiguration.find_by_key('system.mode')
42 config.value = params[:id]
42 config.value = params[:id]
43 config.save
43 config.save
44 else
44 else
45 flash[:notice] = 'Wrong contest mode value'
45 flash[:notice] = 'Wrong contest mode value'
46 end
46 end
47 redirect_to :action => 'index'
47 redirect_to :action => 'index'
48 end
48 end
49
49
50 end
50 end
@@ -1,108 +1,106
1 class GradersController < ApplicationController
1 class GradersController < ApplicationController
2
2
3 before_filter :admin_authorization, except: [ :submission ]
3 before_filter :admin_authorization, except: [ :submission ]
4 before_filter(only: [:submission]) {
4 before_filter(only: [:submission]) {
5 #check if authenticated
5 #check if authenticated
6 return false unless authenticate
6 return false unless authenticate
7
7
8 #admin always has privileged
8 #admin always has privileged
9 if @current_user.admin?
9 if @current_user.admin?
10 return true
10 return true
11 end
11 end
12
12
13 if GraderConfiguration["right.user_view_submission"] and Submission.find(params[:id]).problem.available?
13 if GraderConfiguration["right.user_view_submission"] and Submission.find(params[:id]).problem.available?
14 return true
14 return true
15 else
15 else
16 unauthorized_redirect
16 unauthorized_redirect
17 return false
17 return false
18 end
18 end
19 }
19 }
20
20
21 verify :method => :post, :only => ['clear_all',
21 verify :method => :post, :only => ['clear_all',
22 'start_exam',
22 'start_exam',
23 'start_grading',
23 'start_grading',
24 'stop_all',
24 'stop_all',
25 'clear_terminated'],
25 'clear_terminated'],
26 :redirect_to => {:action => 'index'}
26 :redirect_to => {:action => 'index'}
27
27
28 def index
28 def index
29 redirect_to :action => 'list'
29 redirect_to :action => 'list'
30 end
30 end
31
31
32 def list
32 def list
33 @grader_processes = GraderProcess.find_running_graders
33 @grader_processes = GraderProcess.find_running_graders
34 @stalled_processes = GraderProcess.find_stalled_process
34 @stalled_processes = GraderProcess.find_stalled_process
35
35
36 @terminated_processes = GraderProcess.find_terminated_graders
36 @terminated_processes = GraderProcess.find_terminated_graders
37
37
38 - @last_task = Task.find(:first,
38 + @last_task = Task.last
39 - :order => 'created_at DESC')
39 + @last_test_request = TestRequest.last
40 - @last_test_request = TestRequest.find(:first,
41 - :order => 'created_at DESC')
42 @submission = Submission.order("id desc").limit(20)
40 @submission = Submission.order("id desc").limit(20)
43 @backlog_submission = Submission.where('graded_at is null')
41 @backlog_submission = Submission.where('graded_at is null')
44 end
42 end
45
43
46 def clear
44 def clear
47 grader_proc = GraderProcess.find(params[:id])
45 grader_proc = GraderProcess.find(params[:id])
48 grader_proc.destroy if grader_proc!=nil
46 grader_proc.destroy if grader_proc!=nil
49 redirect_to :action => 'list'
47 redirect_to :action => 'list'
50 end
48 end
51
49
52 def clear_terminated
50 def clear_terminated
53 GraderProcess.find_terminated_graders.each do |p|
51 GraderProcess.find_terminated_graders.each do |p|
54 p.destroy
52 p.destroy
55 end
53 end
56 redirect_to :action => 'list'
54 redirect_to :action => 'list'
57 end
55 end
58
56
59 def clear_all
57 def clear_all
60 - GraderProcess.find(:all).each do |p|
58 + GraderProcess.all.each do |p|
61 p.destroy
59 p.destroy
62 end
60 end
63 redirect_to :action => 'list'
61 redirect_to :action => 'list'
64 end
62 end
65
63
66 def view
64 def view
67 if params[:type]=='Task'
65 if params[:type]=='Task'
68 redirect_to :action => 'task', :id => params[:id]
66 redirect_to :action => 'task', :id => params[:id]
69 else
67 else
70 redirect_to :action => 'test_request', :id => params[:id]
68 redirect_to :action => 'test_request', :id => params[:id]
71 end
69 end
72 end
70 end
73
71
74 def test_request
72 def test_request
75 @test_request = TestRequest.find(params[:id])
73 @test_request = TestRequest.find(params[:id])
76 end
74 end
77
75
78 def task
76 def task
79 @task = Task.find(params[:id])
77 @task = Task.find(params[:id])
80 end
78 end
81
79
82 def submission
80 def submission
83 @submission = Submission.find(params[:id])
81 @submission = Submission.find(params[:id])
84 formatter = Rouge::Formatters::HTML.new(css_class: 'highlight', line_numbers: true )
82 formatter = Rouge::Formatters::HTML.new(css_class: 'highlight', line_numbers: true )
85 lexer = case @submission.language.name
83 lexer = case @submission.language.name
86 when "c" then Rouge::Lexers::C.new
84 when "c" then Rouge::Lexers::C.new
87 when "cpp" then Rouge::Lexers::Cpp.new
85 when "cpp" then Rouge::Lexers::Cpp.new
88 when "pas" then Rouge::Lexers::Pas.new
86 when "pas" then Rouge::Lexers::Pas.new
89 when "ruby" then Rouge::Lexers::Ruby.new
87 when "ruby" then Rouge::Lexers::Ruby.new
90 when "python" then Rouge::Lexers::Python.new
88 when "python" then Rouge::Lexers::Python.new
91 when "java" then Rouge::Lexers::Java.new
89 when "java" then Rouge::Lexers::Java.new
92 when "php" then Rouge::Lexers::PHP.new
90 when "php" then Rouge::Lexers::PHP.new
93 end
91 end
94 @formatted_code = formatter.format(lexer.lex(@submission.source))
92 @formatted_code = formatter.format(lexer.lex(@submission.source))
95 @css_style = Rouge::Themes::ThankfulEyes.render(scope: '.highlight')
93 @css_style = Rouge::Themes::ThankfulEyes.render(scope: '.highlight')
96
94
97 user = User.find(session[:user_id])
95 user = User.find(session[:user_id])
98 SubmissionViewLog.create(user_id: session[:user_id],submission_id: @submission.id) unless user.admin?
96 SubmissionViewLog.create(user_id: session[:user_id],submission_id: @submission.id) unless user.admin?
99
97
100 end
98 end
101
99
102 # various grader controls
100 # various grader controls
103
101
104 def stop
102 def stop
105 grader_proc = GraderProcess.find(params[:id])
103 grader_proc = GraderProcess.find(params[:id])
106 GraderScript.stop_grader(grader_proc.pid)
104 GraderScript.stop_grader(grader_proc.pid)
107 flash[:notice] = 'Grader stopped. It may not disappear now, but it should disappear shortly.'
105 flash[:notice] = 'Grader stopped. It may not disappear now, but it should disappear shortly.'
108 redirect_to :action => 'list'
106 redirect_to :action => 'list'
@@ -1,96 +1,96
1 class MainController < ApplicationController
1 class MainController < ApplicationController
2
2
3 before_filter :authenticate, :except => [:index, :login]
3 before_filter :authenticate, :except => [:index, :login]
4 before_filter :check_viewability, :except => [:index, :login]
4 before_filter :check_viewability, :except => [:index, :login]
5
5
6 append_before_filter :confirm_and_update_start_time,
6 append_before_filter :confirm_and_update_start_time,
7 :except => [:index,
7 :except => [:index,
8 :login,
8 :login,
9 :confirm_contest_start]
9 :confirm_contest_start]
10
10
11 # to prevent log in box to be shown when user logged out of the
11 # to prevent log in box to be shown when user logged out of the
12 # system only in some tab
12 # system only in some tab
13 prepend_before_filter :reject_announcement_refresh_when_logged_out,
13 prepend_before_filter :reject_announcement_refresh_when_logged_out,
14 :only => [:announcements]
14 :only => [:announcements]
15
15
16 before_filter :authenticate_by_ip_address, :only => [:list]
16 before_filter :authenticate_by_ip_address, :only => [:list]
17
17
18 # COMMENTED OUT: filter in each action instead
18 # COMMENTED OUT: filter in each action instead
19 # before_filter :verify_time_limit, :only => [:submit]
19 # before_filter :verify_time_limit, :only => [:submit]
20
20
21 verify :method => :post, :only => [:submit],
21 verify :method => :post, :only => [:submit],
22 :redirect_to => { :action => :index }
22 :redirect_to => { :action => :index }
23
23
24 # COMMENT OUT: only need when having high load
24 # COMMENT OUT: only need when having high load
25 # caches_action :index, :login
25 # caches_action :index, :login
26
26
27 # NOTE: This method is not actually needed, 'config/routes.rb' has
27 # NOTE: This method is not actually needed, 'config/routes.rb' has
28 # assigned action login as a default action.
28 # assigned action login as a default action.
29 def index
29 def index
30 redirect_to :action => 'login'
30 redirect_to :action => 'login'
31 end
31 end
32
32
33 def login
33 def login
34 saved_notice = flash[:notice]
34 saved_notice = flash[:notice]
35 reset_session
35 reset_session
36 flash.now[:notice] = saved_notice
36 flash.now[:notice] = saved_notice
37
37
38 # EXPERIMENT:
38 # EXPERIMENT:
39 # Hide login if in single user mode and the url does not
39 # Hide login if in single user mode and the url does not
40 # explicitly specify /login
40 # explicitly specify /login
41 #
41 #
42 # logger.info "PATH: #{request.path}"
42 # logger.info "PATH: #{request.path}"
43 # if GraderConfiguration['system.single_user_mode'] and
43 # if GraderConfiguration['system.single_user_mode'] and
44 # request.path!='/main/login'
44 # request.path!='/main/login'
45 # @hidelogin = true
45 # @hidelogin = true
46 # end
46 # end
47
47
48 - @announcements = Announcement.find_for_frontpage
48 + @announcements = Announcement.frontpage
49 render :action => 'login', :layout => 'empty'
49 render :action => 'login', :layout => 'empty'
50 end
50 end
51
51
52 def list
52 def list
53 prepare_list_information
53 prepare_list_information
54 end
54 end
55
55
56 def help
56 def help
57 @user = User.find(session[:user_id])
57 @user = User.find(session[:user_id])
58 end
58 end
59
59
60 def submit
60 def submit
61 user = User.find(session[:user_id])
61 user = User.find(session[:user_id])
62
62
63 @submission = Submission.new
63 @submission = Submission.new
64 @submission.problem_id = params[:submission][:problem_id]
64 @submission.problem_id = params[:submission][:problem_id]
65 @submission.user = user
65 @submission.user = user
66 @submission.language_id = 0
66 @submission.language_id = 0
67 if (params['file']) and (params['file']!='')
67 if (params['file']) and (params['file']!='')
68 @submission.source = File.open(params['file'].path,'r:UTF-8',&:read)
68 @submission.source = File.open(params['file'].path,'r:UTF-8',&:read)
69 @submission.source.encode!('UTF-8','UTF-8',invalid: :replace, replace: '')
69 @submission.source.encode!('UTF-8','UTF-8',invalid: :replace, replace: '')
70 @submission.source_filename = params['file'].original_filename
70 @submission.source_filename = params['file'].original_filename
71 end
71 end
72
72
73 if (params[:editor_text])
73 if (params[:editor_text])
74 language = Language.find_by_id(params[:language_id])
74 language = Language.find_by_id(params[:language_id])
75 @submission.source = params[:editor_text]
75 @submission.source = params[:editor_text]
76 @submission.source_filename = "live_edit.#{language.ext}"
76 @submission.source_filename = "live_edit.#{language.ext}"
77 @submission.language = language
77 @submission.language = language
78 end
78 end
79
79
80 @submission.submitted_at = Time.new.gmtime
80 @submission.submitted_at = Time.new.gmtime
81 @submission.ip_address = request.remote_ip
81 @submission.ip_address = request.remote_ip
82
82
83 if GraderConfiguration.time_limit_mode? and user.contest_finished?
83 if GraderConfiguration.time_limit_mode? and user.contest_finished?
84 @submission.errors.add(:base,"The contest is over.")
84 @submission.errors.add(:base,"The contest is over.")
85 prepare_list_information
85 prepare_list_information
86 render :action => 'list' and return
86 render :action => 'list' and return
87 end
87 end
88
88
89 if @submission.valid?
89 if @submission.valid?
90 if @submission.save == false
90 if @submission.save == false
91 flash[:notice] = 'Error saving your submission'
91 flash[:notice] = 'Error saving your submission'
92 elsif Task.create(:submission_id => @submission.id,
92 elsif Task.create(:submission_id => @submission.id,
93 :status => Task::STATUS_INQUEUE) == false
93 :status => Task::STATUS_INQUEUE) == false
94 flash[:notice] = 'Error adding your submission to task queue'
94 flash[:notice] = 'Error adding your submission to task queue'
95 end
95 end
96 else
96 else
@@ -172,99 +172,99
172 if !FileTest.exists?(out_filename)
172 if !FileTest.exists?(out_filename)
173 flash[:notice] = 'Output not found.'
173 flash[:notice] = 'Output not found.'
174 redirect_to :action => 'list' and return
174 redirect_to :action => 'list' and return
175 end
175 end
176
176
177 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
177 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
178 response.headers['Content-Type'] = "application/force-download"
178 response.headers['Content-Type'] = "application/force-download"
179 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
179 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
180 response.headers["X-Sendfile"] = out_filename
180 response.headers["X-Sendfile"] = out_filename
181 response.headers['Content-length'] = File.size(out_filename)
181 response.headers['Content-length'] = File.size(out_filename)
182 render :nothing => true
182 render :nothing => true
183 else
183 else
184 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
184 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
185 end
185 end
186 end
186 end
187
187
188 def error
188 def error
189 @user = User.find(session[:user_id])
189 @user = User.find(session[:user_id])
190 end
190 end
191
191
192 # announcement refreshing and hiding methods
192 # announcement refreshing and hiding methods
193
193
194 def announcements
194 def announcements
195 if params.has_key? 'recent'
195 if params.has_key? 'recent'
196 prepare_announcements(params[:recent])
196 prepare_announcements(params[:recent])
197 else
197 else
198 prepare_announcements
198 prepare_announcements
199 end
199 end
200 render(:partial => 'announcement',
200 render(:partial => 'announcement',
201 :collection => @announcements,
201 :collection => @announcements,
202 :locals => {:announcement_effect => true})
202 :locals => {:announcement_effect => true})
203 end
203 end
204
204
205 def confirm_contest_start
205 def confirm_contest_start
206 user = User.find(session[:user_id])
206 user = User.find(session[:user_id])
207 if request.method == 'POST'
207 if request.method == 'POST'
208 user.update_start_time
208 user.update_start_time
209 redirect_to :action => 'list'
209 redirect_to :action => 'list'
210 else
210 else
211 @contests = user.contests
211 @contests = user.contests
212 @user = user
212 @user = user
213 end
213 end
214 end
214 end
215
215
216 protected
216 protected
217
217
218 def prepare_announcements(recent=nil)
218 def prepare_announcements(recent=nil)
219 if GraderConfiguration.show_tasks_to?(@user)
219 if GraderConfiguration.show_tasks_to?(@user)
220 - @announcements = Announcement.find_published(true)
220 + @announcements = Announcement.published(true)
221 else
221 else
222 - @announcements = Announcement.find_published
222 + @announcements = Announcement.published
223 end
223 end
224 if recent!=nil
224 if recent!=nil
225 recent_id = recent.to_i
225 recent_id = recent.to_i
226 @announcements = @announcements.find_all { |a| a.id > recent_id }
226 @announcements = @announcements.find_all { |a| a.id > recent_id }
227 end
227 end
228 end
228 end
229
229
230 def prepare_list_information
230 def prepare_list_information
231 @user = User.find(session[:user_id])
231 @user = User.find(session[:user_id])
232 if not GraderConfiguration.multicontests?
232 if not GraderConfiguration.multicontests?
233 @problems = @user.available_problems
233 @problems = @user.available_problems
234 else
234 else
235 @contest_problems = @user.available_problems_group_by_contests
235 @contest_problems = @user.available_problems_group_by_contests
236 @problems = @user.available_problems
236 @problems = @user.available_problems
237 end
237 end
238 @prob_submissions = {}
238 @prob_submissions = {}
239 @problems.each do |p|
239 @problems.each do |p|
240 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
240 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
241 if sub!=nil
241 if sub!=nil
242 @prob_submissions[p.id] = { :count => sub.number, :submission => sub }
242 @prob_submissions[p.id] = { :count => sub.number, :submission => sub }
243 else
243 else
244 @prob_submissions[p.id] = { :count => 0, :submission => nil }
244 @prob_submissions[p.id] = { :count => 0, :submission => nil }
245 end
245 end
246 end
246 end
247 prepare_announcements
247 prepare_announcements
248 end
248 end
249
249
250 def check_viewability
250 def check_viewability
251 @user = User.find(session[:user_id])
251 @user = User.find(session[:user_id])
252 if (!GraderConfiguration.show_tasks_to?(@user)) and
252 if (!GraderConfiguration.show_tasks_to?(@user)) and
253 ((action_name=='submission') or (action_name=='submit'))
253 ((action_name=='submission') or (action_name=='submit'))
254 redirect_to :action => 'list' and return
254 redirect_to :action => 'list' and return
255 end
255 end
256 end
256 end
257
257
258 def prepare_grading_result(submission)
258 def prepare_grading_result(submission)
259 if GraderConfiguration.task_grading_info.has_key? submission.problem.name
259 if GraderConfiguration.task_grading_info.has_key? submission.problem.name
260 grading_info = GraderConfiguration.task_grading_info[submission.problem.name]
260 grading_info = GraderConfiguration.task_grading_info[submission.problem.name]
261 else
261 else
262 # guess task info from problem.full_score
262 # guess task info from problem.full_score
263 cases = submission.problem.full_score / 10
263 cases = submission.problem.full_score / 10
264 grading_info = {
264 grading_info = {
265 'testruns' => cases,
265 'testruns' => cases,
266 'testcases' => cases
266 'testcases' => cases
267 }
267 }
268 end
268 end
269 @test_runs = []
269 @test_runs = []
270 if grading_info['testruns'].is_a? Integer
270 if grading_info['testruns'].is_a? Integer
@@ -1,58 +1,58
1 class ProblemsController < ApplicationController
1 class ProblemsController < ApplicationController
2
2
3 before_filter :authenticate, :authorization
3 before_filter :authenticate, :authorization
4
4
5 in_place_edit_for :problem, :name
5 in_place_edit_for :problem, :name
6 in_place_edit_for :problem, :full_name
6 in_place_edit_for :problem, :full_name
7 in_place_edit_for :problem, :full_score
7 in_place_edit_for :problem, :full_score
8
8
9 def index
9 def index
10 - @problems = Problem.find(:all, :order => 'date_added DESC')
10 + @problems = Problem.order(date_added: :desc)
11 end
11 end
12
12
13 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
13 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
14 verify :method => :post, :only => [ :create, :quick_create,
14 verify :method => :post, :only => [ :create, :quick_create,
15 :do_manage,
15 :do_manage,
16 :do_import,
16 :do_import,
17 ],
17 ],
18 :redirect_to => { :action => :index }
18 :redirect_to => { :action => :index }
19
19
20 def show
20 def show
21 @problem = Problem.find(params[:id])
21 @problem = Problem.find(params[:id])
22 end
22 end
23
23
24 def new
24 def new
25 @problem = Problem.new
25 @problem = Problem.new
26 @description = nil
26 @description = nil
27 end
27 end
28
28
29 def create
29 def create
30 @problem = Problem.new(params[:problem])
30 @problem = Problem.new(params[:problem])
31 @description = Description.new(params[:description])
31 @description = Description.new(params[:description])
32 if @description.body!=''
32 if @description.body!=''
33 if !@description.save
33 if !@description.save
34 render :action => new and return
34 render :action => new and return
35 end
35 end
36 else
36 else
37 @description = nil
37 @description = nil
38 end
38 end
39 @problem.description = @description
39 @problem.description = @description
40 if @problem.save
40 if @problem.save
41 flash[:notice] = 'Problem was successfully created.'
41 flash[:notice] = 'Problem was successfully created.'
42 redirect_to action: :index
42 redirect_to action: :index
43 else
43 else
44 render :action => 'new'
44 render :action => 'new'
45 end
45 end
46 end
46 end
47
47
48 def quick_create
48 def quick_create
49 @problem = Problem.new(params[:problem])
49 @problem = Problem.new(params[:problem])
50 @problem.full_name = @problem.name if @problem.full_name == ''
50 @problem.full_name = @problem.name if @problem.full_name == ''
51 @problem.full_score = 100
51 @problem.full_score = 100
52 @problem.available = false
52 @problem.available = false
53 @problem.test_allowed = true
53 @problem.test_allowed = true
54 @problem.output_only = false
54 @problem.output_only = false
55 @problem.date_added = Time.new
55 @problem.date_added = Time.new
56 if @problem.save
56 if @problem.save
57 flash[:notice] = 'Problem was successfully created.'
57 flash[:notice] = 'Problem was successfully created.'
58 redirect_to action: :index
58 redirect_to action: :index
@@ -90,138 +90,136
90 if @problem.update_attributes(params[:problem])
90 if @problem.update_attributes(params[:problem])
91 flash[:notice] = 'Problem was successfully updated.'
91 flash[:notice] = 'Problem was successfully updated.'
92 unless params[:file] == nil or params[:file] == ''
92 unless params[:file] == nil or params[:file] == ''
93 flash[:notice] = 'Problem was successfully updated and a new PDF file is uploaded.'
93 flash[:notice] = 'Problem was successfully updated and a new PDF file is uploaded.'
94 out_dirname = "#{Problem.download_file_basedir}/#{@problem.id}"
94 out_dirname = "#{Problem.download_file_basedir}/#{@problem.id}"
95 if not FileTest.exists? out_dirname
95 if not FileTest.exists? out_dirname
96 Dir.mkdir out_dirname
96 Dir.mkdir out_dirname
97 end
97 end
98
98
99 out_filename = "#{out_dirname}/#{@problem.name}.pdf"
99 out_filename = "#{out_dirname}/#{@problem.name}.pdf"
100 if FileTest.exists? out_filename
100 if FileTest.exists? out_filename
101 File.delete out_filename
101 File.delete out_filename
102 end
102 end
103
103
104 File.open(out_filename,"wb") do |file|
104 File.open(out_filename,"wb") do |file|
105 file.write(params[:file].read)
105 file.write(params[:file].read)
106 end
106 end
107 @problem.description_filename = "#{@problem.name}.pdf"
107 @problem.description_filename = "#{@problem.name}.pdf"
108 @problem.save
108 @problem.save
109 end
109 end
110 redirect_to :action => 'show', :id => @problem
110 redirect_to :action => 'show', :id => @problem
111 else
111 else
112 render :action => 'edit'
112 render :action => 'edit'
113 end
113 end
114 end
114 end
115
115
116 def destroy
116 def destroy
117 p = Problem.find(params[:id]).destroy
117 p = Problem.find(params[:id]).destroy
118 redirect_to action: :index
118 redirect_to action: :index
119 end
119 end
120
120
121 def toggle
121 def toggle
122 @problem = Problem.find(params[:id])
122 @problem = Problem.find(params[:id])
123 @problem.update_attributes(available: !(@problem.available) )
123 @problem.update_attributes(available: !(@problem.available) )
124 respond_to do |format|
124 respond_to do |format|
125 format.js { }
125 format.js { }
126 end
126 end
127 end
127 end
128
128
129 def toggle_test
129 def toggle_test
130 @problem = Problem.find(params[:id])
130 @problem = Problem.find(params[:id])
131 @problem.update_attributes(test_allowed: !(@problem.test_allowed?) )
131 @problem.update_attributes(test_allowed: !(@problem.test_allowed?) )
132 respond_to do |format|
132 respond_to do |format|
133 format.js { }
133 format.js { }
134 end
134 end
135 end
135 end
136
136
137 def turn_all_off
137 def turn_all_off
138 - Problem.find(:all,
138 + Problem.available.all.each do |problem|
139 - :conditions => "available = 1").each do |problem|
140 problem.available = false
139 problem.available = false
141 problem.save
140 problem.save
142 end
141 end
143 redirect_to action: :index
142 redirect_to action: :index
144 end
143 end
145
144
146 def turn_all_on
145 def turn_all_on
147 - Problem.find(:all,
146 + Problem.where.not(available: true).each do |problem|
148 - :conditions => "available = 0").each do |problem|
149 problem.available = true
147 problem.available = true
150 problem.save
148 problem.save
151 end
149 end
152 redirect_to action: :index
150 redirect_to action: :index
153 end
151 end
154
152
155 def stat
153 def stat
156 @problem = Problem.find(params[:id])
154 @problem = Problem.find(params[:id])
157 unless @problem.available or session[:admin]
155 unless @problem.available or session[:admin]
158 redirect_to :controller => 'main', :action => 'list'
156 redirect_to :controller => 'main', :action => 'list'
159 return
157 return
160 end
158 end
161 @submissions = Submission.includes(:user).where(problem_id: params[:id]).order(:user_id,:id)
159 @submissions = Submission.includes(:user).where(problem_id: params[:id]).order(:user_id,:id)
162
160
163 #stat summary
161 #stat summary
164 range =65
162 range =65
165 @histogram = { data: Array.new(range,0), summary: {} }
163 @histogram = { data: Array.new(range,0), summary: {} }
166 user = Hash.new(0)
164 user = Hash.new(0)
167 @submissions.find_each do |sub|
165 @submissions.find_each do |sub|
168 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
166 d = (DateTime.now.in_time_zone - sub.submitted_at) / 24 / 60 / 60
169 @histogram[:data][d.to_i] += 1 if d < range
167 @histogram[:data][d.to_i] += 1 if d < range
170 user[sub.user_id] = [user[sub.user_id], ((sub.try(:points) || 0) >= @problem.full_score) ? 1 : 0].max
168 user[sub.user_id] = [user[sub.user_id], ((sub.try(:points) || 0) >= @problem.full_score) ? 1 : 0].max
171 end
169 end
172 @histogram[:summary][:max] = [@histogram[:data].max,1].max
170 @histogram[:summary][:max] = [@histogram[:data].max,1].max
173
171
174 @summary = { attempt: user.count, solve: 0 }
172 @summary = { attempt: user.count, solve: 0 }
175 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
173 user.each_value { |v| @summary[:solve] += 1 if v == 1 }
176 end
174 end
177
175
178 def manage
176 def manage
179 - @problems = Problem.find(:all, :order => 'date_added DESC')
177 + @problems = Problem.order(date_added: :desc)
180 end
178 end
181
179
182 def do_manage
180 def do_manage
183 if params.has_key? 'change_date_added'
181 if params.has_key? 'change_date_added'
184 change_date_added
182 change_date_added
185 elsif params.has_key? 'add_to_contest'
183 elsif params.has_key? 'add_to_contest'
186 add_to_contest
184 add_to_contest
187 elsif params.has_key? 'enable_problem'
185 elsif params.has_key? 'enable_problem'
188 set_available(true)
186 set_available(true)
189 elsif params.has_key? 'disable_problem'
187 elsif params.has_key? 'disable_problem'
190 set_available(false)
188 set_available(false)
191 end
189 end
192 redirect_to :action => 'manage'
190 redirect_to :action => 'manage'
193 end
191 end
194
192
195 def import
193 def import
196 @allow_test_pair_import = allow_test_pair_import?
194 @allow_test_pair_import = allow_test_pair_import?
197 end
195 end
198
196
199 def do_import
197 def do_import
200 old_problem = Problem.find_by_name(params[:name])
198 old_problem = Problem.find_by_name(params[:name])
201 if !allow_test_pair_import? and params.has_key? :import_to_db
199 if !allow_test_pair_import? and params.has_key? :import_to_db
202 params.delete :import_to_db
200 params.delete :import_to_db
203 end
201 end
204 @problem, import_log = Problem.create_from_import_form_params(params,
202 @problem, import_log = Problem.create_from_import_form_params(params,
205 old_problem)
203 old_problem)
206
204
207 if !@problem.errors.empty?
205 if !@problem.errors.empty?
208 render :action => 'import' and return
206 render :action => 'import' and return
209 end
207 end
210
208
211 if old_problem!=nil
209 if old_problem!=nil
212 flash[:notice] = "The test data has been replaced for problem #{@problem.name}"
210 flash[:notice] = "The test data has been replaced for problem #{@problem.name}"
213 end
211 end
214 @log = import_log
212 @log = import_log
215 end
213 end
216
214
217 def remove_contest
215 def remove_contest
218 problem = Problem.find(params[:id])
216 problem = Problem.find(params[:id])
219 contest = Contest.find(params[:contest_id])
217 contest = Contest.find(params[:contest_id])
220 if problem!=nil and contest!=nil
218 if problem!=nil and contest!=nil
221 problem.contests.delete(contest)
219 problem.contests.delete(contest)
222 end
220 end
223 redirect_to :action => 'manage'
221 redirect_to :action => 'manage'
224 end
222 end
225
223
226 ##################################
224 ##################################
227 protected
225 protected
@@ -1,126 +1,122
1 require 'csv'
1 require 'csv'
2
2
3 class ReportController < ApplicationController
3 class ReportController < ApplicationController
4
4
5 before_filter :authenticate
5 before_filter :authenticate
6
6
7 before_filter :admin_authorization, only: [:login_stat,:submission_stat, :stuck, :cheat_report, :cheat_scruntinize, :show_max_score]
7 before_filter :admin_authorization, only: [:login_stat,:submission_stat, :stuck, :cheat_report, :cheat_scruntinize, :show_max_score]
8
8
9 before_filter(only: [:problem_hof]) { |c|
9 before_filter(only: [:problem_hof]) { |c|
10 return false unless authenticate
10 return false unless authenticate
11
11
12 - if GraderConfiguration["right.user_view_submission"]
12 + admin_authorization unless GraderConfiguration["right.user_view_submission"]
13 - return true;
14 - end
15 -
16 - admin_authorization
17 }
13 }
18
14
19 def max_score
15 def max_score
20 end
16 end
21
17
22 def current_score
18 def current_score
23 - @problems = Problem.find_available_problems
19 + @problems = Problem.available_problems
24 @users = User.includes(:contests).includes(:contest_stat).where(enabled: true)
20 @users = User.includes(:contests).includes(:contest_stat).where(enabled: true)
25 @scorearray = calculate_max_score(@problems, @users,0,0,true)
21 @scorearray = calculate_max_score(@problems, @users,0,0,true)
26
22
27 #rencer accordingly
23 #rencer accordingly
28 if params[:button] == 'download' then
24 if params[:button] == 'download' then
29 csv = gen_csv_from_scorearray(@scorearray,@problems)
25 csv = gen_csv_from_scorearray(@scorearray,@problems)
30 send_data csv, filename: 'max_score.csv'
26 send_data csv, filename: 'max_score.csv'
31 else
27 else
32 #render template: 'user_admin/user_stat'
28 #render template: 'user_admin/user_stat'
33 render 'current_score'
29 render 'current_score'
34 end
30 end
35 end
31 end
36
32
37 def show_max_score
33 def show_max_score
38 #process parameters
34 #process parameters
39 #problems
35 #problems
40 @problems = []
36 @problems = []
41 params[:problem_id].each do |id|
37 params[:problem_id].each do |id|
42 next unless id.strip != ""
38 next unless id.strip != ""
43 pid = Problem.find_by_id(id.to_i)
39 pid = Problem.find_by_id(id.to_i)
44 @problems << pid if pid
40 @problems << pid if pid
45 end
41 end
46
42
47 #users
43 #users
48 @users = if params[:user] == "all" then
44 @users = if params[:user] == "all" then
49 - User.find(:all, :include => [:contests, :contest_stat])
45 + User.includes(:contests).includes(:contest_stat)
50 else
46 else
51 User.includes(:contests).includes(:contest_stat).where(enabled: true)
47 User.includes(:contests).includes(:contest_stat).where(enabled: true)
52 end
48 end
53
49
54 #set up range from param
50 #set up range from param
55 since_id = params.fetch(:from_id, 0).to_i
51 since_id = params.fetch(:from_id, 0).to_i
56 until_id = params.fetch(:to_id, 0).to_i
52 until_id = params.fetch(:to_id, 0).to_i
57
53
58 #calculate the routine
54 #calculate the routine
59 @scorearray = calculate_max_score(@problems, @users,since_id,until_id)
55 @scorearray = calculate_max_score(@problems, @users,since_id,until_id)
60
56
61 #rencer accordingly
57 #rencer accordingly
62 if params[:button] == 'download' then
58 if params[:button] == 'download' then
63 csv = gen_csv_from_scorearray(@scorearray,@problems)
59 csv = gen_csv_from_scorearray(@scorearray,@problems)
64 send_data csv, filename: 'max_score.csv'
60 send_data csv, filename: 'max_score.csv'
65 else
61 else
66 #render template: 'user_admin/user_stat'
62 #render template: 'user_admin/user_stat'
67 render 'max_score'
63 render 'max_score'
68 end
64 end
69
65
70 end
66 end
71
67
72 def score
68 def score
73 if params[:commit] == 'download csv'
69 if params[:commit] == 'download csv'
74 @problems = Problem.all
70 @problems = Problem.all
75 else
71 else
76 - @problems = Problem.find_available_problems
72 + @problems = Problem.available_problems
77 end
73 end
78 - @users = User.includes(:contests, :contest_stat).where(enabled: true) #find(:all, :include => [:contests, :contest_stat]).where(enabled: true)
74 + @users = User.includes(:contests, :contest_stat).where(enabled: true)
79 @scorearray = Array.new
75 @scorearray = Array.new
80 @users.each do |u|
76 @users.each do |u|
81 ustat = Array.new
77 ustat = Array.new
82 ustat[0] = u
78 ustat[0] = u
83 @problems.each do |p|
79 @problems.each do |p|
84 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
80 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
85 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
81 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
86 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
82 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
87 else
83 else
88 ustat << [0,false]
84 ustat << [0,false]
89 end
85 end
90 end
86 end
91 @scorearray << ustat
87 @scorearray << ustat
92 end
88 end
93 if params[:commit] == 'download csv' then
89 if params[:commit] == 'download csv' then
94 csv = gen_csv_from_scorearray(@scorearray,@problems)
90 csv = gen_csv_from_scorearray(@scorearray,@problems)
95 send_data csv, filename: 'last_score.csv'
91 send_data csv, filename: 'last_score.csv'
96 else
92 else
97 render template: 'user_admin/user_stat'
93 render template: 'user_admin/user_stat'
98 end
94 end
99
95
100 end
96 end
101
97
102 def login_stat
98 def login_stat
103 @logins = Array.new
99 @logins = Array.new
104
100
105 date_and_time = '%Y-%m-%d %H:%M'
101 date_and_time = '%Y-%m-%d %H:%M'
106 begin
102 begin
107 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
103 md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
108 @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
104 @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
109 rescue
105 rescue
110 @since_time = DateTime.new(1000,1,1)
106 @since_time = DateTime.new(1000,1,1)
111 end
107 end
112 begin
108 begin
113 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
109 md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/)
114 @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
110 @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i)
115 rescue
111 rescue
116 @until_time = DateTime.new(3000,1,1)
112 @until_time = DateTime.new(3000,1,1)
117 end
113 end
118
114
119 User.all.each do |user|
115 User.all.each do |user|
120 @logins << { id: user.id,
116 @logins << { id: user.id,
121 login: user.login,
117 login: user.login,
122 full_name: user.full_name,
118 full_name: user.full_name,
123 count: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
119 count: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
124 user.id,@since_time,@until_time)
120 user.id,@since_time,@until_time)
125 .count(:id),
121 .count(:id),
126 min: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
122 min: Login.where("user_id = ? AND created_at >= ? AND created_at <= ?",
@@ -1,55 +1,55
1 class SiteController < ApplicationController
1 class SiteController < ApplicationController
2
2
3 before_filter :site_admin_authorization, :except => 'login'
3 before_filter :site_admin_authorization, :except => 'login'
4
4
5 def login
5 def login
6 # Site administrator login
6 # Site administrator login
7 - @countries = Country.find(:all, :include => :sites)
7 + @countries = Country.includes(:sites).all
8 @country_select = @countries.collect { |c| [c.name, c.id] }
8 @country_select = @countries.collect { |c| [c.name, c.id] }
9
9
10 @country_select_with_all = [['Any',0]]
10 @country_select_with_all = [['Any',0]]
11 @countries.each do |country|
11 @countries.each do |country|
12 @country_select_with_all << [country.name, country.id]
12 @country_select_with_all << [country.name, country.id]
13 end
13 end
14
14
15 @site_select = []
15 @site_select = []
16 @countries.each do |country|
16 @countries.each do |country|
17 country.sites.each do |site|
17 country.sites.each do |site|
18 @site_select << ["#{site.name}, #{country.name}", site.id]
18 @site_select << ["#{site.name}, #{country.name}", site.id]
19 end
19 end
20 end
20 end
21
21
22 @default_site = Site.first if !GraderConfiguration['contest.multisites']
22 @default_site = Site.first if !GraderConfiguration['contest.multisites']
23
23
24 render :action => 'login', :layout => 'empty'
24 render :action => 'login', :layout => 'empty'
25 end
25 end
26
26
27 def index
27 def index
28 if @site.started
28 if @site.started
29 render :action => 'started', :layout => 'empty'
29 render :action => 'started', :layout => 'empty'
30 else
30 else
31 render :action => 'prompt', :layout => 'empty'
31 render :action => 'prompt', :layout => 'empty'
32 end
32 end
33 end
33 end
34
34
35 def start
35 def start
36 @site.started = true
36 @site.started = true
37 @site.start_time = Time.new.gmtime
37 @site.start_time = Time.new.gmtime
38 @site.save
38 @site.save
39 redirect_to :action => 'index'
39 redirect_to :action => 'index'
40 end
40 end
41
41
42 def logout
42 def logout
43 reset_session
43 reset_session
44 redirect_to :controller => 'main', :action => 'login'
44 redirect_to :controller => 'main', :action => 'login'
45 end
45 end
46
46
47 protected
47 protected
48 def site_admin_authorization
48 def site_admin_authorization
49 if session[:site_id]==nil
49 if session[:site_id]==nil
50 redirect_to :controller => 'site', :action => 'login' and return
50 redirect_to :controller => 'site', :action => 'login' and return
51 end
51 end
52 begin
52 begin
53 @site = Site.find(session[:site_id], :include => :country)
53 @site = Site.find(session[:site_id], :include => :country)
54 rescue ActiveRecord::RecordNotFound
54 rescue ActiveRecord::RecordNotFound
55 @site = nil
55 @site = nil
@@ -1,56 +1,56
1 class SitesController < ApplicationController
1 class SitesController < ApplicationController
2
2
3 before_filter :admin_authorization
3 before_filter :admin_authorization
4
4
5 # GET /sites
5 # GET /sites
6 # GET /sites.xml
6 # GET /sites.xml
7 def index
7 def index
8 - @sites = Site.find(:all, :order => 'country_id')
8 + @sites = Site.order(:country_id)
9
9
10 respond_to do |format|
10 respond_to do |format|
11 format.html # index.html.erb
11 format.html # index.html.erb
12 format.xml { render :xml => @sites }
12 format.xml { render :xml => @sites }
13 end
13 end
14 end
14 end
15
15
16 # GET /sites/1
16 # GET /sites/1
17 # GET /sites/1.xml
17 # GET /sites/1.xml
18 def show
18 def show
19 @site = Site.find(params[:id])
19 @site = Site.find(params[:id])
20
20
21 respond_to do |format|
21 respond_to do |format|
22 format.html # show.html.erb
22 format.html # show.html.erb
23 format.xml { render :xml => @site }
23 format.xml { render :xml => @site }
24 end
24 end
25 end
25 end
26
26
27 # GET /sites/new
27 # GET /sites/new
28 # GET /sites/new.xml
28 # GET /sites/new.xml
29 def new
29 def new
30 @site = Site.new
30 @site = Site.new
31
31
32 respond_to do |format|
32 respond_to do |format|
33 format.html # new.html.erb
33 format.html # new.html.erb
34 format.xml { render :xml => @site }
34 format.xml { render :xml => @site }
35 end
35 end
36 end
36 end
37
37
38 # GET /sites/1/edit
38 # GET /sites/1/edit
39 def edit
39 def edit
40 @site = Site.find(params[:id])
40 @site = Site.find(params[:id])
41 end
41 end
42
42
43 # POST /sites
43 # POST /sites
44 # POST /sites.xml
44 # POST /sites.xml
45 def create
45 def create
46 @site = Site.new(params[:site])
46 @site = Site.new(params[:site])
47 @site.clear_start_time_if_not_started
47 @site.clear_start_time_if_not_started
48
48
49 respond_to do |format|
49 respond_to do |format|
50 if @site.save
50 if @site.save
51 flash[:notice] = 'Site was successfully created.'
51 flash[:notice] = 'Site was successfully created.'
52 format.html { redirect_to(@site) }
52 format.html { redirect_to(@site) }
53 format.xml { render :xml => @site, :status => :created, :location => @site }
53 format.xml { render :xml => @site, :status => :created, :location => @site }
54 else
54 else
55 format.html { render :action => "new" }
55 format.html { render :action => "new" }
56 format.xml { render :xml => @site.errors, :status => :unprocessable_entity }
56 format.xml { render :xml => @site.errors, :status => :unprocessable_entity }
@@ -1,80 +1,80
1 require 'csv'
1 require 'csv'
2
2
3 class UserAdminController < ApplicationController
3 class UserAdminController < ApplicationController
4
4
5 include MailHelperMethods
5 include MailHelperMethods
6
6
7 before_filter :admin_authorization
7 before_filter :admin_authorization
8
8
9 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
9 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
10 verify :method => :post, :only => [
10 verify :method => :post, :only => [
11 :create, :create_from_list,
11 :create, :create_from_list,
12 :update,
12 :update,
13 :manage_contest,
13 :manage_contest,
14 :bulk_mail
14 :bulk_mail
15 ],
15 ],
16 :redirect_to => { :action => :list }
16 :redirect_to => { :action => :list }
17
17
18 def index
18 def index
19 @user_count = User.count
19 @user_count = User.count
20 if params[:page] == 'all'
20 if params[:page] == 'all'
21 @users = User.all
21 @users = User.all
22 @paginated = false
22 @paginated = false
23 else
23 else
24 @users = User.paginate :page => params[:page]
24 @users = User.paginate :page => params[:page]
25 @paginated = true
25 @paginated = true
26 end
26 end
27 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
27 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
28 @contests = Contest.enabled
28 @contests = Contest.enabled
29 end
29 end
30
30
31 def active
31 def active
32 - sessions = ActiveRecord::SessionStore::Session.find(:all, :conditions => ["updated_at >= ?", 60.minutes.ago])
32 + sessions = ActiveRecord::SessionStore::Session.where("updated_at >= ?", 60.minutes.ago)
33 @users = []
33 @users = []
34 sessions.each do |session|
34 sessions.each do |session|
35 if session.data[:user_id]
35 if session.data[:user_id]
36 @users << User.find(session.data[:user_id])
36 @users << User.find(session.data[:user_id])
37 end
37 end
38 end
38 end
39 end
39 end
40
40
41 def show
41 def show
42 @user = User.find(params[:id])
42 @user = User.find(params[:id])
43 end
43 end
44
44
45 def new
45 def new
46 @user = User.new
46 @user = User.new
47 end
47 end
48
48
49 def create
49 def create
50 @user = User.new(params[:user])
50 @user = User.new(params[:user])
51 @user.activated = true
51 @user.activated = true
52 if @user.save
52 if @user.save
53 flash[:notice] = 'User was successfully created.'
53 flash[:notice] = 'User was successfully created.'
54 redirect_to :action => 'index'
54 redirect_to :action => 'index'
55 else
55 else
56 render :action => 'new'
56 render :action => 'new'
57 end
57 end
58 end
58 end
59
59
60 def clear_last_ip
60 def clear_last_ip
61 @user = User.find(params[:id])
61 @user = User.find(params[:id])
62 @user.last_ip = nil
62 @user.last_ip = nil
63 @user.save
63 @user.save
64 redirect_to action: 'index', page: params[:page]
64 redirect_to action: 'index', page: params[:page]
65 end
65 end
66
66
67 def create_from_list
67 def create_from_list
68 lines = params[:user_list]
68 lines = params[:user_list]
69
69
70 note = []
70 note = []
71
71
72 lines.split("\n").each do |line|
72 lines.split("\n").each do |line|
73 items = line.chomp.split(',')
73 items = line.chomp.split(',')
74 if items.length>=2
74 if items.length>=2
75 login = items[0]
75 login = items[0]
76 full_name = items[1]
76 full_name = items[1]
77
77
78 added_random_password = false
78 added_random_password = false
79 if items.length>=3
79 if items.length>=3
80 password = items[2].chomp(" ")
80 password = items[2].chomp(" ")
@@ -90,163 +90,163
90 user.full_name = full_name
90 user.full_name = full_name
91 user.password = password
91 user.password = password
92 else
92 else
93 user = User.new({:login => login,
93 user = User.new({:login => login,
94 :full_name => full_name,
94 :full_name => full_name,
95 :password => password,
95 :password => password,
96 :password_confirmation => password,
96 :password_confirmation => password,
97 :alias => user_alias})
97 :alias => user_alias})
98 end
98 end
99 user.activated = true
99 user.activated = true
100 user.save
100 user.save
101
101
102 if added_random_password
102 if added_random_password
103 note << "'#{login}' (+)"
103 note << "'#{login}' (+)"
104 else
104 else
105 note << login
105 note << login
106 end
106 end
107 end
107 end
108 end
108 end
109 flash[:notice] = 'User(s) ' + note.join(', ') +
109 flash[:notice] = 'User(s) ' + note.join(', ') +
110 ' were successfully created. ' +
110 ' were successfully created. ' +
111 '( (+) - created with random passwords.)'
111 '( (+) - created with random passwords.)'
112 redirect_to :action => 'index'
112 redirect_to :action => 'index'
113 end
113 end
114
114
115 def edit
115 def edit
116 @user = User.find(params[:id])
116 @user = User.find(params[:id])
117 end
117 end
118
118
119 def update
119 def update
120 @user = User.find(params[:id])
120 @user = User.find(params[:id])
121 if @user.update_attributes(user_params)
121 if @user.update_attributes(user_params)
122 flash[:notice] = 'User was successfully updated.'
122 flash[:notice] = 'User was successfully updated.'
123 redirect_to :action => 'show', :id => @user
123 redirect_to :action => 'show', :id => @user
124 else
124 else
125 render :action => 'edit'
125 render :action => 'edit'
126 end
126 end
127 end
127 end
128
128
129 def destroy
129 def destroy
130 User.find(params[:id]).destroy
130 User.find(params[:id]).destroy
131 redirect_to :action => 'index'
131 redirect_to :action => 'index'
132 end
132 end
133
133
134 def user_stat
134 def user_stat
135 if params[:commit] == 'download csv'
135 if params[:commit] == 'download csv'
136 @problems = Problem.all
136 @problems = Problem.all
137 else
137 else
138 - @problems = Problem.find_available_problems
138 + @problems = Problem.available_problems
139 end
139 end
140 - @users = User.includes(:contests, :contest_stat).where(enabled: true) #find(:all, :include => [:contests, :contest_stat]).where(enabled: true)
140 + @users = User.includes(:contests, :contest_stat).where(enabled: true)
141 @scorearray = Array.new
141 @scorearray = Array.new
142 @users.each do |u|
142 @users.each do |u|
143 ustat = Array.new
143 ustat = Array.new
144 ustat[0] = u
144 ustat[0] = u
145 @problems.each do |p|
145 @problems.each do |p|
146 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
146 sub = Submission.find_last_by_user_and_problem(u.id,p.id)
147 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
147 if (sub!=nil) and (sub.points!=nil) and p and p.full_score
148 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
148 ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)]
149 else
149 else
150 ustat << [0,false]
150 ustat << [0,false]
151 end
151 end
152 end
152 end
153 @scorearray << ustat
153 @scorearray << ustat
154 end
154 end
155 if params[:commit] == 'download csv' then
155 if params[:commit] == 'download csv' then
156 csv = gen_csv_from_scorearray(@scorearray,@problems)
156 csv = gen_csv_from_scorearray(@scorearray,@problems)
157 send_data csv, filename: 'last_score.csv'
157 send_data csv, filename: 'last_score.csv'
158 else
158 else
159 render template: 'user_admin/user_stat'
159 render template: 'user_admin/user_stat'
160 end
160 end
161 end
161 end
162
162
163 def user_stat_max
163 def user_stat_max
164 if params[:commit] == 'download csv'
164 if params[:commit] == 'download csv'
165 @problems = Problem.all
165 @problems = Problem.all
166 else
166 else
167 - @problems = Problem.find_available_problems
167 + @problems = Problem.available_problems
168 end
168 end
169 - @users = User.find(:all, :include => [:contests, :contest_stat])
169 + @users = User.includes(:contests).includes(:contest_stat).all
170 @scorearray = Array.new
170 @scorearray = Array.new
171 #set up range from param
171 #set up range from param
172 since_id = params.fetch(:since_id, 0).to_i
172 since_id = params.fetch(:since_id, 0).to_i
173 until_id = params.fetch(:until_id, 0).to_i
173 until_id = params.fetch(:until_id, 0).to_i
174 @users.each do |u|
174 @users.each do |u|
175 ustat = Array.new
175 ustat = Array.new
176 ustat[0] = u
176 ustat[0] = u
177 @problems.each do |p|
177 @problems.each do |p|
178 max_points = 0
178 max_points = 0
179 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
179 Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub|
180 max_points = sub.points if sub and sub.points and (sub.points > max_points)
180 max_points = sub.points if sub and sub.points and (sub.points > max_points)
181 end
181 end
182 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
182 ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)]
183 end
183 end
184 @scorearray << ustat
184 @scorearray << ustat
185 end
185 end
186
186
187 if params[:commit] == 'download csv' then
187 if params[:commit] == 'download csv' then
188 csv = gen_csv_from_scorearray(@scorearray,@problems)
188 csv = gen_csv_from_scorearray(@scorearray,@problems)
189 send_data csv, filename: 'max_score.csv'
189 send_data csv, filename: 'max_score.csv'
190 else
190 else
191 render template: 'user_admin/user_stat'
191 render template: 'user_admin/user_stat'
192 end
192 end
193 end
193 end
194
194
195 def import
195 def import
196 if params[:file]==''
196 if params[:file]==''
197 flash[:notice] = 'Error importing no file'
197 flash[:notice] = 'Error importing no file'
198 redirect_to :action => 'index' and return
198 redirect_to :action => 'index' and return
199 end
199 end
200 import_from_file(params[:file])
200 import_from_file(params[:file])
201 end
201 end
202
202
203 def random_all_passwords
203 def random_all_passwords
204 - users = User.find(:all)
204 + users = User.all
205 @prefix = params[:prefix] || ''
205 @prefix = params[:prefix] || ''
206 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
206 @non_admin_users = User.find_non_admin_with_prefix(@prefix)
207 @changed = false
207 @changed = false
208 if request.request_method == 'POST'
208 if request.request_method == 'POST'
209 @non_admin_users.each do |user|
209 @non_admin_users.each do |user|
210 password = random_password
210 password = random_password
211 user.password = password
211 user.password = password
212 user.password_confirmation = password
212 user.password_confirmation = password
213 user.save
213 user.save
214 end
214 end
215 @changed = true
215 @changed = true
216 end
216 end
217 end
217 end
218
218
219 # contest management
219 # contest management
220
220
221 def contests
221 def contests
222 @contest, @users = find_contest_and_user_from_contest_id(params[:id])
222 @contest, @users = find_contest_and_user_from_contest_id(params[:id])
223 @contests = Contest.enabled
223 @contests = Contest.enabled
224 end
224 end
225
225
226 def assign_from_list
226 def assign_from_list
227 contest_id = params[:users_contest_id]
227 contest_id = params[:users_contest_id]
228 org_contest, users = find_contest_and_user_from_contest_id(contest_id)
228 org_contest, users = find_contest_and_user_from_contest_id(contest_id)
229 contest = Contest.find(params[:new_contest][:id])
229 contest = Contest.find(params[:new_contest][:id])
230 if !contest
230 if !contest
231 flash[:notice] = 'Error: no contest'
231 flash[:notice] = 'Error: no contest'
232 redirect_to :action => 'contests', :id =>contest_id
232 redirect_to :action => 'contests', :id =>contest_id
233 end
233 end
234
234
235 note = []
235 note = []
236 users.each do |u|
236 users.each do |u|
237 u.contests = [contest]
237 u.contests = [contest]
238 note << u.login
238 note << u.login
239 end
239 end
240 flash[:notice] = 'User(s) ' + note.join(', ') +
240 flash[:notice] = 'User(s) ' + note.join(', ') +
241 " were successfully reassigned to #{contest.title}."
241 " were successfully reassigned to #{contest.title}."
242 redirect_to :action => 'contests', :id =>contest.id
242 redirect_to :action => 'contests', :id =>contest.id
243 end
243 end
244
244
245 def add_to_contest
245 def add_to_contest
246 user = User.find(params[:id])
246 user = User.find(params[:id])
247 contest = Contest.find(params[:contest_id])
247 contest = Contest.find(params[:contest_id])
248 if user and contest
248 if user and contest
249 user.contests << contest
249 user.contests << contest
250 end
250 end
251 redirect_to :action => 'index'
251 redirect_to :action => 'index'
252 end
252 end
@@ -279,97 +279,97
279
279
280 lines = params[:login_list]
280 lines = params[:login_list]
281 if !lines or lines.blank?
281 if !lines or lines.blank?
282 flash[:notice] = 'You entered an empty list.'
282 flash[:notice] = 'You entered an empty list.'
283 redirect_to :action => 'contest_management' and return
283 redirect_to :action => 'contest_management' and return
284 end
284 end
285
285
286 note = []
286 note = []
287 users = []
287 users = []
288 lines.split("\n").each do |line|
288 lines.split("\n").each do |line|
289 user = User.find_by_login(line.chomp)
289 user = User.find_by_login(line.chomp)
290 if user
290 if user
291 if operation=='add'
291 if operation=='add'
292 if ! user.contests.include? contest
292 if ! user.contests.include? contest
293 user.contests << contest
293 user.contests << contest
294 end
294 end
295 elsif operation=='remove'
295 elsif operation=='remove'
296 user.contests.delete(contest)
296 user.contests.delete(contest)
297 else
297 else
298 user.contests = [contest]
298 user.contests = [contest]
299 end
299 end
300
300
301 if params[:reset_timer]
301 if params[:reset_timer]
302 user.contest_stat.forced_logout = true
302 user.contest_stat.forced_logout = true
303 user.contest_stat.reset_timer_and_save
303 user.contest_stat.reset_timer_and_save
304 end
304 end
305
305
306 if params[:notification_emails]
306 if params[:notification_emails]
307 send_contest_update_notification_email(user, contest)
307 send_contest_update_notification_email(user, contest)
308 end
308 end
309
309
310 note << user.login
310 note << user.login
311 users << user
311 users << user
312 end
312 end
313 end
313 end
314
314
315 if params[:reset_timer]
315 if params[:reset_timer]
316 logout_users(users)
316 logout_users(users)
317 end
317 end
318
318
319 flash[:notice] = 'User(s) ' + note.join(', ') +
319 flash[:notice] = 'User(s) ' + note.join(', ') +
320 ' were successfully modified. '
320 ' were successfully modified. '
321 redirect_to :action => 'contest_management'
321 redirect_to :action => 'contest_management'
322 end
322 end
323
323
324 # admin management
324 # admin management
325
325
326 def admin
326 def admin
327 - @admins = User.find(:all).find_all {|user| user.admin? }
327 + @admins = User.all.find_all {|user| user.admin? }
328 end
328 end
329
329
330 def grant_admin
330 def grant_admin
331 login = params[:login]
331 login = params[:login]
332 user = User.find_by_login(login)
332 user = User.find_by_login(login)
333 if user!=nil
333 if user!=nil
334 admin_role = Role.find_by_name('admin')
334 admin_role = Role.find_by_name('admin')
335 user.roles << admin_role
335 user.roles << admin_role
336 else
336 else
337 flash[:notice] = 'Unknown user'
337 flash[:notice] = 'Unknown user'
338 end
338 end
339 flash[:notice] = 'User added as admins'
339 flash[:notice] = 'User added as admins'
340 redirect_to :action => 'admin'
340 redirect_to :action => 'admin'
341 end
341 end
342
342
343 def revoke_admin
343 def revoke_admin
344 user = User.find(params[:id])
344 user = User.find(params[:id])
345 if user==nil
345 if user==nil
346 flash[:notice] = 'Unknown user'
346 flash[:notice] = 'Unknown user'
347 redirect_to :action => 'admin' and return
347 redirect_to :action => 'admin' and return
348 elsif user.login == 'root'
348 elsif user.login == 'root'
349 flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
349 flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
350 redirect_to :action => 'admin' and return
350 redirect_to :action => 'admin' and return
351 end
351 end
352
352
353 admin_role = Role.find_by_name('admin')
353 admin_role = Role.find_by_name('admin')
354 user.roles.delete(admin_role)
354 user.roles.delete(admin_role)
355 flash[:notice] = 'User permission revoked'
355 flash[:notice] = 'User permission revoked'
356 redirect_to :action => 'admin'
356 redirect_to :action => 'admin'
357 end
357 end
358
358
359 # mass mailing
359 # mass mailing
360
360
361 def mass_mailing
361 def mass_mailing
362 end
362 end
363
363
364 def bulk_mail
364 def bulk_mail
365 lines = params[:login_list]
365 lines = params[:login_list]
366 if !lines or lines.blank?
366 if !lines or lines.blank?
367 flash[:notice] = 'You entered an empty list.'
367 flash[:notice] = 'You entered an empty list.'
368 redirect_to :action => 'mass_mailing' and return
368 redirect_to :action => 'mass_mailing' and return
369 end
369 end
370
370
371 mail_subject = params[:subject]
371 mail_subject = params[:subject]
372 if !mail_subject or mail_subject.blank?
372 if !mail_subject or mail_subject.blank?
373 flash[:notice] = 'You entered an empty mail subject.'
373 flash[:notice] = 'You entered an empty mail subject.'
374 redirect_to :action => 'mass_mailing' and return
374 redirect_to :action => 'mass_mailing' and return
375 end
375 end
@@ -1,21 +1,15
1 class Announcement < ActiveRecord::Base
1 class Announcement < ActiveRecord::Base
2
2
3 - def self.find_published(contest_started=false)
3 + def self.published(contest_started=false)
4 if contest_started
4 if contest_started
5 - Announcement.find(:all,
5 + where(published: true).where(frontpage: false).order(created_at: :desc)
6 - :conditions => "(published = 1) AND (frontpage = 0)",
7 - :order => "created_at DESC")
8 else
6 else
9 - Announcement.find(:all,
7 + where(published: true).where(frontpage: false).where(contest_only: false).order(created_at: :desc)
10 - :conditions => "(published = 1) AND (frontpage = 0) AND (contest_only = 0)",
11 - :order => "created_at DESC")
12 end
8 end
13 end
9 end
14
10
15 - def self.find_for_frontpage
11 + def self.frontpage
16 - Announcement.find(:all,
12 + where(published: 1).where(frontpage: 1).order(created_at: :desc)
17 - :conditions => "(published = 1) AND (frontpage = 1)",
18 - :order => "created_at DESC")
19 end
13 end
20
14
21 end
15 end
@@ -107,71 +107,71
107
107
108 def self.time_limit_mode?
108 def self.time_limit_mode?
109 mode = get(SYSTEM_MODE_CONF_KEY)
109 mode = get(SYSTEM_MODE_CONF_KEY)
110 return ((mode == 'contest') or (mode == 'indv-contest'))
110 return ((mode == 'contest') or (mode == 'indv-contest'))
111 end
111 end
112
112
113 def self.analysis_mode?
113 def self.analysis_mode?
114 return get(SYSTEM_MODE_CONF_KEY) == 'analysis'
114 return get(SYSTEM_MODE_CONF_KEY) == 'analysis'
115 end
115 end
116
116
117 def self.contest_time_limit
117 def self.contest_time_limit
118 contest_time_str = GraderConfiguration[CONTEST_TIME_LIMIT_KEY]
118 contest_time_str = GraderConfiguration[CONTEST_TIME_LIMIT_KEY]
119
119
120 if not defined? GraderConfiguration.contest_time_str
120 if not defined? GraderConfiguration.contest_time_str
121 GraderConfiguration.contest_time_str = nil
121 GraderConfiguration.contest_time_str = nil
122 end
122 end
123
123
124 if GraderConfiguration.contest_time_str != contest_time_str
124 if GraderConfiguration.contest_time_str != contest_time_str
125 GraderConfiguration.contest_time_str = contest_time_str
125 GraderConfiguration.contest_time_str = contest_time_str
126 if tmatch = /(\d+):(\d+)/.match(contest_time_str)
126 if tmatch = /(\d+):(\d+)/.match(contest_time_str)
127 h = tmatch[1].to_i
127 h = tmatch[1].to_i
128 m = tmatch[2].to_i
128 m = tmatch[2].to_i
129
129
130 GraderConfiguration.contest_time = h.hour + m.minute
130 GraderConfiguration.contest_time = h.hour + m.minute
131 else
131 else
132 GraderConfiguration.contest_time = nil
132 GraderConfiguration.contest_time = nil
133 end
133 end
134 end
134 end
135 return GraderConfiguration.contest_time
135 return GraderConfiguration.contest_time
136 end
136 end
137
137
138 protected
138 protected
139
139
140 def self.convert_type(val,type)
140 def self.convert_type(val,type)
141 case type
141 case type
142 when 'string'
142 when 'string'
143 return val
143 return val
144
144
145 when 'integer'
145 when 'integer'
146 return val.to_i
146 return val.to_i
147
147
148 when 'boolean'
148 when 'boolean'
149 return (val=='true')
149 return (val=='true')
150 end
150 end
151 end
151 end
152
152
153 def self.read_config
153 def self.read_config
154 GraderConfiguration.config_cache = {}
154 GraderConfiguration.config_cache = {}
155 - GraderConfiguration.find(:all).each do |conf|
155 + GraderConfiguration.all.each do |conf|
156 key = conf.key
156 key = conf.key
157 val = conf.value
157 val = conf.value
158 GraderConfiguration.config_cache[key] = GraderConfiguration.convert_type(val,conf.value_type)
158 GraderConfiguration.config_cache[key] = GraderConfiguration.convert_type(val,conf.value_type)
159 end
159 end
160 end
160 end
161
161
162 def self.read_one_key(key)
162 def self.read_one_key(key)
163 conf = GraderConfiguration.find_by_key(key)
163 conf = GraderConfiguration.find_by_key(key)
164 if conf
164 if conf
165 return GraderConfiguration.convert_type(conf.value,conf.value_type)
165 return GraderConfiguration.convert_type(conf.value,conf.value_type)
166 else
166 else
167 return nil
167 return nil
168 end
168 end
169 end
169 end
170
170
171 def self.read_grading_info
171 def self.read_grading_info
172 f = File.open(TASK_GRADING_INFO_FILENAME)
172 f = File.open(TASK_GRADING_INFO_FILENAME)
173 GraderConfiguration.task_grading_info_cache = YAML.load(f)
173 GraderConfiguration.task_grading_info_cache = YAML.load(f)
174 f.close
174 f.close
175 end
175 end
176
176
177 end
177 end
@@ -1,81 +1,72
1 class GraderProcess < ActiveRecord::Base
1 class GraderProcess < ActiveRecord::Base
2
2
3 def self.find_by_host_and_pid(host,pid)
3 def self.find_by_host_and_pid(host,pid)
4 - return GraderProcess.find(:first,
4 + return GraderProcess.where(host:host).where(pid: pid).first
5 - :conditions => {
6 - :host => host,
7 - :pid => pid
8 - })
9 end
5 end
10
6
11 def self.register(host,pid,mode)
7 def self.register(host,pid,mode)
12 grader = GraderProcess.find_by_host_and_pid(host,pid)
8 grader = GraderProcess.find_by_host_and_pid(host,pid)
13 if grader
9 if grader
14 grader.mode = mode
10 grader.mode = mode
15 grader.active = nil
11 grader.active = nil
16 grader.task_id = nil
12 grader.task_id = nil
17 grader.task_type = nil
13 grader.task_type = nil
18 grader.terminated = false
14 grader.terminated = false
19 grader.save
15 grader.save
20 else
16 else
21 grader = GraderProcess.create(:host => host,
17 grader = GraderProcess.create(:host => host,
22 :pid => pid,
18 :pid => pid,
23 :mode => mode,
19 :mode => mode,
24 :terminated => false)
20 :terminated => false)
25 end
21 end
26 grader
22 grader
27 end
23 end
28
24
29 def self.find_running_graders
25 def self.find_running_graders
30 - GraderProcess.find(:all,
26 + where(terminated: false)
31 - :conditions => {:terminated => 0})
32 end
27 end
33
28
34 def self.find_terminated_graders
29 def self.find_terminated_graders
35 - GraderProcess.find(:all,
30 + where(terminated: true)
36 - :conditions => "`terminated`")
37 end
31 end
38
32
39 def self.find_stalled_process
33 def self.find_stalled_process
40 - GraderProcess.find(:all,
34 + where(terminated: false).where(active: true).where("updated_at < ?",Time.now.gmtime - GraderProcess.stalled_time)
41 - :conditions => ["(`terminated` = 0) AND active AND " +
42 - "(updated_at < ?)",
43 - Time.now.gmtime - GraderProcess.stalled_time])
44 end
35 end
45
36
46 def report_active(task=nil)
37 def report_active(task=nil)
47 self.active = true
38 self.active = true
48 if task!=nil
39 if task!=nil
49 self.task_id = task.id
40 self.task_id = task.id
50 self.task_type = task.class.to_s
41 self.task_type = task.class.to_s
51 else
42 else
52 self.task_id = nil
43 self.task_id = nil
53 self.task_type = nil
44 self.task_type = nil
54 end
45 end
55 self.save
46 self.save
56 end
47 end
57
48
58 def report_inactive(task=nil)
49 def report_inactive(task=nil)
59 self.active = false
50 self.active = false
60 if task!=nil
51 if task!=nil
61 self.task_id = task.id
52 self.task_id = task.id
62 self.task_type = task.class.to_s
53 self.task_type = task.class.to_s
63 else
54 else
64 self.task_id = nil
55 self.task_id = nil
65 self.task_type = nil
56 self.task_type = nil
66 end
57 end
67 self.save
58 self.save
68 end
59 end
69
60
70 def terminate
61 def terminate
71 self.terminated = true
62 self.terminated = true
72 self.save
63 self.save
73 end
64 end
74
65
75 protected
66 protected
76
67
77 def self.stalled_time()
68 def self.stalled_time()
78 return 1.minute
69 return 1.minute
79 end
70 end
80
71
81 end
72 end
@@ -1,24 +1,24
1 class Language < ActiveRecord::Base
1 class Language < ActiveRecord::Base
2
2
3 @@languages_by_ext = {}
3 @@languages_by_ext = {}
4
4
5 def self.cache_ext_hash
5 def self.cache_ext_hash
6 @@languages_by_ext = {}
6 @@languages_by_ext = {}
7 - Language.find(:all).each do |language|
7 + Language.all.each do |language|
8 language.common_ext.split(',').each do |ext|
8 language.common_ext.split(',').each do |ext|
9 @@languages_by_ext[ext] = language
9 @@languages_by_ext[ext] = language
10 end
10 end
11 end
11 end
12 end
12 end
13
13
14 def self.find_by_extension(ext)
14 def self.find_by_extension(ext)
15 if @@languages_by_ext.length == 0
15 if @@languages_by_ext.length == 0
16 Language.cache_ext_hash
16 Language.cache_ext_hash
17 end
17 end
18 if @@languages_by_ext.has_key? ext
18 if @@languages_by_ext.has_key? ext
19 return @@languages_by_ext[ext]
19 return @@languages_by_ext[ext]
20 else
20 else
21 return nil
21 return nil
22 end
22 end
23 end
23 end
24 end
24 end
@@ -1,60 +1,58
1 class Message < ActiveRecord::Base
1 class Message < ActiveRecord::Base
2
2
3 belongs_to :sender, :class_name => "User"
3 belongs_to :sender, :class_name => "User"
4 belongs_to :receiver, :class_name => "User"
4 belongs_to :receiver, :class_name => "User"
5
5
6 belongs_to :replying_message, :class_name => "Message"
6 belongs_to :replying_message, :class_name => "Message"
7
7
8 # commented manually do it
8 # commented manually do it
9 #
9 #
10 #has_many :replied_messages, {
10 #has_many :replied_messages, {
11 # :class_name => "Message",
11 # :class_name => "Message",
12 # :foreign_key => "replying_message_id"
12 # :foreign_key => "replying_message_id"
13 #}
13 #}
14 #
14 #
15
15
16 attr_accessor :replied_messages
16 attr_accessor :replied_messages
17
17
18 def self.find_all_sent_by_user(user)
18 def self.find_all_sent_by_user(user)
19 messages = user.messages
19 messages = user.messages
20 replied_messages = user.replied_messages
20 replied_messages = user.replied_messages
21 Message.build_replying_message_hierarchy messages, replied_messages
21 Message.build_replying_message_hierarchy messages, replied_messages
22 return messages
22 return messages
23 end
23 end
24
24
25 def self.find_all_system_unreplied_messages
25 def self.find_all_system_unreplied_messages
26 - self.find(:all,
26 + where('ISNULL(receiver_id) ' +
27 - :conditions => 'ISNULL(receiver_id) ' +
27 + 'AND (ISNULL(replied) OR replied=0)')
28 - 'AND (ISNULL(replied) OR replied=0)',
29 - :order => 'created_at')
30 end
28 end
31
29
32 def self.build_replying_message_hierarchy(*args)
30 def self.build_replying_message_hierarchy(*args)
33 # manually build replies hierarchy (to improve efficiency)
31 # manually build replies hierarchy (to improve efficiency)
34 all_messages = {}
32 all_messages = {}
35
33
36 args.each do |collection|
34 args.each do |collection|
37 collection.each do |m|
35 collection.each do |m|
38 all_messages[m.id] = m
36 all_messages[m.id] = m
39 m.replied_messages = []
37 m.replied_messages = []
40 end
38 end
41 end
39 end
42
40
43 all_messages.each_value do |m|
41 all_messages.each_value do |m|
44 rep_id = m.replying_message_id
42 rep_id = m.replying_message_id
45 if all_messages[rep_id]!=nil
43 if all_messages[rep_id]!=nil
46 all_messages[rep_id].add_replied_message(m)
44 all_messages[rep_id].add_replied_message(m)
47 end
45 end
48 end
46 end
49 end
47 end
50
48
51 def add_replied_message(m)
49 def add_replied_message(m)
52 if @replied_messages==nil
50 if @replied_messages==nil
53 @replied_messages = [m]
51 @replied_messages = [m]
54 else
52 else
55 @replied_messages << m
53 @replied_messages << m
56 end
54 end
57 @replied_messages
55 @replied_messages
58 end
56 end
59
57
60 end
58 end
@@ -1,66 +1,67
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 has_many :test_pairs, :dependent => :delete_all
5 has_many :test_pairs, :dependent => :delete_all
6 has_many :testcases, :dependent => :destroy
6 has_many :testcases, :dependent => :destroy
7
7
8 validates_presence_of :name
8 validates_presence_of :name
9 validates_format_of :name, :with => /\A\w+\z/
9 validates_format_of :name, :with => /\A\w+\z/
10 validates_presence_of :full_name
10 validates_presence_of :full_name
11
11
12 - scope :available, :conditions => {:available => true}
12 + scope :available, -> { where(available: true) }
13
13
14 DEFAULT_TIME_LIMIT = 1
14 DEFAULT_TIME_LIMIT = 1
15 DEFAULT_MEMORY_LIMIT = 32
15 DEFAULT_MEMORY_LIMIT = 32
16
16
17 - def self.find_available_problems
17 + def self.available_problems
18 - Problem.available.all(:order => "date_added DESC, name ASC")
18 + available.order(date_added: :desc).order(:name)
19 + #Problem.available.all(:order => "date_added DESC, name ASC")
19 end
20 end
20
21
21 def self.create_from_import_form_params(params, old_problem=nil)
22 def self.create_from_import_form_params(params, old_problem=nil)
22 org_problem = old_problem || Problem.new
23 org_problem = old_problem || Problem.new
23 import_params, problem = Problem.extract_params_and_check(params,
24 import_params, problem = Problem.extract_params_and_check(params,
24 org_problem)
25 org_problem)
25
26
26 if !problem.errors.empty?
27 if !problem.errors.empty?
27 return problem, 'Error importing'
28 return problem, 'Error importing'
28 end
29 end
29
30
30 problem.full_score = 100
31 problem.full_score = 100
31 problem.date_added = Time.new
32 problem.date_added = Time.new
32 problem.test_allowed = true
33 problem.test_allowed = true
33 problem.output_only = false
34 problem.output_only = false
34 problem.available = false
35 problem.available = false
35
36
36 if not problem.save
37 if not problem.save
37 return problem, 'Error importing'
38 return problem, 'Error importing'
38 end
39 end
39
40
40 import_to_db = params.has_key? :import_to_db
41 import_to_db = params.has_key? :import_to_db
41
42
42 importer = TestdataImporter.new(problem)
43 importer = TestdataImporter.new(problem)
43
44
44 if not importer.import_from_file(import_params[:file],
45 if not importer.import_from_file(import_params[:file],
45 import_params[:time_limit],
46 import_params[:time_limit],
46 import_params[:memory_limit],
47 import_params[:memory_limit],
47 import_params[:checker_name],
48 import_params[:checker_name],
48 import_to_db)
49 import_to_db)
49 problem.errors.add(:base,'Import error.')
50 problem.errors.add(:base,'Import error.')
50 end
51 end
51
52
52 return problem, importer.log_msg
53 return problem, importer.log_msg
53 end
54 end
54
55
55 def self.download_file_basedir
56 def self.download_file_basedir
56 return "#{Rails.root}/data/tasks"
57 return "#{Rails.root}/data/tasks"
57 end
58 end
58
59
59 def get_submission_stat
60 def get_submission_stat
60 result = Hash.new
61 result = Hash.new
61 #total number of submission
62 #total number of submission
62 result[:total_sub] = Submission.where(problem_id: self.id).count
63 result[:total_sub] = Submission.where(problem_id: self.id).count
63 result[:attempted_user] = Submission.where(problem_id: self.id).group_by(:user_id)
64 result[:attempted_user] = Submission.where(problem_id: self.id).group_by(:user_id)
64 end
65 end
65
66
66 def long_name
67 def long_name
@@ -1,116 +1,103
1 class Submission < ActiveRecord::Base
1 class Submission < ActiveRecord::Base
2
2
3 belongs_to :language
3 belongs_to :language
4 belongs_to :problem
4 belongs_to :problem
5 belongs_to :user
5 belongs_to :user
6
6
7 before_validation :assign_problem
7 before_validation :assign_problem
8 before_validation :assign_language
8 before_validation :assign_language
9
9
10 validates_presence_of :source
10 validates_presence_of :source
11 validates_length_of :source, :maximum => 100_000, :allow_blank => true, :message => 'too long'
11 validates_length_of :source, :maximum => 100_000, :allow_blank => true, :message => 'too long'
12 validates_length_of :source, :minimum => 1, :allow_blank => true, :message => 'too short'
12 validates_length_of :source, :minimum => 1, :allow_blank => true, :message => 'too short'
13 validate :must_have_valid_problem
13 validate :must_have_valid_problem
14 validate :must_specify_language
14 validate :must_specify_language
15
15
16 before_save :assign_latest_number_if_new_recond
16 before_save :assign_latest_number_if_new_recond
17
17
18 def self.find_last_by_user_and_problem(user_id, problem_id)
18 def self.find_last_by_user_and_problem(user_id, problem_id)
19 - last_sub = find(:first,
19 + where("user_id = ? AND problem_id = ?",user_id,problem_id).last
20 - :conditions => {:user_id => user_id,
21 - :problem_id => problem_id},
22 - :order => 'number DESC')
23 - return last_sub
24 end
20 end
25
21
26 def self.find_all_last_by_problem(problem_id)
22 def self.find_all_last_by_problem(problem_id)
27 # need to put in SQL command, maybe there's a better way
23 # need to put in SQL command, maybe there's a better way
28 Submission.includes(:user).find_by_sql("SELECT * FROM submissions " +
24 Submission.includes(:user).find_by_sql("SELECT * FROM submissions " +
29 "WHERE id = " +
25 "WHERE id = " +
30 "(SELECT MAX(id) FROM submissions AS subs " +
26 "(SELECT MAX(id) FROM submissions AS subs " +
31 "WHERE subs.user_id = submissions.user_id AND " +
27 "WHERE subs.user_id = submissions.user_id AND " +
32 "problem_id = " + problem_id.to_s + " " +
28 "problem_id = " + problem_id.to_s + " " +
33 "GROUP BY user_id) " +
29 "GROUP BY user_id) " +
34 "ORDER BY user_id")
30 "ORDER BY user_id")
35 end
31 end
36
32
37 def self.find_in_range_by_user_and_problem(user_id, problem_id,since_id,until_id)
33 def self.find_in_range_by_user_and_problem(user_id, problem_id,since_id,until_id)
38 records = Submission.where(problem_id: problem_id,user_id: user_id)
34 records = Submission.where(problem_id: problem_id,user_id: user_id)
39 records = records.where('id >= ?',since_id) if since_id > 0
35 records = records.where('id >= ?',since_id) if since_id > 0
40 records = records.where('id <= ?',until_id) if until_id > 0
36 records = records.where('id <= ?',until_id) if until_id > 0
41 records.all
37 records.all
42 end
38 end
43
39
44 def self.find_last_for_all_available_problems(user_id)
40 def self.find_last_for_all_available_problems(user_id)
45 submissions = Array.new
41 submissions = Array.new
46 - problems = Problem.find_available_problems
42 + problems = Problem.available_problems
47 problems.each do |problem|
43 problems.each do |problem|
48 sub = Submission.find_last_by_user_and_problem(user_id, problem.id)
44 sub = Submission.find_last_by_user_and_problem(user_id, problem.id)
49 submissions << sub if sub!=nil
45 submissions << sub if sub!=nil
50 end
46 end
51 submissions
47 submissions
52 end
48 end
53
49
54 def self.find_by_user_problem_number(user_id, problem_id, number)
50 def self.find_by_user_problem_number(user_id, problem_id, number)
55 - Submission.find(:first,
51 + where("user_id = ? AND problem_id = ? AND number = ?",user_id,problem_id,number).first
56 - :conditions => {
57 - :user_id => user_id,
58 - :problem_id => problem_id,
59 - :number => number
60 - })
61 end
52 end
62
53
63 def self.find_all_by_user_problem(user_id, problem_id)
54 def self.find_all_by_user_problem(user_id, problem_id)
64 - Submission.find(:all,
55 + where("user_id = ? AND problem_id = ?",user_id,problem_id)
65 - :conditions => {
66 - :user_id => user_id,
67 - :problem_id => problem_id,
68 - })
69 end
56 end
70
57
71 def download_filename
58 def download_filename
72 if self.problem.output_only
59 if self.problem.output_only
73 return self.source_filename
60 return self.source_filename
74 else
61 else
75 timestamp = self.submitted_at.localtime.strftime("%H%M%S")
62 timestamp = self.submitted_at.localtime.strftime("%H%M%S")
76 return "#{self.problem.name}-#{timestamp}.#{self.language.ext}"
63 return "#{self.problem.name}-#{timestamp}.#{self.language.ext}"
77 end
64 end
78 end
65 end
79
66
80 protected
67 protected
81
68
82 def self.find_option_in_source(option, source)
69 def self.find_option_in_source(option, source)
83 if source==nil
70 if source==nil
84 return nil
71 return nil
85 end
72 end
86 i = 0
73 i = 0
87 source.each_line do |s|
74 source.each_line do |s|
88 if s =~ option
75 if s =~ option
89 words = s.split
76 words = s.split
90 return words[1]
77 return words[1]
91 end
78 end
92 i = i + 1
79 i = i + 1
93 if i==10
80 if i==10
94 return nil
81 return nil
95 end
82 end
96 end
83 end
97 return nil
84 return nil
98 end
85 end
99
86
100 def self.find_language_in_source(source, source_filename="")
87 def self.find_language_in_source(source, source_filename="")
101 langopt = find_option_in_source(/^LANG:/,source)
88 langopt = find_option_in_source(/^LANG:/,source)
102 if langopt
89 if langopt
103 return (Language.find_by_name(langopt) ||
90 return (Language.find_by_name(langopt) ||
104 Language.find_by_pretty_name(langopt))
91 Language.find_by_pretty_name(langopt))
105 else
92 else
106 if source_filename
93 if source_filename
107 return Language.find_by_extension(source_filename.split('.').last)
94 return Language.find_by_extension(source_filename.split('.').last)
108 else
95 else
109 return nil
96 return nil
110 end
97 end
111 end
98 end
112 end
99 end
113
100
114 def self.find_problem_in_source(source, source_filename="")
101 def self.find_problem_in_source(source, source_filename="")
115 prob_opt = find_option_in_source(/^TASK:/,source)
102 prob_opt = find_option_in_source(/^TASK:/,source)
116 if problem = Problem.find_by_name(prob_opt)
103 if problem = Problem.find_by_name(prob_opt)
@@ -3,66 +3,63
3 belongs_to :submission
3 belongs_to :submission
4
4
5 STATUS_GRADING = 0
5 STATUS_GRADING = 0
6 STATUS_INQUEUE = 1
6 STATUS_INQUEUE = 1
7 STATUS_COMPLETE = 2
7 STATUS_COMPLETE = 2
8
8
9 def status_inqueue
9 def status_inqueue
10 self.status = Task::STATUS_INQUEUE
10 self.status = Task::STATUS_INQUEUE
11 end
11 end
12
12
13 def status_inqueue!
13 def status_inqueue!
14 status_inqueue
14 status_inqueue
15 self.save
15 self.save
16 end
16 end
17
17
18 def status_grading
18 def status_grading
19 self.status = Task::STATUS_GRADING
19 self.status = Task::STATUS_GRADING
20 end
20 end
21
21
22 def status_grading!
22 def status_grading!
23 status_grading
23 status_grading
24 self.save
24 self.save
25 end
25 end
26
26
27 def status_complete
27 def status_complete
28 self.status = Task::STATUS_COMPLETE
28 self.status = Task::STATUS_COMPLETE
29 end
29 end
30
30
31 def status_complete!
31 def status_complete!
32 status_complete
32 status_complete
33 self.save
33 self.save
34 end
34 end
35
35
36 def status_str
36 def status_str
37 case self.status
37 case self.status
38 when Task::STATUS_INQUEUE
38 when Task::STATUS_INQUEUE
39 "inqueue"
39 "inqueue"
40 when Task::STATUS_GRADING
40 when Task::STATUS_GRADING
41 "grading"
41 "grading"
42 when Task::STATUS_COMPLETE
42 when Task::STATUS_COMPLETE
43 "complete"
43 "complete"
44 end
44 end
45 end
45 end
46
46
47 def self.get_inqueue_and_change_status(status)
47 def self.get_inqueue_and_change_status(status)
48 task = nil
48 task = nil
49 begin
49 begin
50 Task.transaction do
50 Task.transaction do
51 - task = Task.find(:first,
51 + task = Task.where(status: Task::STATUS_INQUEUE).where(lock: true).first
52 - :order => "created_at",
53 - :conditions => {:status=> Task::STATUS_INQUEUE},
54 - :lock => true)
55 if task!=nil
52 if task!=nil
56 task.status = status
53 task.status = status
57 task.save!
54 task.save!
58 end
55 end
59 end
56 end
60
57
61 rescue
58 rescue
62 task = nil
59 task = nil
63
60
64 end
61 end
65 task
62 task
66 end
63 end
67
64
68 end
65 end
@@ -1,90 +1,88
1 #
1 #
2 # A TestRequest is a composition of submission with user's testdata.
2 # A TestRequest is a composition of submission with user's testdata.
3 #
3 #
4 # Note about TestRequest#problem: Usually, A TestRequest has to be
4 # Note about TestRequest#problem: Usually, A TestRequest has to be
5 # associated with a problem, so that execution environment can be
5 # associated with a problem, so that execution environment can be
6 # determined. However, to be more flexible, we have to ensure that
6 # determined. However, to be more flexible, we have to ensure that
7 # it works as well with problem=nil. In this case, we shall provide
7 # it works as well with problem=nil. In this case, we shall provide
8 # a "default" execution environment for it. This can be done
8 # a "default" execution environment for it. This can be done
9 # seamlessly by using TestRequest#problem_name or
9 # seamlessly by using TestRequest#problem_name or
10 # TestRequest#name_of(problem) when retrieving the name of the
10 # TestRequest#name_of(problem) when retrieving the name of the
11 # problem: #name_of would return problem.name when problem!=nil and
11 # problem: #name_of would return problem.name when problem!=nil and
12 # it would return "default" when problem=nil, #problem_name just
12 # it would return "default" when problem=nil, #problem_name just
13 # call #name_of.
13 # call #name_of.
14 #
14 #
15
15
16 require 'fileutils'
16 require 'fileutils'
17
17
18 class TestRequest < Task
18 class TestRequest < Task
19 self.table_name = "test_requests"
19 self.table_name = "test_requests"
20
20
21 belongs_to :user
21 belongs_to :user
22 belongs_to :problem
22 belongs_to :problem
23 belongs_to :submission
23 belongs_to :submission
24
24
25 validates_presence_of :submission
25 validates_presence_of :submission
26 validate :must_have_valid_problem
26 validate :must_have_valid_problem
27
27
28 def problem_name
28 def problem_name
29 TestRequest.name_of(self.problem)
29 TestRequest.name_of(self.problem)
30 end
30 end
31
31
32 def language
32 def language
33 self.submission.language
33 self.submission.language
34 end
34 end
35
35
36 def self.get_inqueue_and_change_status(status)
36 def self.get_inqueue_and_change_status(status)
37 # since there will be only one grader grading TestRequest
37 # since there will be only one grader grading TestRequest
38 # we do not need locking (hopefully)
38 # we do not need locking (hopefully)
39
39
40 - test_request = TestRequest.find(:first,
40 + test_request = TestRequest.where(status: Task::STATUS_INQUEUE).first
41 - :order => "created_at",
42 - :conditions => {:status=> Task::STATUS_INQUEUE})
43 if test_request!=nil
41 if test_request!=nil
44 test_request.status = status
42 test_request.status = status
45 test_request.save!
43 test_request.save!
46 end
44 end
47
45
48 test_request
46 test_request
49 end
47 end
50
48
51 # interfacing with form
49 # interfacing with form
52 def self.new_from_form_params(user,params)
50 def self.new_from_form_params(user,params)
53 test_request = TestRequest.new
51 test_request = TestRequest.new
54 test_request.user = user
52 test_request.user = user
55 begin
53 begin
56 problem = Problem.find(params[:problem_id])
54 problem = Problem.find(params[:problem_id])
57 rescue ActiveRecord::RecordNotFound
55 rescue ActiveRecord::RecordNotFound
58 problem = nil
56 problem = nil
59 end
57 end
60 test_request.problem = problem
58 test_request.problem = problem
61 if problem!=nil
59 if problem!=nil
62 test_request.submission =
60 test_request.submission =
63 Submission.find_by_user_problem_number(user.id,
61 Submission.find_by_user_problem_number(user.id,
64 problem.id,
62 problem.id,
65 params[:submission_number])
63 params[:submission_number])
66 else
64 else
67 test_request.submission = nil
65 test_request.submission = nil
68 end
66 end
69
67
70 # checks if the user submits any input file
68 # checks if the user submits any input file
71 if params[:input_file]==nil or params[:input_file]==""
69 if params[:input_file]==nil or params[:input_file]==""
72 test_request.errors.add(:base,"No input submitted.")
70 test_request.errors.add(:base,"No input submitted.")
73 test_request.input_file_name = nil
71 test_request.input_file_name = nil
74 else
72 else
75 test_request.input_file_name = save_input_file(params[:input_file], user, problem)
73 test_request.input_file_name = save_input_file(params[:input_file], user, problem)
76 if test_request.input_file_name == nil
74 if test_request.input_file_name == nil
77 test_request.errors.adds(:base,"No input submitted.")
75 test_request.errors.adds(:base,"No input submitted.")
78 end
76 end
79 if params[:additional_file]!=nil and params[:additional_file]!=""
77 if params[:additional_file]!=nil and params[:additional_file]!=""
80 save_additional_file(params[:additional_file],
78 save_additional_file(params[:additional_file],
81 "#{test_request.input_file_name}.files")
79 "#{test_request.input_file_name}.files")
82 end
80 end
83 end
81 end
84 test_request.submitted_at = Time.new.gmtime
82 test_request.submitted_at = Time.new.gmtime
85 test_request.status_inqueue
83 test_request.status_inqueue
86 test_request
84 test_request
87 end
85 end
88
86
89 protected
87 protected
90
88
@@ -130,104 +130,104
130
130
131 def email_for_editing
131 def email_for_editing
132 if self.email==nil
132 if self.email==nil
133 "(unknown)"
133 "(unknown)"
134 elsif self.email==''
134 elsif self.email==''
135 "(blank)"
135 "(blank)"
136 else
136 else
137 self.email
137 self.email
138 end
138 end
139 end
139 end
140
140
141 def email_for_editing=(e)
141 def email_for_editing=(e)
142 self.email=e
142 self.email=e
143 end
143 end
144
144
145 def alias_for_editing
145 def alias_for_editing
146 if self.alias==nil
146 if self.alias==nil
147 "(unknown)"
147 "(unknown)"
148 elsif self.alias==''
148 elsif self.alias==''
149 "(blank)"
149 "(blank)"
150 else
150 else
151 self.alias
151 self.alias
152 end
152 end
153 end
153 end
154
154
155 def alias_for_editing=(e)
155 def alias_for_editing=(e)
156 self.alias=e
156 self.alias=e
157 end
157 end
158
158
159 def activation_key
159 def activation_key
160 if self.hashed_password==nil
160 if self.hashed_password==nil
161 encrypt_new_password
161 encrypt_new_password
162 end
162 end
163 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
163 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
164 end
164 end
165
165
166 def verify_activation_key(key)
166 def verify_activation_key(key)
167 key == activation_key
167 key == activation_key
168 end
168 end
169
169
170 def self.random_password(length=5)
170 def self.random_password(length=5)
171 chars = 'abcdefghjkmnopqrstuvwxyz'
171 chars = 'abcdefghjkmnopqrstuvwxyz'
172 password = ''
172 password = ''
173 length.times { password << chars[rand(chars.length - 1)] }
173 length.times { password << chars[rand(chars.length - 1)] }
174 password
174 password
175 end
175 end
176
176
177 def self.find_non_admin_with_prefix(prefix='')
177 def self.find_non_admin_with_prefix(prefix='')
178 - users = User.find(:all)
178 + users = User.all
179 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
179 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
180 end
180 end
181
181
182 # Contest information
182 # Contest information
183
183
184 def self.find_users_with_no_contest()
184 def self.find_users_with_no_contest()
185 - users = User.find(:all)
185 + users = User.all
186 return users.find_all { |u| u.contests.length == 0 }
186 return users.find_all { |u| u.contests.length == 0 }
187 end
187 end
188
188
189
189
190 def contest_time_left
190 def contest_time_left
191 if GraderConfiguration.contest_mode?
191 if GraderConfiguration.contest_mode?
192 return nil if site==nil
192 return nil if site==nil
193 return site.time_left
193 return site.time_left
194 elsif GraderConfiguration.indv_contest_mode?
194 elsif GraderConfiguration.indv_contest_mode?
195 time_limit = GraderConfiguration.contest_time_limit
195 time_limit = GraderConfiguration.contest_time_limit
196 if time_limit == nil
196 if time_limit == nil
197 return nil
197 return nil
198 end
198 end
199 if contest_stat==nil or contest_stat.started_at==nil
199 if contest_stat==nil or contest_stat.started_at==nil
200 return (Time.now.gmtime + time_limit) - Time.now.gmtime
200 return (Time.now.gmtime + time_limit) - Time.now.gmtime
201 else
201 else
202 finish_time = contest_stat.started_at + time_limit
202 finish_time = contest_stat.started_at + time_limit
203 current_time = Time.now.gmtime
203 current_time = Time.now.gmtime
204 if current_time > finish_time
204 if current_time > finish_time
205 return 0
205 return 0
206 else
206 else
207 return finish_time - current_time
207 return finish_time - current_time
208 end
208 end
209 end
209 end
210 else
210 else
211 return nil
211 return nil
212 end
212 end
213 end
213 end
214
214
215 def contest_finished?
215 def contest_finished?
216 if GraderConfiguration.contest_mode?
216 if GraderConfiguration.contest_mode?
217 return false if site==nil
217 return false if site==nil
218 return site.finished?
218 return site.finished?
219 elsif GraderConfiguration.indv_contest_mode?
219 elsif GraderConfiguration.indv_contest_mode?
220 return false if self.contest_stat(true)==nil
220 return false if self.contest_stat(true)==nil
221 return contest_time_left == 0
221 return contest_time_left == 0
222 else
222 else
223 return false
223 return false
224 end
224 end
225 end
225 end
226
226
227 def contest_started?
227 def contest_started?
228 if GraderConfiguration.indv_contest_mode?
228 if GraderConfiguration.indv_contest_mode?
229 stat = self.contest_stat
229 stat = self.contest_stat
230 return ((stat != nil) and (stat.started_at != nil))
230 return ((stat != nil) and (stat.started_at != nil))
231 elsif GraderConfiguration.contest_mode?
231 elsif GraderConfiguration.contest_mode?
232 return true if site==nil
232 return true if site==nil
233 return site.started
233 return site.started
@@ -236,97 +236,97
236 end
236 end
237 end
237 end
238
238
239 def update_start_time
239 def update_start_time
240 stat = self.contest_stat
240 stat = self.contest_stat
241 if stat.nil? or stat.started_at.nil?
241 if stat.nil? or stat.started_at.nil?
242 stat ||= UserContestStat.new(:user => self)
242 stat ||= UserContestStat.new(:user => self)
243 stat.started_at = Time.now.gmtime
243 stat.started_at = Time.now.gmtime
244 stat.save
244 stat.save
245 end
245 end
246 end
246 end
247
247
248 def problem_in_user_contests?(problem)
248 def problem_in_user_contests?(problem)
249 problem_contests = problem.contests.all
249 problem_contests = problem.contests.all
250
250
251 if problem_contests.length == 0 # this is public contest
251 if problem_contests.length == 0 # this is public contest
252 return true
252 return true
253 end
253 end
254
254
255 contests.each do |contest|
255 contests.each do |contest|
256 if problem_contests.find {|c| c.id == contest.id }
256 if problem_contests.find {|c| c.id == contest.id }
257 return true
257 return true
258 end
258 end
259 end
259 end
260 return false
260 return false
261 end
261 end
262
262
263 def available_problems_group_by_contests
263 def available_problems_group_by_contests
264 contest_problems = []
264 contest_problems = []
265 pin = {}
265 pin = {}
266 contests.enabled.each do |contest|
266 contests.enabled.each do |contest|
267 available_problems = contest.problems.available
267 available_problems = contest.problems.available
268 contest_problems << {
268 contest_problems << {
269 :contest => contest,
269 :contest => contest,
270 :problems => available_problems
270 :problems => available_problems
271 }
271 }
272 available_problems.each {|p| pin[p.id] = true}
272 available_problems.each {|p| pin[p.id] = true}
273 end
273 end
274 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
274 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
275 contest_problems << {
275 contest_problems << {
276 :contest => nil,
276 :contest => nil,
277 :problems => other_avaiable_problems
277 :problems => other_avaiable_problems
278 }
278 }
279 return contest_problems
279 return contest_problems
280 end
280 end
281
281
282 def available_problems
282 def available_problems
283 if not GraderConfiguration.multicontests?
283 if not GraderConfiguration.multicontests?
284 - return Problem.find_available_problems
284 + return Problem.available_problems
285 else
285 else
286 contest_problems = []
286 contest_problems = []
287 pin = {}
287 pin = {}
288 contests.enabled.each do |contest|
288 contests.enabled.each do |contest|
289 contest.problems.available.each do |problem|
289 contest.problems.available.each do |problem|
290 if not pin.has_key? problem.id
290 if not pin.has_key? problem.id
291 contest_problems << problem
291 contest_problems << problem
292 end
292 end
293 pin[problem.id] = true
293 pin[problem.id] = true
294 end
294 end
295 end
295 end
296 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
296 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
297 return contest_problems + other_avaiable_problems
297 return contest_problems + other_avaiable_problems
298 end
298 end
299 end
299 end
300
300
301 def can_view_problem?(problem)
301 def can_view_problem?(problem)
302 if not GraderConfiguration.multicontests?
302 if not GraderConfiguration.multicontests?
303 return problem.available
303 return problem.available
304 else
304 else
305 return problem_in_user_contests? problem
305 return problem_in_user_contests? problem
306 end
306 end
307 end
307 end
308
308
309 def self.clear_last_login
309 def self.clear_last_login
310 User.update_all(:last_ip => nil)
310 User.update_all(:last_ip => nil)
311 end
311 end
312
312
313 protected
313 protected
314 def encrypt_new_password
314 def encrypt_new_password
315 return if password.blank?
315 return if password.blank?
316 self.salt = (10+rand(90)).to_s
316 self.salt = (10+rand(90)).to_s
317 self.hashed_password = User.encrypt(self.password,self.salt)
317 self.hashed_password = User.encrypt(self.password,self.salt)
318 end
318 end
319
319
320 def assign_default_site
320 def assign_default_site
321 # have to catch error when migrating (because self.site is not available).
321 # have to catch error when migrating (because self.site is not available).
322 begin
322 begin
323 if self.site==nil
323 if self.site==nil
324 self.site = Site.find_by_name('default')
324 self.site = Site.find_by_name('default')
325 if self.site==nil
325 if self.site==nil
326 self.site = Site.find(1) # when 'default has be renamed'
326 self.site = Site.find(1) # when 'default has be renamed'
327 end
327 end
328 end
328 end
329 rescue
329 rescue
330 end
330 end
331 end
331 end
332
332
@@ -1,34 +1,34
1 %table.table.sortable.table-striped.table-bordered.table-condensed
1 %table.table.sortable.table-striped.table-bordered.table-condensed
2 %thead
2 %thead
3 %tr
3 %tr
4 %th Login
4 %th Login
5 %th Name
5 %th Name
6 / %th Activated?
6 / %th Activated?
7 / %th Logged_in
7 / %th Logged_in
8 / %th Contest(s)
8 / %th Contest(s)
9 %th Remark
9 %th Remark
10 - @problems.each do |p|
10 - @problems.each do |p|
11 %th.text-right= p.name.gsub('_',' ')
11 %th.text-right= p.name.gsub('_',' ')
12 %th.text-right Total
12 %th.text-right Total
13 %th.text-right Passed
13 %th.text-right Passed
14 %tbody
14 %tbody
15 - @scorearray.each do |sc|
15 - @scorearray.each do |sc|
16 %tr
16 %tr
17 - total,num_passed = 0,0
17 - total,num_passed = 0,0
18 - sc.each_index do |i|
18 - sc.each_index do |i|
19 - if i == 0
19 - if i == 0
20 - %td= link_to sc[i].login, controller: 'users', action: 'profile', id: sc[i]
20 + %td= link_to sc[i].login, stat_user_path(sc[i])
21 %td= sc[i].full_name
21 %td= sc[i].full_name
22 / %td= sc[i].activated
22 / %td= sc[i].activated
23 / %td= sc[i].try(:contest_stat).try(:started_at) ? 'yes' : 'no'
23 / %td= sc[i].try(:contest_stat).try(:started_at) ? 'yes' : 'no'
24 / %td= sc[i].contests.collect {|c| c.name}.join(', ')
24 / %td= sc[i].contests.collect {|c| c.name}.join(', ')
25 %td= sc[i].remark
25 %td= sc[i].remark
26 - else
26 - else
27 %td.text-right= sc[i][0]
27 %td.text-right= sc[i][0]
28 - total += sc[i][0]
28 - total += sc[i][0]
29 - num_passed += 1 if sc[i][1]
29 - num_passed += 1 if sc[i][1]
30 %td.text-right= total
30 %td.text-right= total
31 %td.text-right= num_passed
31 %td.text-right= num_passed
32
32
33 :javascript
33 :javascript
34 $.bootstrapSortable(true,'reversed')
34 $.bootstrapSortable(true,'reversed')
@@ -1,18 +1,18
1 ENV["RAILS_ENV"] = "test"
1 ENV["RAILS_ENV"] = "test"
2 require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")
2 require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")
3
3
4 def clear_all_tasks
4 def clear_all_tasks
5 - Task.find(:all).each do |task|
5 + Task.all.each do |task|
6 task.destroy
6 task.destroy
7 end
7 end
8 end
8 end
9
9
10
10
11 clear_all_tasks
11 clear_all_tasks
12
12
13 (1..1000).each do |i|
13 (1..1000).each do |i|
14 Task.create(:id => i,
14 Task.create(:id => i,
15 :submission_id => i,
15 :submission_id => i,
16 :status => Task::STATUS_INQUEUE)
16 :status => Task::STATUS_INQUEUE)
17 end
17 end
18
18
@@ -1,14 +1,13
1 ENV["RAILS_ENV"] = "test"
1 ENV["RAILS_ENV"] = "test"
2 require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")
2 require File.expand_path(File.dirname(__FILE__) + "/../../config/environment")
3
3
4 def clear_all_tasks
4 def clear_all_tasks
5 - Task.find(:all).each do |task|
5 + Task.all.each do |task|
6 task.destroy
6 task.destroy
7 end
7 end
8 end
8 end
9
9
10 - puts Task.find(:all,
10 + puts Task.where(status: Task::STATUS_COMPLETE).length
11 - :conditions => {:status => Task::STATUS_COMPLETE}).length
12
11
13 clear_all_tasks
12 clear_all_tasks
14
13
You need to be logged in to leave comments. Login now