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

r649:3cb38436f7f6 - - 6 files changed: 41 inserted, 3 deleted

@@ -0,0 +1,9
1 + class AddHeartBeatFull < ActiveRecord::Migration
2 + def up
3 + GraderConfiguration.create key: 'right.heartbeat_response_full', value_type: 'string', value:'RESTART', description:'Heart beat response text when user got full score (set this value to the empty string to disable this feature)'
4 + end
5 +
6 + def down
7 +
8 + end
9 + end
@@ -1,31 +1,46
1 1 class HeartbeatController < ApplicationController
2 2 before_filter :admin_authorization, :only => ['index']
3 3
4 4 def edit
5 5 #@user = User.find_by_login(params[:id])
6 6 #unless @user
7 7 # render text: "LOGIN_NOT_FOUND"
8 8 # return
9 9 #end
10 10
11 11 #hb = HeartBeat.where(user_id: @user.id, ip_address: request.remote_ip).first
12 12 #puts "status = #{params[:status]}"
13 13 #if hb
14 14 # if params[:status]
15 15 # hb.status = params[:status]
16 16 # hb.save
17 17 # end
18 18 # hb.touch
19 19 #else
20 20 # HeartBeat.creae(user_id: @user.id, ip_address: request.remote_ip)
21 21 #end
22 22 #HeartBeat.create(user_id: @user.id, ip_address: request.remote_ip, status: params[:status])
23 23
24 + res = GraderConfiguration['right.heartbeat_response']
25 + res.strip! if res
26 + full = GraderConfiguration['right.heartbeat_response_full']
27 + full.strip! if full
28 +
29 + if full and full != ''
30 + l = Login.where(ip_address: request.remote_ip).last
31 + @user = l.user
32 + if @user.solve_all_available_problems?
33 + render text: (full || 'OK')
34 + else
35 + render text: (res || 'OK')
36 + end
37 + else
24 38 render text: (GraderConfiguration['right.heartbeat_response'] || 'OK')
25 39 end
40 + end
26 41
27 42 def index
28 43 @hb = HeartBeat.where("updated_at >= ?",Time.zone.now-2.hours).includes(:user).order(:user_id).all
29 44 @num = HeartBeat.where("updated_at >= ?",Time.zone.now-5.minutes).count(:user_id,distinct: true)
30 45 end
31 46 end
@@ -90,290 +90,299
90 90 pop.finish
91 91 return true
92 92 rescue
93 93 return false
94 94 end
95 95 end
96 96
97 97 def authenticated_by_cucas?(password)
98 98 url = URI.parse('https://www.cas.chula.ac.th/cas/api/?q=studentAuthenticate')
99 99 appid = '41508763e340d5858c00f8c1a0f5a2bb'
100 100 appsecret ='d9cbb5863091dbe186fded85722a1e31'
101 101 post_args = {
102 102 'appid' => appid,
103 103 'appsecret' => appsecret,
104 104 'username' => login,
105 105 'password' => password
106 106 }
107 107
108 108 #simple call
109 109 begin
110 110 http = Net::HTTP.new('www.cas.chula.ac.th', 443)
111 111 http.use_ssl = true
112 112 http.verify_mode = OpenSSL::SSL::VERIFY_NONE
113 113 result = [ ]
114 114 http.start do |http|
115 115 req = Net::HTTP::Post.new('/cas/api/?q=studentAuthenticate')
116 116 param = "appid=#{appid}&appsecret=#{appsecret}&username=#{login}&password=#{password}"
117 117 resp = http.request(req,param)
118 118 result = JSON.parse resp.body
119 119 end
120 120 return true if result["type"] == "beanStudent"
121 121 rescue => e
122 122 return false
123 123 end
124 124 return false
125 125 end
126 126
127 127 def admin?
128 128 self.roles.detect {|r| r.name == 'admin' }
129 129 end
130 130
131 131 def email_for_editing
132 132 if self.email==nil
133 133 "(unknown)"
134 134 elsif self.email==''
135 135 "(blank)"
136 136 else
137 137 self.email
138 138 end
139 139 end
140 140
141 141 def email_for_editing=(e)
142 142 self.email=e
143 143 end
144 144
145 145 def alias_for_editing
146 146 if self.alias==nil
147 147 "(unknown)"
148 148 elsif self.alias==''
149 149 "(blank)"
150 150 else
151 151 self.alias
152 152 end
153 153 end
154 154
155 155 def alias_for_editing=(e)
156 156 self.alias=e
157 157 end
158 158
159 159 def activation_key
160 160 if self.hashed_password==nil
161 161 encrypt_new_password
162 162 end
163 163 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
164 164 end
165 165
166 166 def verify_activation_key(key)
167 167 key == activation_key
168 168 end
169 169
170 170 def self.random_password(length=5)
171 171 chars = 'abcdefghjkmnopqrstuvwxyz'
172 172 password = ''
173 173 length.times { password << chars[rand(chars.length - 1)] }
174 174 password
175 175 end
176 176
177 177 def self.find_non_admin_with_prefix(prefix='')
178 178 users = User.all
179 179 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
180 180 end
181 181
182 182 # Contest information
183 183
184 184 def self.find_users_with_no_contest()
185 185 users = User.all
186 186 return users.find_all { |u| u.contests.length == 0 }
187 187 end
188 188
189 189
190 190 def contest_time_left
191 191 if GraderConfiguration.contest_mode?
192 192 return nil if site==nil
193 193 return site.time_left
194 194 elsif GraderConfiguration.indv_contest_mode?
195 195 time_limit = GraderConfiguration.contest_time_limit
196 196 if time_limit == nil
197 197 return nil
198 198 end
199 199 if contest_stat==nil or contest_stat.started_at==nil
200 200 return (Time.now.gmtime + time_limit) - Time.now.gmtime
201 201 else
202 202 finish_time = contest_stat.started_at + time_limit
203 203 current_time = Time.now.gmtime
204 204 if current_time > finish_time
205 205 return 0
206 206 else
207 207 return finish_time - current_time
208 208 end
209 209 end
210 210 else
211 211 return nil
212 212 end
213 213 end
214 214
215 215 def contest_finished?
216 216 if GraderConfiguration.contest_mode?
217 217 return false if site==nil
218 218 return site.finished?
219 219 elsif GraderConfiguration.indv_contest_mode?
220 220 return false if self.contest_stat(true)==nil
221 221 return contest_time_left == 0
222 222 else
223 223 return false
224 224 end
225 225 end
226 226
227 227 def contest_started?
228 228 if GraderConfiguration.indv_contest_mode?
229 229 stat = self.contest_stat
230 230 return ((stat != nil) and (stat.started_at != nil))
231 231 elsif GraderConfiguration.contest_mode?
232 232 return true if site==nil
233 233 return site.started
234 234 else
235 235 return true
236 236 end
237 237 end
238 238
239 239 def update_start_time
240 240 stat = self.contest_stat
241 241 if stat.nil? or stat.started_at.nil?
242 242 stat ||= UserContestStat.new(:user => self)
243 243 stat.started_at = Time.now.gmtime
244 244 stat.save
245 245 end
246 246 end
247 247
248 248 def problem_in_user_contests?(problem)
249 249 problem_contests = problem.contests.all
250 250
251 251 if problem_contests.length == 0 # this is public contest
252 252 return true
253 253 end
254 254
255 255 contests.each do |contest|
256 256 if problem_contests.find {|c| c.id == contest.id }
257 257 return true
258 258 end
259 259 end
260 260 return false
261 261 end
262 262
263 263 def available_problems_group_by_contests
264 264 contest_problems = []
265 265 pin = {}
266 266 contests.enabled.each do |contest|
267 267 available_problems = contest.problems.available
268 268 contest_problems << {
269 269 :contest => contest,
270 270 :problems => available_problems
271 271 }
272 272 available_problems.each {|p| pin[p.id] = true}
273 273 end
274 274 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
275 275 contest_problems << {
276 276 :contest => nil,
277 277 :problems => other_avaiable_problems
278 278 }
279 279 return contest_problems
280 280 end
281 281
282 + def solve_all_available_problems?
283 + available_problems.each do |p|
284 + u = self
285 + sub = Submission.find_last_by_user_and_problem(u.id,p.id)
286 + return false if !p or !sub or sub.points < p.full_score
287 + end
288 + return true
289 + end
290 +
282 291 def available_problems
283 292 if not GraderConfiguration.multicontests?
284 293 return Problem.available_problems
285 294 else
286 295 contest_problems = []
287 296 pin = {}
288 297 contests.enabled.each do |contest|
289 298 contest.problems.available.each do |problem|
290 299 if not pin.has_key? problem.id
291 300 contest_problems << problem
292 301 end
293 302 pin[problem.id] = true
294 303 end
295 304 end
296 305 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
297 306 return contest_problems + other_avaiable_problems
298 307 end
299 308 end
300 309
301 310 def can_view_problem?(problem)
302 311 if not GraderConfiguration.multicontests?
303 312 return problem.available
304 313 else
305 314 return problem_in_user_contests? problem
306 315 end
307 316 end
308 317
309 318 def self.clear_last_login
310 319 User.update_all(:last_ip => nil)
311 320 end
312 321
313 322 protected
314 323 def encrypt_new_password
315 324 return if password.blank?
316 325 self.salt = (10+rand(90)).to_s
317 326 self.hashed_password = User.encrypt(self.password,self.salt)
318 327 end
319 328
320 329 def assign_default_site
321 330 # have to catch error when migrating (because self.site is not available).
322 331 begin
323 332 if self.site==nil
324 333 self.site = Site.find_by_name('default')
325 334 if self.site==nil
326 335 self.site = Site.find(1) # when 'default has be renamed'
327 336 end
328 337 end
329 338 rescue
330 339 end
331 340 end
332 341
333 342 def assign_default_contest
334 343 # have to catch error when migrating (because self.site is not available).
335 344 begin
336 345 if self.contests.length == 0
337 346 default_contest = Contest.find_by_name(GraderConfiguration['contest.default_contest_name'])
338 347 if default_contest
339 348 self.contests = [default_contest]
340 349 end
341 350 end
342 351 rescue
343 352 end
344 353 end
345 354
346 355 def password_required?
347 356 self.hashed_password.blank? || !self.password.blank?
348 357 end
349 358
350 359 def self.encrypt(string,salt)
351 360 Digest::SHA1.hexdigest(salt + string)
352 361 end
353 362
354 363 def uniqueness_of_email_from_activated_users
355 364 user = User.activated_users.find_by_email(self.email)
356 365 if user and (user.login != self.login)
357 366 self.errors.add(:base,"Email has already been taken")
358 367 end
359 368 end
360 369
361 370 def enough_time_interval_between_same_email_registrations
362 371 return if !self.new_record?
363 372 return if self.activated
364 373 open_user = User.find_by_email(self.email,
365 374 :order => 'created_at DESC')
366 375 if open_user and open_user.created_at and
367 376 (open_user.created_at > Time.now.gmtime - 5.minutes)
368 377 self.errors.add(:base,"There are already unactivated registrations with this e-mail address (please wait for 5 minutes)")
369 378 end
370 379 end
371 380
372 381 def email_validation?
373 382 begin
374 383 return VALIDATE_USER_EMAILS
375 384 rescue
376 385 return false
377 386 end
378 387 end
379 388 end
@@ -1,100 +1,98
1 1 CafeGrader::Application.routes.draw do
2 2 get "sources/direct_edit"
3 3
4 4 root :to => 'main#login'
5 5
6 6 #logins
7 7 get 'login/login', to: 'login#login'
8 8
9 9 resources :contests
10 10
11 11 resources :sites
12 12
13 13 resources :announcements do
14 14 member do
15 15 get 'toggle','toggle_front'
16 16 end
17 17 end
18 18
19 19 resources :problems do
20 20 member do
21 21 get 'toggle'
22 22 get 'toggle_test'
23 23 get 'toggle_view_testcase'
24 24 get 'stat'
25 25 end
26 26 collection do
27 27 get 'turn_all_off'
28 28 get 'turn_all_on'
29 29 get 'import'
30 30 get 'manage'
31 31 end
32 32
33 33 end
34 34
35 35 resources :testcases, only: [] do
36 36 member do
37 37 get 'download_input'
38 38 get 'download_sol'
39 39 end
40 40 collection do
41 41 get 'show_problem/:problem_id(/:test_num)' => 'testcases#show_problem', as: 'show_problem'
42 42 end
43 43 end
44 44
45 45 resources :grader_configuration, controller: 'configurations'
46 46
47 47 resources :users do
48 48 member do
49 49 get 'toggle_activate', 'toggle_enable'
50 50 get 'stat'
51 51 end
52 52 end
53 53
54 54 resources :submissions do
55 55 member do
56 56 get 'download'
57 57 get 'compiler_msg'
58 58 get 'rejudge'
59 59 end
60 60 collection do
61 61 get 'prob/:problem_id', to: 'submissions#index', as: 'problem'
62 62 get 'direct_edit_problem/:problem_id', to: 'submissions#direct_edit_problem', as: 'direct_edit_problem'
63 63 get 'get_latest_submission_status/:uid/:pid', to: 'submissions#get_latest_submission_status', as: 'get_latest_submission_status'
64 64 end
65 65 end
66 66
67 67
68 68
69 69 #main
70 70 get "main/list"
71 71 get 'main/submission(/:id)', to: 'main#submission', as: 'main_submission'
72 72
73 73 #user admin
74 74 get 'user_admin/bulk_manage', to: 'user_admin#bulk_manage', as: 'bulk_manage_user_admin'
75 75
76 76 #report
77 77 get 'report/current_score', to: 'report#current_score', as: 'report_current_score'
78 78 get 'report/problem_hof(/:id)', to: 'report#problem_hof', as: 'report_problem_hof'
79 79 get "report/login"
80 80 get 'report/max_score', to: 'report#max_score', as: 'report_max_score'
81 81 post 'report/show_max_score', to: 'report#show_max_score', as: 'report_show_max_score'
82 82
83 83
84 84 #
85 85 get 'tasks/view/:file.:ext' => 'tasks#view'
86 86 get 'tasks/download/:id/:file.:ext' => 'tasks#download'
87 87 get 'heartbeat/:id/edit' => 'heartbeat#edit'
88 88
89 89 #grader
90 90 get 'graders/list', to: 'graders#list', as: 'grader_list'
91 91
92 92
93 - get 'heartbeat/:id/edit' => 'heartbeat#edit'
94 -
95 93 # See how all your routes lay out with "rake routes"
96 94
97 95 # This is a legacy wild controller route that's not recommended for RESTful applications.
98 96 # Note: This route will make all actions in every controller accessible via GET requests.
99 97 match ':controller(/:action(/:id))(.:format)', via: [:get, :post]
100 98 end
@@ -1,206 +1,206
1 1 # encoding: UTF-8
2 2 # This file is auto-generated from the current state of the database. Instead
3 3 # of editing this file, please use the migrations feature of Active Record to
4 4 # incrementally modify your database, and then regenerate this schema definition.
5 5 #
6 6 # Note that this schema.rb definition is the authoritative source for your
7 7 # database schema. If you need to create the application database on another
8 8 # system, you should be using db:schema:load, not running all the migrations
9 9 # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10 10 # you'll amass, the slower it'll run and the greater likelihood for issues).
11 11 #
12 12 # It's strongly recommended that you check this file into your version control system.
13 13
14 - ActiveRecord::Schema.define(version: 20170310110146) do
14 + ActiveRecord::Schema.define(version: 20170427070345) do
15 15
16 16 create_table "announcements", force: :cascade do |t|
17 17 t.string "author", limit: 255
18 18 t.text "body", limit: 65535
19 19 t.boolean "published"
20 20 t.datetime "created_at", null: false
21 21 t.datetime "updated_at", null: false
22 22 t.boolean "frontpage", default: false
23 23 t.boolean "contest_only", default: false
24 24 t.string "title", limit: 255
25 25 t.string "notes", limit: 255
26 26 end
27 27
28 28 create_table "contests", force: :cascade do |t|
29 29 t.string "title", limit: 255
30 30 t.boolean "enabled"
31 31 t.datetime "created_at", null: false
32 32 t.datetime "updated_at", null: false
33 33 t.string "name", limit: 255
34 34 end
35 35
36 36 create_table "contests_problems", id: false, force: :cascade do |t|
37 37 t.integer "contest_id", limit: 4
38 38 t.integer "problem_id", limit: 4
39 39 end
40 40
41 41 create_table "contests_users", id: false, force: :cascade do |t|
42 42 t.integer "contest_id", limit: 4
43 43 t.integer "user_id", limit: 4
44 44 end
45 45
46 46 create_table "countries", force: :cascade do |t|
47 47 t.string "name", limit: 255
48 48 t.datetime "created_at", null: false
49 49 t.datetime "updated_at", null: false
50 50 end
51 51
52 52 create_table "descriptions", force: :cascade do |t|
53 53 t.text "body", limit: 65535
54 54 t.boolean "markdowned"
55 55 t.datetime "created_at", null: false
56 56 t.datetime "updated_at", null: false
57 57 end
58 58
59 59 create_table "grader_configurations", force: :cascade do |t|
60 60 t.string "key", limit: 255
61 61 t.string "value_type", limit: 255
62 62 t.string "value", limit: 255
63 63 t.datetime "created_at", null: false
64 64 t.datetime "updated_at", null: false
65 65 t.text "description", limit: 65535
66 66 end
67 67
68 68 create_table "grader_processes", force: :cascade do |t|
69 69 t.string "host", limit: 255
70 70 t.integer "pid", limit: 4
71 71 t.string "mode", limit: 255
72 72 t.boolean "active"
73 73 t.datetime "created_at", null: false
74 74 t.datetime "updated_at", null: false
75 75 t.integer "task_id", limit: 4
76 76 t.string "task_type", limit: 255
77 77 t.boolean "terminated"
78 78 end
79 79
80 80 add_index "grader_processes", ["host", "pid"], name: "index_grader_processes_on_ip_and_pid", using: :btree
81 81
82 82 create_table "heart_beats", force: :cascade do |t|
83 83 t.integer "user_id", limit: 4
84 84 t.string "ip_address", limit: 255
85 85 t.datetime "created_at", null: false
86 86 t.datetime "updated_at", null: false
87 87 t.string "status", limit: 255
88 88 end
89 89
90 90 add_index "heart_beats", ["updated_at"], name: "index_heart_beats_on_updated_at", using: :btree
91 91
92 92 create_table "languages", force: :cascade do |t|
93 93 t.string "name", limit: 10
94 94 t.string "pretty_name", limit: 255
95 95 t.string "ext", limit: 10
96 96 t.string "common_ext", limit: 255
97 97 end
98 98
99 99 create_table "logins", force: :cascade do |t|
100 100 t.integer "user_id", limit: 4
101 101 t.string "ip_address", limit: 255
102 102 t.datetime "created_at", null: false
103 103 t.datetime "updated_at", null: false
104 104 end
105 105
106 106 create_table "messages", force: :cascade do |t|
107 107 t.integer "sender_id", limit: 4
108 108 t.integer "receiver_id", limit: 4
109 109 t.integer "replying_message_id", limit: 4
110 110 t.text "body", limit: 65535
111 111 t.boolean "replied"
112 112 t.datetime "created_at", null: false
113 113 t.datetime "updated_at", null: false
114 114 end
115 115
116 116 create_table "problems", force: :cascade do |t|
117 117 t.string "name", limit: 30
118 118 t.string "full_name", limit: 255
119 119 t.integer "full_score", limit: 4
120 120 t.date "date_added"
121 121 t.boolean "available"
122 122 t.string "url", limit: 255
123 123 t.integer "description_id", limit: 4
124 124 t.boolean "test_allowed"
125 125 t.boolean "output_only"
126 126 t.string "description_filename", limit: 255
127 127 t.boolean "view_testcase"
128 128 end
129 129
130 130 create_table "rights", force: :cascade do |t|
131 131 t.string "name", limit: 255
132 132 t.string "controller", limit: 255
133 133 t.string "action", limit: 255
134 134 end
135 135
136 136 create_table "rights_roles", id: false, force: :cascade do |t|
137 137 t.integer "right_id", limit: 4
138 138 t.integer "role_id", limit: 4
139 139 end
140 140
141 141 add_index "rights_roles", ["role_id"], name: "index_rights_roles_on_role_id", using: :btree
142 142
143 143 create_table "roles", force: :cascade do |t|
144 144 t.string "name", limit: 255
145 145 end
146 146
147 147 create_table "roles_users", id: false, force: :cascade do |t|
148 148 t.integer "role_id", limit: 4
149 149 t.integer "user_id", limit: 4
150 150 end
151 151
152 152 add_index "roles_users", ["user_id"], name: "index_roles_users_on_user_id", using: :btree
153 153
154 154 create_table "sessions", force: :cascade do |t|
155 155 t.string "session_id", limit: 255
156 156 t.text "data", limit: 65535
157 157 t.datetime "updated_at"
158 158 end
159 159
160 160 add_index "sessions", ["session_id"], name: "index_sessions_on_session_id", using: :btree
161 161 add_index "sessions", ["updated_at"], name: "index_sessions_on_updated_at", using: :btree
162 162
163 163 create_table "sites", force: :cascade do |t|
164 164 t.string "name", limit: 255
165 165 t.boolean "started"
166 166 t.datetime "start_time"
167 167 t.datetime "created_at", null: false
168 168 t.datetime "updated_at", null: false
169 169 t.integer "country_id", limit: 4
170 170 t.string "password", limit: 255
171 171 end
172 172
173 173 create_table "submission_view_logs", force: :cascade do |t|
174 174 t.integer "user_id", limit: 4
175 175 t.integer "submission_id", limit: 4
176 176 t.datetime "created_at", null: false
177 177 t.datetime "updated_at", null: false
178 178 end
179 179
180 180 create_table "submissions", force: :cascade do |t|
181 181 t.integer "user_id", limit: 4
182 182 t.integer "problem_id", limit: 4
183 183 t.integer "language_id", limit: 4
184 184 t.text "source", limit: 65535
185 185 t.binary "binary", limit: 65535
186 186 t.datetime "submitted_at"
187 187 t.datetime "compiled_at"
188 188 t.text "compiler_message", limit: 65535
189 189 t.datetime "graded_at"
190 190 t.integer "points", limit: 4
191 191 t.text "grader_comment", limit: 65535
192 192 t.integer "number", limit: 4
193 193 t.string "source_filename", limit: 255
194 194 t.float "max_runtime", limit: 24
195 195 t.integer "peak_memory", limit: 4
196 196 t.integer "effective_code_length", limit: 4
197 197 t.string "ip_address", limit: 255
198 198 end
199 199
200 200 add_index "submissions", ["user_id", "problem_id", "number"], name: "index_submissions_on_user_id_and_problem_id_and_number", unique: true, using: :btree
201 201 add_index "submissions", ["user_id", "problem_id"], name: "index_submissions_on_user_id_and_problem_id", using: :btree
202 202
203 203 create_table "tasks", force: :cascade do |t|
204 204 t.integer "submission_id", limit: 4
205 205 t.datetime "created_at"
206 206 t.integer "status", limit: 4
@@ -1,251 +1,258
1 1 CONFIGURATIONS =
2 2 [
3 3 {
4 4 :key => 'system.single_user_mode',
5 5 :value_type => 'boolean',
6 6 :default_value => 'false',
7 7 :description => 'Only admins can log in to the system when running under single user mode.'
8 8 },
9 9
10 10 {
11 11 :key => 'ui.front.title',
12 12 :value_type => 'string',
13 13 :default_value => 'Grader'
14 14 },
15 15
16 16 {
17 17 :key => 'ui.front.welcome_message',
18 18 :value_type => 'string',
19 19 :default_value => 'Welcome!'
20 20 },
21 21
22 22 {
23 23 :key => 'ui.show_score',
24 24 :value_type => 'boolean',
25 25 :default_value => 'true'
26 26 },
27 27
28 28 {
29 29 :key => 'contest.time_limit',
30 30 :value_type => 'string',
31 31 :default_value => 'unlimited',
32 32 :description => 'Time limit in format hh:mm, or "unlimited" for contests with no time limits. This config is CACHED. Restart the server before the change can take effect.'
33 33 },
34 34
35 35 {
36 36 :key => 'system.mode',
37 37 :value_type => 'string',
38 38 :default_value => 'standard',
39 39 :description => 'Current modes are "standard", "contest", "indv-contest", and "analysis".'
40 40 },
41 41
42 42 {
43 43 :key => 'contest.name',
44 44 :value_type => 'string',
45 45 :default_value => 'Grader',
46 46 :description => 'This name will be shown on the user header bar.'
47 47 },
48 48
49 49 {
50 50 :key => 'contest.multisites',
51 51 :value_type => 'boolean',
52 52 :default_value => 'false',
53 53 :description => 'If the server is in contest mode and this option is true, on the log in of the admin a menu for site selections is shown.'
54 54 },
55 55
56 56 #---------------------------- right --------------------------------
57 57 {
58 58 :key => 'right.user_hall_of_fame',
59 59 :value_type => 'boolean',
60 60 :default_value => 'false',
61 61 :description => 'If true, any user can access hall of fame page.'
62 62 },
63 63
64 64 {
65 65 :key => 'right.multiple_ip_login',
66 66 :value_type => 'boolean',
67 67 :default_value => 'true',
68 68 :description => 'When change from true to false, a user can login from the first IP they logged into afterward.'
69 69 },
70 70
71 71 {
72 72 :key => 'right.user_view_submission',
73 73 :value_type => 'boolean',
74 74 :default_value => 'false',
75 75 :description => 'If true, any user can view submissions of every one.'
76 76 },
77 77
78 78 {
79 79 :key => 'right.bypass_agreement',
80 80 :value_type => 'boolean',
81 81 :default_value => 'true',
82 82 :description => 'When false, a user must accept usage agreement before login'
83 83 },
84 84
85 85 {
86 86 :key => 'right.heartbeat_response',
87 87 :value_type => 'string',
88 88 :default_value => 'OK',
89 89 :description => 'Heart beat response text'
90 90 },
91 91
92 92 {
93 + :key => 'right.heartbeat_response_full',
94 + :value_type => 'string',
95 + :default_value => 'OK',
96 + :description => 'Heart beat response text when user got full score (set this value to the empty string to disable this feature)'
97 + },
98 +
99 + {
93 100 :key => 'right.view_testcase',
94 101 :value_type => 'boolean',
95 102 :default_value => 'false',
96 103 :description => 'When true, any user can view/download test data'
97 104 },
98 105 # If Configuration['system.online_registration'] is true, the
99 106 # system allows online registration, and will use these
100 107 # information for sending confirmation emails.
101 108 {
102 109 :key => 'system.online_registration.smtp',
103 110 :value_type => 'string',
104 111 :default_value => 'smtp.somehost.com'
105 112 },
106 113
107 114 {
108 115 :key => 'system.online_registration.from',
109 116 :value_type => 'string',
110 117 :default_value => 'your.email@address'
111 118 },
112 119
113 120 {
114 121 :key => 'system.admin_email',
115 122 :value_type => 'string',
116 123 :default_value => 'admin@admin.email'
117 124 },
118 125
119 126 {
120 127 :key => 'system.user_setting_enabled',
121 128 :value_type => 'boolean',
122 129 :default_value => 'true',
123 130 :description => 'If this option is true, users can change their settings'
124 131 },
125 132
126 133 {
127 134 :key => 'system.user_setting_enabled',
128 135 :value_type => 'boolean',
129 136 :default_value => 'true',
130 137 :description => 'If this option is true, users can change their settings'
131 138 },
132 139
133 140 # If Configuration['contest.test_request.early_timeout'] is true
134 141 # the user will not be able to use test request at 30 minutes
135 142 # before the contest ends.
136 143 {
137 144 :key => 'contest.test_request.early_timeout',
138 145 :value_type => 'boolean',
139 146 :default_value => 'false'
140 147 },
141 148
142 149 {
143 150 :key => 'system.multicontests',
144 151 :value_type => 'boolean',
145 152 :default_value => 'false'
146 153 },
147 154
148 155 {
149 156 :key => 'contest.confirm_indv_contest_start',
150 157 :value_type => 'boolean',
151 158 :default_value => 'false'
152 159 },
153 160
154 161 {
155 162 :key => 'contest.default_contest_name',
156 163 :value_type => 'string',
157 164 :default_value => 'none',
158 165 :description => "New user will be assigned to this contest automatically, if it exists. Set to 'none' if there is no default contest."
159 166 }
160 167
161 168 ]
162 169
163 170
164 171 def create_configuration_key(key,
165 172 value_type,
166 173 default_value,
167 174 description='')
168 175 conf = (GraderConfiguration.find_by_key(key) ||
169 176 GraderConfiguration.new(:key => key,
170 177 :value_type => value_type,
171 178 :value => default_value))
172 179 conf.description = description
173 180 conf.save
174 181 end
175 182
176 183 def seed_config
177 184 CONFIGURATIONS.each do |conf|
178 185 if conf.has_key? :description
179 186 desc = conf[:description]
180 187 else
181 188 desc = ''
182 189 end
183 190 create_configuration_key(conf[:key],
184 191 conf[:value_type],
185 192 conf[:default_value],
186 193 desc)
187 194 end
188 195 end
189 196
190 197 def seed_roles
191 198 return if Role.find_by_name('admin')
192 199
193 200 role = Role.create(:name => 'admin')
194 201 user_admin_right = Right.create(:name => 'user_admin',
195 202 :controller => 'user_admin',
196 203 :action => 'all')
197 204 problem_admin_right = Right.create(:name=> 'problem_admin',
198 205 :controller => 'problems',
199 206 :action => 'all')
200 207
201 208 graders_right = Right.create(:name => 'graders_admin',
202 209 :controller => 'graders',
203 210 :action => 'all')
204 211
205 212 role.rights << user_admin_right;
206 213 role.rights << problem_admin_right;
207 214 role.rights << graders_right;
208 215 role.save
209 216 end
210 217
211 218 def seed_root
212 219 return if User.find_by_login('root')
213 220
214 221 root = User.new(:login => 'root',
215 222 :full_name => 'Administrator',
216 223 :alias => 'root')
217 224 root.password = 'ioionrails';
218 225
219 226 class << root
220 227 public :encrypt_new_password
221 228 def valid?(context=nil)
222 229 true
223 230 end
224 231 end
225 232
226 233 root.encrypt_new_password
227 234
228 235 root.roles << Role.find_by_name('admin')
229 236
230 237 root.activated = true
231 238 root.save
232 239 end
233 240
234 241 def seed_users_and_roles
235 242 seed_roles
236 243 seed_root
237 244 end
238 245
239 246 def seed_more_languages
240 247 Language.delete_all
241 248 Language.create( name: 'c', pretty_name: 'C', ext: 'c', common_ext: 'c' )
242 249 Language.create( name: 'cpp', pretty_name: 'C++', ext: 'cpp', common_ext: 'cpp,cc' )
243 250 Language.create( name: 'pas', pretty_name: 'Pascal', ext: 'pas', common_ext: 'pas' )
244 251 Language.create( name: 'ruby', pretty_name: 'Ruby', ext: 'rb', common_ext: 'rb' )
245 252 Language.create( name: 'python', pretty_name: 'Python', ext: 'py', common_ext: 'py' )
246 253 Language.create( name: 'java', pretty_name: 'Java', ext: 'java', common_ext: 'java' )
247 254 end
248 255
249 256 seed_config
250 257 seed_users_and_roles
251 258 seed_more_languages
You need to be logged in to leave comments. Login now