Description:
added individual contest mode
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r217:f2fe2340b1dc - - 24 files changed: 288 inserted, 47 deleted

@@ -0,0 +1,30
1 + class ContestsController < ApplicationController
2 +
3 + before_filter :admin_authorization
4 +
5 + def index
6 + end
7 +
8 + def user_stat
9 + if not Configuration.indv_contest_mode?
10 + redirect_to :action => 'index' and return
11 + end
12 +
13 + @users = User.find(:all)
14 + @start_times = {}
15 + UserContestStat.find(:all).each do |stat|
16 + @start_times[stat.user_id] = stat.started_at
17 + end
18 + end
19 +
20 + def clear_all_stat
21 + if not Configuration.indv_contest_mode?
22 + redirect_to :action => 'index' and return
23 + end
24 +
25 + UserContestStat.delete_all()
26 + flash[:notice] = 'All start time statistic cleared.'
27 + redirect_to :action => 'index'
28 + end
29 +
30 + end
@@ -0,0 +1,2
1 + module ContestsHelper
2 + end
@@ -0,0 +1,14
1 + class UserContestStat < ActiveRecord::Base
2 +
3 + belongs_to :user
4 +
5 + def self.update_user_start_time(user)
6 + stat = user.contest_stat
7 + if stat == nil
8 + stat = UserContestStat.new(:user => user,
9 + :started_at => Time.now.gmtime)
10 + stat.save
11 + end
12 + end
13 +
14 + end
@@ -0,0 +1,4
1 + .submitbox
2 + %b Menu:
3 + = link_to '[View user start time]', :action => 'user_stat'
4 + = link_to '[Clear all start times]', {:action => 'clear_all_stat'}, {:confirm => 'Do you really want to clear all start time statistics?'}
@@ -0,0 +1,9
1 + %h1 Contest management
2 +
3 + - if (not Configuration.contest_mode?) and (not Configuration.indv_contest_mode?)
4 + Currently the system is not running in contest mode.
5 + - elsif Configuration.contest_mode?
6 + System running in normal contest mode.
7 + - else
8 + System running in individual contest mode.
9 + = render :partial => 'indv_contest_mode_index'
@@ -0,0 +1,24
1 + %h1 Individual Contest: User start time
2 +
3 + If you want to restart contest, you may want to
4 + %b
5 + = link_to '[clear all start times]', {:action => 'clear_all_stat'}, {:confirm => 'Do you really want to clear all start time statistics?'}
6 + so that users can participate again.
7 +
8 + %table.info
9 + %tr.info-head
10 + %th Login
11 + %th Start time
12 + %th Time left
13 + %th
14 + - @users.each_with_index do |user,i|
15 + %tr{:class => 'info-' + cycle('even','odd')}
16 + %td= user.login
17 + %td
18 + - if @start_times.has_key? user.id
19 + = @start_times[user.id]
20 + - else
21 + n/a
22 + %td= format_short_duration(user.contest_time_left)
23 + %td
24 + = link_to '[reset]', {:action => 'clear_stat', :id => user.id}, :confirm => 'Are you sure?'
@@ -0,0 +1,9
1 + class AddDescriptionToConfig < ActiveRecord::Migration
2 + def self.up
3 + add_column :configurations, :description, :text
4 + end
5 +
6 + def self.down
7 + remove_column :configurations, :description
8 + end
9 + end
@@ -0,0 +1,14
1 + class CreateUserContestStats < ActiveRecord::Migration
2 + def self.up
3 + create_table :user_contest_stats do |t|
4 + t.integer :user_id
5 + t.timestamp :started_at
6 +
7 + t.timestamps
8 + end
9 + end
10 +
11 + def self.down
12 + drop_table :user_contest_stats
13 + end
14 + end
@@ -0,0 +1,2
1 + .sass-cache
2 +
@@ -0,0 +1,9
1 + # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 +
3 + one:
4 + user_id: 1
5 + started_at: 2010-01-24 12:44:58
6 +
7 + two:
8 + user_id: 1
9 + started_at: 2010-01-24 12:44:58
@@ -0,0 +1,8
1 + require 'test_helper'
2 +
3 + class ContestsControllerTest < ActionController::TestCase
4 + # Replace this with your real tests.
5 + test "the truth" do
6 + assert true
7 + end
8 + end
@@ -0,0 +1,4
1 + require 'test_helper'
2 +
3 + class ContestsHelperTest < ActionView::TestCase
4 + end
@@ -0,0 +1,8
1 + require 'test_helper'
2 +
3 + class UserContestStatTest < ActiveSupport::TestCase
4 + # Replace this with your real tests.
5 + test "the truth" do
6 + assert true
7 + end
8 + end
@@ -17,58 +17,58
17 unless user.roles.detect { |role| allowed_roles.member?(role.name) }
17 unless user.roles.detect { |role| allowed_roles.member?(role.name) }
18 flash[:notice] = 'You are not authorized to view the page you requested'
18 flash[:notice] = 'You are not authorized to view the page you requested'
19 redirect_to :controller => 'main', :action => 'login'
19 redirect_to :controller => 'main', :action => 'login'
20 return false
20 return false
21 end
21 end
22 end
22 end
23
23
24 protected
24 protected
25
25
26 def authenticate
26 def authenticate
27 unless session[:user_id]
27 unless session[:user_id]
28 redirect_to :controller => 'main', :action => 'login'
28 redirect_to :controller => 'main', :action => 'login'
29 return false
29 return false
30 end
30 end
31
31
32 #Configuration.reload
32 #Configuration.reload
33 # check if run in single user mode
33 # check if run in single user mode
34 if (Configuration[SINGLE_USER_MODE_CONF_KEY])
34 if (Configuration[SINGLE_USER_MODE_CONF_KEY])
35 user = User.find(session[:user_id])
35 user = User.find(session[:user_id])
36 if user==nil or user.login != 'root'
36 if user==nil or user.login != 'root'
37 redirect_to :controller => 'main', :action => 'login'
37 redirect_to :controller => 'main', :action => 'login'
38 return false
38 return false
39 end
39 end
40 end
40 end
41
41
42 return true
42 return true
43 end
43 end
44
44
45 def authorization
45 def authorization
46 return false unless authenticate
46 return false unless authenticate
47 user = User.find(session[:user_id])
47 user = User.find(session[:user_id])
48 unless user.roles.detect { |role|
48 unless user.roles.detect { |role|
49 role.rights.detect{ |right|
49 role.rights.detect{ |right|
50 right.controller == self.class.controller_name and
50 right.controller == self.class.controller_name and
51 (right.action == 'all' or right.action == action_name)
51 (right.action == 'all' or right.action == action_name)
52 }
52 }
53 }
53 }
54 flash[:notice] = 'You are not authorized to view the page you requested'
54 flash[:notice] = 'You are not authorized to view the page you requested'
55 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
55 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
56 redirect_to :controller => 'main', :action => 'login'
56 redirect_to :controller => 'main', :action => 'login'
57 return false
57 return false
58 end
58 end
59 end
59 end
60
60
61 def verify_time_limit
61 def verify_time_limit
62 return true if session[:user_id]==nil
62 return true if session[:user_id]==nil
63 user = User.find(session[:user_id], :include => :site)
63 user = User.find(session[:user_id], :include => :site)
64 return true if user==nil or user.site == nil
64 return true if user==nil or user.site == nil
65 - if user.site.finished?
65 + if user.contest_finished?
66 - flash[:notice] = 'Error: the contest on your site is over.'
66 + flash[:notice] = 'Error: the contest you are participating is over.'
67 redirect_to :back
67 redirect_to :back
68 return false
68 return false
69 end
69 end
70 return true
70 return true
71 end
71 end
72
72
73 end
73 end
74
74
@@ -1,43 +1,40
1 class LoginController < ApplicationController
1 class LoginController < ApplicationController
2
2
3 def index
3 def index
4 # show login screen
4 # show login screen
5 reset_session
5 reset_session
6 redirect_to :controller => 'main', :action => 'login'
6 redirect_to :controller => 'main', :action => 'login'
7 end
7 end
8
8
9 def login
9 def login
10 if user = User.authenticate(params[:login], params[:password])
10 if user = User.authenticate(params[:login], params[:password])
11 session[:user_id] = user.id
11 session[:user_id] = user.id
12 + session[:admin] = user.admin?
13 + UserContestStat.update_user_start_time(user)
12 redirect_to :controller => 'main', :action => 'list'
14 redirect_to :controller => 'main', :action => 'list'
13 - if user.admin?
14 - session[:admin] = true
15 - else
16 - session[:admin] = false
17 - end
18 else
15 else
19 flash[:notice] = 'Wrong password'
16 flash[:notice] = 'Wrong password'
20 redirect_to :controller => 'main', :action => 'login'
17 redirect_to :controller => 'main', :action => 'login'
21 end
18 end
22 end
19 end
23
20
24 def site_login
21 def site_login
25 begin
22 begin
26 site = Site.find(params[:login][:site_id])
23 site = Site.find(params[:login][:site_id])
27 rescue ActiveRecord::RecordNotFound
24 rescue ActiveRecord::RecordNotFound
28 site = nil
25 site = nil
29 end
26 end
30 if site==nil
27 if site==nil
31 flash[:notice] = 'Wrong site'
28 flash[:notice] = 'Wrong site'
32 redirect_to :controller => 'main', :action => 'login' and return
29 redirect_to :controller => 'main', :action => 'login' and return
33 end
30 end
34 if (site.password) and (site.password == params[:login][:password])
31 if (site.password) and (site.password == params[:login][:password])
35 session[:site_id] = site.id
32 session[:site_id] = site.id
36 redirect_to :controller => 'site', :action => 'index'
33 redirect_to :controller => 'site', :action => 'index'
37 else
34 else
38 flash[:notice] = 'Wrong site password'
35 flash[:notice] = 'Wrong site password'
39 redirect_to :controller => 'site', :action => 'login'
36 redirect_to :controller => 'site', :action => 'login'
40 end
37 end
41 end
38 end
42
39
43 end
40 end
@@ -1,111 +1,108
1 class MainController < ApplicationController
1 class MainController < ApplicationController
2
2
3 - SYSTEM_MODE_CONF_KEY = 'system.mode'
4 -
5 before_filter :authenticate, :except => [:index, :login]
3 before_filter :authenticate, :except => [:index, :login]
6 before_filter :check_viewability, :except => [:index, :login]
4 before_filter :check_viewability, :except => [:index, :login]
7
5
8 # COMMENTED OUT: filter in each action instead
6 # COMMENTED OUT: filter in each action instead
9 # before_filter :verify_time_limit, :only => [:submit]
7 # before_filter :verify_time_limit, :only => [:submit]
10
8
11 verify :method => :post, :only => [:submit],
9 verify :method => :post, :only => [:submit],
12 :redirect_to => { :action => :index }
10 :redirect_to => { :action => :index }
13
11
14 # COMMENT OUT: only need when having high load
12 # COMMENT OUT: only need when having high load
15 # caches_action :index, :login
13 # caches_action :index, :login
16
14
17 # NOTE: This method is not actually needed, 'config/routes.rb' has
15 # NOTE: This method is not actually needed, 'config/routes.rb' has
18 # assigned action login as a default action.
16 # assigned action login as a default action.
19 def index
17 def index
20 redirect_to :action => 'login'
18 redirect_to :action => 'login'
21 end
19 end
22
20
23 def login
21 def login
24 saved_notice = flash[:notice]
22 saved_notice = flash[:notice]
25 reset_session
23 reset_session
26 flash[:notice] = saved_notice
24 flash[:notice] = saved_notice
27
25
28 # EXPERIMENT:
26 # EXPERIMENT:
29 # Hide login if in single user mode and the url does not
27 # Hide login if in single user mode and the url does not
30 # explicitly specify /login
28 # explicitly specify /login
31 #
29 #
32 # logger.info "PATH: #{request.path}"
30 # logger.info "PATH: #{request.path}"
33 # if Configuration['system.single_user_mode'] and
31 # if Configuration['system.single_user_mode'] and
34 # request.path!='/main/login'
32 # request.path!='/main/login'
35 # @hidelogin = true
33 # @hidelogin = true
36 # end
34 # end
37
35
38 @announcements = Announcement.find_for_frontpage
36 @announcements = Announcement.find_for_frontpage
39 render :action => 'login', :layout => 'empty'
37 render :action => 'login', :layout => 'empty'
40 end
38 end
41
39
42 def list
40 def list
43 prepare_list_information
41 prepare_list_information
44 end
42 end
45
43
46 def help
44 def help
47 @user = User.find(session[:user_id])
45 @user = User.find(session[:user_id])
48 end
46 end
49
47
50 def submit
48 def submit
51 user = User.find(session[:user_id])
49 user = User.find(session[:user_id])
52
50
53 @submission = Submission.new(params[:submission])
51 @submission = Submission.new(params[:submission])
54 @submission.user = user
52 @submission.user = user
55 @submission.language_id = 0
53 @submission.language_id = 0
56 if (params['file']) and (params['file']!='')
54 if (params['file']) and (params['file']!='')
57 @submission.source = params['file'].read
55 @submission.source = params['file'].read
58 @submission.source_filename = params['file'].original_filename
56 @submission.source_filename = params['file'].original_filename
59 end
57 end
60 @submission.submitted_at = Time.new.gmtime
58 @submission.submitted_at = Time.new.gmtime
61
59
62 - if Configuration[SYSTEM_MODE_CONF_KEY]=='contest' and
60 + if Configuration.time_limit_mode? and user.contest_finished?
63 - user.site!=nil and user.site.finished?
64 @submission.errors.add_to_base "The contest is over."
61 @submission.errors.add_to_base "The contest is over."
65 prepare_list_information
62 prepare_list_information
66 render :action => 'list' and return
63 render :action => 'list' and return
67 end
64 end
68
65
69 if @submission.valid?
66 if @submission.valid?
70 if @submission.save == false
67 if @submission.save == false
71 flash[:notice] = 'Error saving your submission'
68 flash[:notice] = 'Error saving your submission'
72 elsif Task.create(:submission_id => @submission.id,
69 elsif Task.create(:submission_id => @submission.id,
73 :status => Task::STATUS_INQUEUE) == false
70 :status => Task::STATUS_INQUEUE) == false
74 flash[:notice] = 'Error adding your submission to task queue'
71 flash[:notice] = 'Error adding your submission to task queue'
75 end
72 end
76 else
73 else
77 prepare_list_information
74 prepare_list_information
78 render :action => 'list' and return
75 render :action => 'list' and return
79 end
76 end
80 redirect_to :action => 'list'
77 redirect_to :action => 'list'
81 end
78 end
82
79
83 def source
80 def source
84 submission = Submission.find(params[:id])
81 submission = Submission.find(params[:id])
85 if submission.user_id == session[:user_id]
82 if submission.user_id == session[:user_id]
86 send_data(submission.source,
83 send_data(submission.source,
87 {:filename => submission.download_filename,
84 {:filename => submission.download_filename,
88 :type => 'text/plain'})
85 :type => 'text/plain'})
89 else
86 else
90 flash[:notice] = 'Error viewing source'
87 flash[:notice] = 'Error viewing source'
91 redirect_to :action => 'list'
88 redirect_to :action => 'list'
92 end
89 end
93 end
90 end
94
91
95 def compiler_msg
92 def compiler_msg
96 @submission = Submission.find(params[:id])
93 @submission = Submission.find(params[:id])
97 if @submission.user_id == session[:user_id]
94 if @submission.user_id == session[:user_id]
98 render :action => 'compiler_msg', :layout => 'empty'
95 render :action => 'compiler_msg', :layout => 'empty'
99 else
96 else
100 flash[:notice] = 'Error viewing source'
97 flash[:notice] = 'Error viewing source'
101 redirect_to :action => 'list'
98 redirect_to :action => 'list'
102 end
99 end
103 end
100 end
104
101
105 def submission
102 def submission
106 @user = User.find(session[:user_id])
103 @user = User.find(session[:user_id])
107 @problems = Problem.find_available_problems
104 @problems = Problem.find_available_problems
108 if params[:id]==nil
105 if params[:id]==nil
109 @problem = nil
106 @problem = nil
110 @submissions = nil
107 @submissions = nil
111 else
108 else
@@ -1,78 +1,76
1 class TestController < ApplicationController
1 class TestController < ApplicationController
2
2
3 - SYSTEM_MODE_CONF_KEY = 'system.mode'
4 -
5 before_filter :authenticate, :check_viewability
3 before_filter :authenticate, :check_viewability
6
4
7 #
5 #
8 # COMMENT OUT: filter in each action instead
6 # COMMENT OUT: filter in each action instead
9 #
7 #
10 # before_filter :verify_time_limit, :only => [:submit]
8 # before_filter :verify_time_limit, :only => [:submit]
11
9
12 verify :method => :post, :only => [:submit],
10 verify :method => :post, :only => [:submit],
13 :redirect_to => { :action => :index }
11 :redirect_to => { :action => :index }
14
12
15 def index
13 def index
16 prepare_index_information
14 prepare_index_information
17 end
15 end
18
16
19 def submit
17 def submit
20 @user = User.find(session[:user_id])
18 @user = User.find(session[:user_id])
21
19
22 @submitted_test_request = TestRequest.new_from_form_params(@user,params[:test_request])
20 @submitted_test_request = TestRequest.new_from_form_params(@user,params[:test_request])
23
21
24 if @submitted_test_request.errors.length != 0
22 if @submitted_test_request.errors.length != 0
25 prepare_index_information
23 prepare_index_information
26 render :action => 'index' and return
24 render :action => 'index' and return
27 end
25 end
28
26
29 - if Configuration[SYSTEM_MODE_CONF_KEY]=='contest'
27 + if Configuration.time_limit_mode?
30 - if @user.site!=nil and @user.site.finished?
28 + if @user.contest_finished?
31 @submitted_test_request.errors.add_to_base('Contest is over.')
29 @submitted_test_request.errors.add_to_base('Contest is over.')
32 prepare_index_information
30 prepare_index_information
33 render :action => 'index' and return
31 render :action => 'index' and return
34 end
32 end
35
33
36 if !Configuration.allow_test_request(@user)
34 if !Configuration.allow_test_request(@user)
37 prepare_index_information
35 prepare_index_information
38 flash[:notice] = 'Test request is not allowed during the last 30 minutes'
36 flash[:notice] = 'Test request is not allowed during the last 30 minutes'
39 redirect_to :action => 'index' and return
37 redirect_to :action => 'index' and return
40 end
38 end
41 end
39 end
42
40
43 if @submitted_test_request.save
41 if @submitted_test_request.save
44 redirect_to :action => 'index'
42 redirect_to :action => 'index'
45 else
43 else
46 prepare_index_information
44 prepare_index_information
47 render :action => 'index'
45 render :action => 'index'
48 end
46 end
49 end
47 end
50
48
51 def read
49 def read
52 user = User.find(session[:user_id])
50 user = User.find(session[:user_id])
53 begin
51 begin
54 test_request = TestRequest.find(params[:id])
52 test_request = TestRequest.find(params[:id])
55 rescue
53 rescue
56 test_request = nil
54 test_request = nil
57 end
55 end
58 if test_request==nil or test_request.user_id != user.id
56 if test_request==nil or test_request.user_id != user.id
59 flash[:notice] = 'Invalid output'
57 flash[:notice] = 'Invalid output'
60 redirect_to :action => 'index'
58 redirect_to :action => 'index'
61 return
59 return
62 end
60 end
63 if test_request.output_file_name!=nil
61 if test_request.output_file_name!=nil
64 data = File.open(test_request.output_file_name).read(2048)
62 data = File.open(test_request.output_file_name).read(2048)
65 if data==nil
63 if data==nil
66 data=""
64 data=""
67 end
65 end
68 send_data(data,
66 send_data(data,
69 {:filename => 'output.txt',
67 {:filename => 'output.txt',
70 :type => 'text/plain'})
68 :type => 'text/plain'})
71 return
69 return
72 end
70 end
73 redirect_to :action => 'index'
71 redirect_to :action => 'index'
74 end
72 end
75
73
76 def result
74 def result
77 @user = User.find(session[:user_id])
75 @user = User.find(session[:user_id])
78 begin
76 begin
@@ -1,124 +1,127
1 # Methods added to this helper will be available to all templates in the application.
1 # Methods added to this helper will be available to all templates in the application.
2 module ApplicationHelper
2 module ApplicationHelper
3
3
4 - SYSTEM_MODE_CONF_KEY = 'system.mode'
5 -
6 def user_header
4 def user_header
7 menu_items = ''
5 menu_items = ''
8 user = User.find(session[:user_id])
6 user = User.find(session[:user_id])
9
7
10 if (user!=nil) and (session[:admin])
8 if (user!=nil) and (session[:admin])
11 # admin menu
9 # admin menu
12 menu_items << "<b>Administrative task:</b> "
10 menu_items << "<b>Administrative task:</b> "
13 append_to menu_items, '[Announcements]', 'announcements', 'index'
11 append_to menu_items, '[Announcements]', 'announcements', 'index'
14 append_to menu_items, '[Msg console]', 'messages', 'console'
12 append_to menu_items, '[Msg console]', 'messages', 'console'
15 - append_to menu_items, '[Problem admin]', 'problems', 'index'
13 + append_to menu_items, '[Problems]', 'problems', 'index'
16 - append_to menu_items, '[User admin]', 'user_admin', 'index'
14 + append_to menu_items, '[Users]', 'user_admin', 'index'
17 append_to menu_items, '[Results]', 'user_admin', 'user_stat'
15 append_to menu_items, '[Results]', 'user_admin', 'user_stat'
18 append_to menu_items, '[Graders]', 'graders', 'list'
16 append_to menu_items, '[Graders]', 'graders', 'list'
17 + append_to menu_items, '[Contests]', 'contests', 'index'
19 append_to menu_items, '[Sites]', 'sites', 'index'
18 append_to menu_items, '[Sites]', 'sites', 'index'
20 append_to menu_items, '[System config]', 'configurations', 'index'
19 append_to menu_items, '[System config]', 'configurations', 'index'
21 menu_items << "<br/>"
20 menu_items << "<br/>"
22 end
21 end
23
22
24 # main page
23 # main page
25 append_to menu_items, "[#{I18n.t 'menu.main'}]", 'main', 'list'
24 append_to menu_items, "[#{I18n.t 'menu.main'}]", 'main', 'list'
26 append_to menu_items, "[#{I18n.t 'menu.messages'}]", 'messages', 'list'
25 append_to menu_items, "[#{I18n.t 'menu.messages'}]", 'messages', 'list'
27
26
28 if (user!=nil) and (Configuration.show_tasks_to?(user))
27 if (user!=nil) and (Configuration.show_tasks_to?(user))
29 append_to menu_items, "[#{I18n.t 'menu.tasks'}]", 'tasks', 'list'
28 append_to menu_items, "[#{I18n.t 'menu.tasks'}]", 'tasks', 'list'
30 append_to menu_items, "[#{I18n.t 'menu.submissions'}]", 'main', 'submission'
29 append_to menu_items, "[#{I18n.t 'menu.submissions'}]", 'main', 'submission'
31 append_to menu_items, "[#{I18n.t 'menu.test'}]", 'test', 'index'
30 append_to menu_items, "[#{I18n.t 'menu.test'}]", 'test', 'index'
32 end
31 end
33 append_to menu_items, "[#{I18n.t 'menu.help'}]", 'main', 'help'
32 append_to menu_items, "[#{I18n.t 'menu.help'}]", 'main', 'help'
34
33
35 if Configuration['system.user_setting_enabled']
34 if Configuration['system.user_setting_enabled']
36 append_to menu_items, "[#{I18n.t 'menu.settings'}]", 'users', 'index'
35 append_to menu_items, "[#{I18n.t 'menu.settings'}]", 'users', 'index'
37 end
36 end
38 append_to menu_items, "[#{I18n.t 'menu.log_out'}]", 'main', 'login'
37 append_to menu_items, "[#{I18n.t 'menu.log_out'}]", 'main', 'login'
39
38
40 menu_items
39 menu_items
41 end
40 end
42
41
43 def append_to(option,label, controller, action)
42 def append_to(option,label, controller, action)
44 option << ' ' if option!=''
43 option << ' ' if option!=''
45 option << link_to_unless_current(label,
44 option << link_to_unless_current(label,
46 :controller => controller,
45 :controller => controller,
47 :action => action)
46 :action => action)
48 end
47 end
49
48
50 def format_short_time(time)
49 def format_short_time(time)
51 now = Time.now.gmtime
50 now = Time.now.gmtime
52 st = ''
51 st = ''
53 if (time.yday != now.yday) or
52 if (time.yday != now.yday) or
54 (time.year != now.year)
53 (time.year != now.year)
55 st = time.strftime("%x ")
54 st = time.strftime("%x ")
56 end
55 end
57 st + time.strftime("%X")
56 st + time.strftime("%X")
58 end
57 end
59
58
59 + def format_short_duration(duration)
60 + return '' if duration==nil
61 + d = duration.to_f
62 + return Time.at(d).gmtime.strftime("%X")
63 + end
64 +
60 def read_textfile(fname,max_size=2048)
65 def read_textfile(fname,max_size=2048)
61 begin
66 begin
62 File.open(fname).read(max_size)
67 File.open(fname).read(max_size)
63 rescue
68 rescue
64 nil
69 nil
65 end
70 end
66 end
71 end
67
72
68 def user_title_bar(user)
73 def user_title_bar(user)
69 header = ''
74 header = ''
70 time_left = ''
75 time_left = ''
71
76
72 #
77 #
73 # if the contest is over
78 # if the contest is over
74 - if Configuration[SYSTEM_MODE_CONF_KEY]=='contest'
79 + if Configuration.time_limit_mode?
75 - if user.site!=nil and user.site.finished?
80 + if user.contest_finished?
76 header = <<CONTEST_OVER
81 header = <<CONTEST_OVER
77 <tr><td colspan="2" align="center">
82 <tr><td colspan="2" align="center">
78 <span class="contest-over-msg">THE CONTEST IS OVER</span>
83 <span class="contest-over-msg">THE CONTEST IS OVER</span>
79 </td></tr>
84 </td></tr>
80 CONTEST_OVER
85 CONTEST_OVER
81 end
86 end
82 - if !user.site.started
87 + if !user.contest_started?
83 time_left = "&nbsp;&nbsp;" + (t 'title_bar.contest_not_started')
88 time_left = "&nbsp;&nbsp;" + (t 'title_bar.contest_not_started')
84 else
89 else
85 - if user.site!=nil
86 time_left = "&nbsp;&nbsp;" + (t 'title_bar.remaining_time') +
90 time_left = "&nbsp;&nbsp;" + (t 'title_bar.remaining_time') +
87 - " #{Time.at(user.site.time_left).gmtime.strftime("%X")}"
91 + " #{format_short_duration(user.contest_time_left)}"
88 - end
89 end
92 end
90 end
93 end
91
94
92 #
95 #
93 # if the contest is in the anaysis mode
96 # if the contest is in the anaysis mode
94 - if Configuration[SYSTEM_MODE_CONF_KEY]=='analysis'
97 + if Configuration.analysis_mode?
95 header = <<ANALYSISMODE
98 header = <<ANALYSISMODE
96 <tr><td colspan="2" align="center">
99 <tr><td colspan="2" align="center">
97 <span class="contest-over-msg">ANALYSIS MODE</span>
100 <span class="contest-over-msg">ANALYSIS MODE</span>
98 </td></tr>
101 </td></tr>
99 ANALYSISMODE
102 ANALYSISMODE
100 end
103 end
101
104
102 contest_name = Configuration['contest.name']
105 contest_name = Configuration['contest.name']
103
106
104 #
107 #
105 # build real title bar
108 # build real title bar
106 <<TITLEBAR
109 <<TITLEBAR
107 <div class="title">
110 <div class="title">
108 <table>
111 <table>
109 #{header}
112 #{header}
110 <tr>
113 <tr>
111 <td class="left-col">
114 <td class="left-col">
112 #{user.full_name}<br/>
115 #{user.full_name}<br/>
113 #{t 'title_bar.current_time'} #{format_short_time(Time.new)}
116 #{t 'title_bar.current_time'} #{format_short_time(Time.new)}
114 #{time_left}
117 #{time_left}
115 <br/>
118 <br/>
116 </td>
119 </td>
117 <td class="right-col">#{contest_name}</td>
120 <td class="right-col">#{contest_name}</td>
118 </tr>
121 </tr>
119 </table>
122 </table>
120 </div>
123 </div>
121 TITLEBAR
124 TITLEBAR
122 end
125 end
123
126
124 end
127 end
@@ -14,122 +14,159
14 @@configurations = nil
14 @@configurations = nil
15 @@task_grading_info = nil
15 @@task_grading_info = nil
16
16
17 def self.get(key)
17 def self.get(key)
18 if @@cache
18 if @@cache
19 if @@configurations == nil
19 if @@configurations == nil
20 self.read_config
20 self.read_config
21 end
21 end
22 return @@configurations[key]
22 return @@configurations[key]
23 else
23 else
24 return Configuration.read_one_key(key)
24 return Configuration.read_one_key(key)
25 end
25 end
26 end
26 end
27
27
28 def self.[](key)
28 def self.[](key)
29 self.get(key)
29 self.get(key)
30 end
30 end
31
31
32 def self.reload
32 def self.reload
33 self.read_config
33 self.read_config
34 end
34 end
35
35
36 def self.clear
36 def self.clear
37 @@configurations = nil
37 @@configurations = nil
38 end
38 end
39
39
40 def self.cache?
40 def self.cache?
41 @@cache
41 @@cache
42 end
42 end
43
43
44 def self.enable_caching
44 def self.enable_caching
45 @@cache = true
45 @@cache = true
46 end
46 end
47
47
48 #
48 #
49 # View decision
49 # View decision
50 #
50 #
51 def self.show_submitbox_to?(user)
51 def self.show_submitbox_to?(user)
52 mode = get(SYSTEM_MODE_CONF_KEY)
52 mode = get(SYSTEM_MODE_CONF_KEY)
53 return false if mode=='analysis'
53 return false if mode=='analysis'
54 if (mode=='contest')
54 if (mode=='contest')
55 return false if (user.site!=nil) and
55 return false if (user.site!=nil) and
56 ((user.site.started!=true) or (user.site.finished?))
56 ((user.site.started!=true) or (user.site.finished?))
57 end
57 end
58 return true
58 return true
59 end
59 end
60
60
61 def self.show_tasks_to?(user)
61 def self.show_tasks_to?(user)
62 - mode = get(SYSTEM_MODE_CONF_KEY)
62 + if time_limit_mode?
63 - if (mode=='contest')
63 + return false if not user.contest_started?
64 - return false if (user.site!=nil) and (user.site.started!=true)
65 end
64 end
66 return true
65 return true
67 end
66 end
68
67
69 def self.show_grading_result
68 def self.show_grading_result
70 return (get(SYSTEM_MODE_CONF_KEY)=='analysis')
69 return (get(SYSTEM_MODE_CONF_KEY)=='analysis')
71 end
70 end
72
71
73 def self.allow_test_request(user)
72 def self.allow_test_request(user)
74 mode = get(SYSTEM_MODE_CONF_KEY)
73 mode = get(SYSTEM_MODE_CONF_KEY)
75 early_timeout = get(TEST_REQUEST_EARLY_TIMEOUT_KEY)
74 early_timeout = get(TEST_REQUEST_EARLY_TIMEOUT_KEY)
76 if (mode=='contest')
75 if (mode=='contest')
77 return false if ((user.site!=nil) and
76 return false if ((user.site!=nil) and
78 ((user.site.started!=true) or
77 ((user.site.started!=true) or
79 (early_timeout and (user.site.time_left < 30.minutes))))
78 (early_timeout and (user.site.time_left < 30.minutes))))
80 end
79 end
81 return false if mode=='analysis'
80 return false if mode=='analysis'
82 return true
81 return true
83 end
82 end
84
83
85 def self.task_grading_info
84 def self.task_grading_info
86 if @@task_grading_info==nil
85 if @@task_grading_info==nil
87 read_grading_info
86 read_grading_info
88 end
87 end
89 return @@task_grading_info
88 return @@task_grading_info
90 end
89 end
91
90
92 - def self.contest_mode
91 + def self.standard_mode?
92 + return get(SYSTEM_MODE_CONF_KEY) == 'standard'
93 + end
94 +
95 + def self.contest_mode?
93 return get(SYSTEM_MODE_CONF_KEY) == 'contest'
96 return get(SYSTEM_MODE_CONF_KEY) == 'contest'
94 end
97 end
95
98
99 + def self.indv_contest_mode?
100 + return get(SYSTEM_MODE_CONF_KEY) == 'indv-contest'
101 + end
102 +
103 + def self.time_limit_mode?
104 + mode = get(SYSTEM_MODE_CONF_KEY)
105 + return ((mode == 'contest') or (mode == 'indv-contest'))
106 + end
107 +
108 + def self.analysis_mode?
109 + return get(SYSTEM_MODE_CONF_KEY) == 'analysis'
110 + end
111 +
112 + def self.contest_time_limit
113 + contest_time_str = Configuration['contest.time_limit']
114 +
115 + if not defined? @@contest_time_str
116 + @@contest_time_str = nil
117 + end
118 +
119 + if @@contest_time_str != contest_time_str
120 + @@contest_time_str = contest_time_str
121 + if tmatch = /(\d+):(\d+)/.match(contest_time_str)
122 + h = tmatch[1].to_i
123 + m = tmatch[2].to_i
124 +
125 + @@contest_time = h.hour + m.minute
126 + else
127 + @@contest_time = nil
128 + end
129 + end
130 + return @@contest_time
131 + end
132 +
96 protected
133 protected
97
134
98 def self.convert_type(val,type)
135 def self.convert_type(val,type)
99 case type
136 case type
100 when 'string'
137 when 'string'
101 return val
138 return val
102
139
103 when 'integer'
140 when 'integer'
104 return val.to_i
141 return val.to_i
105
142
106 when 'boolean'
143 when 'boolean'
107 return (val=='true')
144 return (val=='true')
108 end
145 end
109 end
146 end
110
147
111 def self.read_config
148 def self.read_config
112 @@configurations = {}
149 @@configurations = {}
113 Configuration.find(:all).each do |conf|
150 Configuration.find(:all).each do |conf|
114 key = conf.key
151 key = conf.key
115 val = conf.value
152 val = conf.value
116 @@configurations[key] = Configuration.convert_type(val,conf.value_type)
153 @@configurations[key] = Configuration.convert_type(val,conf.value_type)
117 end
154 end
118 end
155 end
119
156
120 def self.read_one_key(key)
157 def self.read_one_key(key)
121 conf = Configuration.find_by_key(key)
158 conf = Configuration.find_by_key(key)
122 if conf
159 if conf
123 return Configuration.convert_type(conf.value,conf.value_type)
160 return Configuration.convert_type(conf.value,conf.value_type)
124 else
161 else
125 return nil
162 return nil
126 end
163 end
127 end
164 end
128
165
129 def self.read_grading_info
166 def self.read_grading_info
130 f = File.open(TASK_GRADING_INFO_FILENAME)
167 f = File.open(TASK_GRADING_INFO_FILENAME)
131 @@task_grading_info = YAML.load(f)
168 @@task_grading_info = YAML.load(f)
132 f.close
169 f.close
133 end
170 end
134
171
135 end
172 end
@@ -1,54 +1,46
1 class Site < ActiveRecord::Base
1 class Site < ActiveRecord::Base
2
2
3 belongs_to :country
3 belongs_to :country
4 has_many :users
4 has_many :users
5
5
6 def clear_start_time_if_not_started
6 def clear_start_time_if_not_started
7 if !self.started
7 if !self.started
8 self.start_time = nil
8 self.start_time = nil
9 end
9 end
10 end
10 end
11
11
12 def time_left
12 def time_left
13 - contest_time = Configuration['contest.time_limit']
13 + contest_time = Configuration.contest_time_limit
14 - if tmatch = /(\d+):(\d+)/.match(contest_time)
15 - h = tmatch[1].to_i
16 - m = tmatch[2].to_i
17
14
18 - contest_time = h.hour + m.minute
15 + return nil if contest_time == nil
19
16
20 return contest_time if !self.started
17 return contest_time if !self.started
21
18
22 current_time = Time.now.gmtime
19 current_time = Time.now.gmtime
23 if self.start_time!=nil
20 if self.start_time!=nil
24 finish_time = self.start_time + contest_time
21 finish_time = self.start_time + contest_time
25 else
22 else
26 finish_time = current_time + contest_time
23 finish_time = current_time + contest_time
27 end
24 end
28
25
29 if current_time > finish_time
26 if current_time > finish_time
30 return current_time - current_time
27 return current_time - current_time
31 else
28 else
32 - finish_time - current_time
29 + return finish_time - current_time
33 - end
34 - else
35 - nil
36 end
30 end
37 end
31 end
38
32
39 def finished?
33 def finished?
40 if !self.started
34 if !self.started
41 return false
35 return false
42 end
36 end
43
37
44 - contest_time = Configuration['contest.time_limit']
38 + contest_time = Configuration.contest_time_limit
45 - if tmatch = /(\d+):(\d+)/.match(contest_time)
39 + if contest_time!=nil
46 - h = tmatch[1].to_i
40 + return Time.now.gmtime > (self.start_time + contest_time)
47 - m = tmatch[2].to_i
48 - return Time.now.gmtime > (self.start_time + h.hour + m.minute)
49 else
41 else
50 false
42 false
51 end
43 end
52 end
44 end
53
45
54 end
46 end
@@ -1,66 +1,68
1 require 'digest/sha1'
1 require 'digest/sha1'
2
2
3 class User < ActiveRecord::Base
3 class User < ActiveRecord::Base
4
4
5 has_and_belongs_to_many :roles
5 has_and_belongs_to_many :roles
6
6
7 has_many :test_requests, :order => "submitted_at DESC"
7 has_many :test_requests, :order => "submitted_at DESC"
8
8
9 has_many :messages,
9 has_many :messages,
10 :class_name => "Message",
10 :class_name => "Message",
11 :foreign_key => "sender_id",
11 :foreign_key => "sender_id",
12 :order => 'created_at DESC'
12 :order => 'created_at DESC'
13
13
14 has_many :replied_messages,
14 has_many :replied_messages,
15 :class_name => "Message",
15 :class_name => "Message",
16 :foreign_key => "receiver_id",
16 :foreign_key => "receiver_id",
17 :order => 'created_at DESC'
17 :order => 'created_at DESC'
18
18
19 + has_one :contest_stat, :class_name => "UserContestStat"
20 +
19 belongs_to :site
21 belongs_to :site
20 belongs_to :country
22 belongs_to :country
21
23
22 named_scope :activated_users, :conditions => {:activated => true}
24 named_scope :activated_users, :conditions => {:activated => true}
23
25
24 validates_presence_of :login
26 validates_presence_of :login
25 validates_uniqueness_of :login
27 validates_uniqueness_of :login
26 validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
28 validates_format_of :login, :with => /^[\_A-Za-z0-9]+$/
27 validates_length_of :login, :within => 3..30
29 validates_length_of :login, :within => 3..30
28
30
29 validates_presence_of :full_name
31 validates_presence_of :full_name
30 validates_length_of :full_name, :minimum => 1
32 validates_length_of :full_name, :minimum => 1
31
33
32 validates_presence_of :password, :if => :password_required?
34 validates_presence_of :password, :if => :password_required?
33 validates_length_of :password, :within => 4..20, :if => :password_required?
35 validates_length_of :password, :within => 4..20, :if => :password_required?
34 validates_confirmation_of :password, :if => :password_required?
36 validates_confirmation_of :password, :if => :password_required?
35
37
36 validates_format_of :email,
38 validates_format_of :email,
37 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
39 :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i,
38 :if => :email_validation?
40 :if => :email_validation?
39 validate :uniqueness_of_email_from_activated_users,
41 validate :uniqueness_of_email_from_activated_users,
40 :if => :email_validation?
42 :if => :email_validation?
41 validate :enough_time_interval_between_same_email_registrations,
43 validate :enough_time_interval_between_same_email_registrations,
42 :if => :email_validation?
44 :if => :email_validation?
43
45
44 # these are for ytopc
46 # these are for ytopc
45 # disable for now
47 # disable for now
46 #validates_presence_of :province
48 #validates_presence_of :province
47
49
48 attr_accessor :password
50 attr_accessor :password
49
51
50 before_save :encrypt_new_password
52 before_save :encrypt_new_password
51 before_save :assign_default_site
53 before_save :assign_default_site
52
54
53 def self.authenticate(login, password)
55 def self.authenticate(login, password)
54 user = find_by_login(login)
56 user = find_by_login(login)
55 return user if user && user.authenticated?(password)
57 return user if user && user.authenticated?(password)
56 end
58 end
57
59
58 def authenticated?(password)
60 def authenticated?(password)
59 if self.activated
61 if self.activated
60 hashed_password == User.encrypt(password,self.salt)
62 hashed_password == User.encrypt(password,self.salt)
61 else
63 else
62 false
64 false
63 end
65 end
64 end
66 end
65
67
66 def admin?
68 def admin?
@@ -73,96 +75,144
73 elsif self.email==''
75 elsif self.email==''
74 "(blank)"
76 "(blank)"
75 else
77 else
76 self.email
78 self.email
77 end
79 end
78 end
80 end
79
81
80 def email_for_editing=(e)
82 def email_for_editing=(e)
81 self.email=e
83 self.email=e
82 end
84 end
83
85
84 def alias_for_editing
86 def alias_for_editing
85 if self.alias==nil
87 if self.alias==nil
86 "(unknown)"
88 "(unknown)"
87 elsif self.alias==''
89 elsif self.alias==''
88 "(blank)"
90 "(blank)"
89 else
91 else
90 self.alias
92 self.alias
91 end
93 end
92 end
94 end
93
95
94 def alias_for_editing=(e)
96 def alias_for_editing=(e)
95 self.alias=e
97 self.alias=e
96 end
98 end
97
99
98 def activation_key
100 def activation_key
99 if self.hashed_password==nil
101 if self.hashed_password==nil
100 encrypt_new_password
102 encrypt_new_password
101 end
103 end
102 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
104 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
103 end
105 end
104
106
105 def verify_activation_key(key)
107 def verify_activation_key(key)
106 key == activation_key
108 key == activation_key
107 end
109 end
108
110
109 def self.random_password(length=5)
111 def self.random_password(length=5)
110 chars = 'abcdefghjkmnopqrstuvwxyz'
112 chars = 'abcdefghjkmnopqrstuvwxyz'
111 password = ''
113 password = ''
112 length.times { password << chars[rand(chars.length - 1)] }
114 length.times { password << chars[rand(chars.length - 1)] }
113 password
115 password
114 end
116 end
115
117
116 def self.find_non_admin_with_prefix(prefix='')
118 def self.find_non_admin_with_prefix(prefix='')
117 users = User.find(:all)
119 users = User.find(:all)
118 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
120 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
119 end
121 end
120
122
123 + # Contest information
124 +
125 + def contest_time_left
126 + if Configuration.contest_mode?
127 + return nil if site==nil
128 + return site.time_left
129 + elsif Configuration.indv_contest_mode?
130 + time_limit = Configuration.contest_time_limit
131 + if contest_stat==nil
132 + return (Time.now.gmtime + time_limit) - Time.now.gmtime
133 + else
134 + finish_time = contest_stat.started_at + time_limit
135 + current_time = Time.now.gmtime
136 + if current_time > finish_time
137 + return 0
138 + else
139 + return finish_time - current_time
140 + end
141 + end
142 + else
143 + return nil
144 + end
145 + end
146 +
147 + def contest_finished?
148 + if Configuration.contest_mode?
149 + return false if site==nil
150 + return site.finished?
151 + elsif Configuration.indv_contest_mode?
152 + time_limit = Configuration.contest_time_limit
153 +
154 + return false if contest_stat==nil
155 +
156 + return contest_time_left == 0
157 + else
158 + return false
159 + end
160 + end
161 +
162 + def contest_started?
163 + if Configuration.contest_mode?
164 + return true if site==nil
165 + return site.started
166 + else
167 + return true
168 + end
169 + end
170 +
121 protected
171 protected
122 def encrypt_new_password
172 def encrypt_new_password
123 return if password.blank?
173 return if password.blank?
124 self.salt = (10+rand(90)).to_s
174 self.salt = (10+rand(90)).to_s
125 self.hashed_password = User.encrypt(self.password,self.salt)
175 self.hashed_password = User.encrypt(self.password,self.salt)
126 end
176 end
127
177
128 def assign_default_site
178 def assign_default_site
129 # have to catch error when migrating (because self.site is not available).
179 # have to catch error when migrating (because self.site is not available).
130 begin
180 begin
131 if self.site==nil
181 if self.site==nil
132 self.site = Site.find_by_name('default')
182 self.site = Site.find_by_name('default')
133 if self.site==nil
183 if self.site==nil
134 self.site = Site.find(1) # when 'default has be renamed'
184 self.site = Site.find(1) # when 'default has be renamed'
135 end
185 end
136 end
186 end
137 rescue
187 rescue
138 end
188 end
139 end
189 end
140
190
141 def password_required?
191 def password_required?
142 self.hashed_password.blank? || !self.password.blank?
192 self.hashed_password.blank? || !self.password.blank?
143 end
193 end
144
194
145 def self.encrypt(string,salt)
195 def self.encrypt(string,salt)
146 Digest::SHA1.hexdigest(salt + string)
196 Digest::SHA1.hexdigest(salt + string)
147 end
197 end
148
198
149 def uniqueness_of_email_from_activated_users
199 def uniqueness_of_email_from_activated_users
150 user = User.activated_users.find_by_email(self.email)
200 user = User.activated_users.find_by_email(self.email)
151 if user and (user.login != self.login)
201 if user and (user.login != self.login)
152 self.errors.add_to_base("Email has already been taken")
202 self.errors.add_to_base("Email has already been taken")
153 end
203 end
154 end
204 end
155
205
156 def enough_time_interval_between_same_email_registrations
206 def enough_time_interval_between_same_email_registrations
157 return if !self.new_record?
207 return if !self.new_record?
158 return if self.activated
208 return if self.activated
159 open_user = User.find_by_email(self.email,
209 open_user = User.find_by_email(self.email,
160 :order => 'created_at DESC')
210 :order => 'created_at DESC')
161 if open_user and open_user.created_at and
211 if open_user and open_user.created_at and
162 (open_user.created_at > Time.now.gmtime - 5.minutes)
212 (open_user.created_at > Time.now.gmtime - 5.minutes)
163 self.errors.add_to_base("There are already unactivated registrations with this e-mail address (please wait for 5 minutes)")
213 self.errors.add_to_base("There are already unactivated registrations with this e-mail address (please wait for 5 minutes)")
164 end
214 end
165 end
215 end
166
216
167 def email_validation?
217 def email_validation?
168 begin
218 begin
@@ -1,39 +1,38
1 - content_for :head do
1 - content_for :head do
2 = javascript_include_tag :defaults
2 = javascript_include_tag :defaults
3 %script{:type => 'text/javascript', :src => '/javascripts/announcement_refresh.js'}
3 %script{:type => 'text/javascript', :src => '/javascripts/announcement_refresh.js'}
4
4
5 = user_title_bar(@user)
5 = user_title_bar(@user)
6
6
7 - if @announcements.length!=0
7 - if @announcements.length!=0
8 .announcementbox
8 .announcementbox
9 %span{:class => 'title'}
9 %span{:class => 'title'}
10 Announcements
10 Announcements
11 #announcementbox-body
11 #announcementbox-body
12 = render :partial => 'announcement', :collection => @announcements
12 = render :partial => 'announcement', :collection => @announcements
13
13
14 - if Configuration.show_submitbox_to?(@user)
14 - if Configuration.show_submitbox_to?(@user)
15 .submitbox
15 .submitbox
16 = error_messages_for 'submission'
16 = error_messages_for 'submission'
17 = render :partial => 'submission_box'
17 = render :partial => 'submission_box'
18
18
19
19
20 %hr/
20 %hr/
21
21
22 - - if (Configuration.contest_mode) and (@user.site!=nil) |
22 + - if (Configuration.contest_mode?) and (@user.site!=nil) and (@user.site.started!=true)
23 - and (@user.site.started!=true)
24 %p=t 'main.start_soon'
23 %p=t 'main.start_soon'
25
24
26 - if Configuration.show_tasks_to?(@user)
25 - if Configuration.show_tasks_to?(@user)
27 %table.info
26 %table.info
28 %tr.info-head
27 %tr.info-head
29 %th
28 %th
30 %th Tasks
29 %th Tasks
31 %th # of sub(s)
30 %th # of sub(s)
32 %th Results
31 %th Results
33 = render :partial => 'problem', :collection => @problems
32 = render :partial => 'problem', :collection => @problems
34
33
35 %hr/
34 %hr/
36
35
37 :javascript
36 :javascript
38 Announcement.registerRefreshEventTimer();
37 Announcement.registerRefreshEventTimer();
39
38
@@ -1,78 +1,79
1 # This file is auto-generated from the current state of the database. Instead of editing this file,
1 # This file is auto-generated from the current state of the database. Instead of editing this file,
2 # please use the migrations feature of Active Record to incrementally modify your database, and
2 # please use the migrations feature of Active Record to incrementally modify your database, and
3 # then regenerate this schema definition.
3 # then regenerate this schema definition.
4 #
4 #
5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
6 # to create the application database on another system, you should be using db:schema:load, not running
6 # to create the application database on another system, you should be using db:schema:load, not running
7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
8 # you'll amass, the slower it'll run and the greater likelihood for issues).
8 # you'll amass, the slower it'll run and the greater likelihood for issues).
9 #
9 #
10 # It's strongly recommended to check this file into your version control system.
10 # It's strongly recommended to check this file into your version control system.
11
11
12 - ActiveRecord::Schema.define(:version => 20100113094740) do
12 + ActiveRecord::Schema.define(:version => 20100124054458) do
13
13
14 create_table "announcements", :force => true do |t|
14 create_table "announcements", :force => true do |t|
15 t.string "author"
15 t.string "author"
16 t.text "body"
16 t.text "body"
17 t.boolean "published"
17 t.boolean "published"
18 t.datetime "created_at"
18 t.datetime "created_at"
19 t.datetime "updated_at"
19 t.datetime "updated_at"
20 t.boolean "frontpage", :default => false
20 t.boolean "frontpage", :default => false
21 t.boolean "contest_only", :default => false
21 t.boolean "contest_only", :default => false
22 t.string "title"
22 t.string "title"
23 end
23 end
24
24
25 create_table "configurations", :force => true do |t|
25 create_table "configurations", :force => true do |t|
26 t.string "key"
26 t.string "key"
27 t.string "value_type"
27 t.string "value_type"
28 t.string "value"
28 t.string "value"
29 t.datetime "created_at"
29 t.datetime "created_at"
30 t.datetime "updated_at"
30 t.datetime "updated_at"
31 + t.text "description"
31 end
32 end
32
33
33 create_table "countries", :force => true do |t|
34 create_table "countries", :force => true do |t|
34 t.string "name"
35 t.string "name"
35 t.datetime "created_at"
36 t.datetime "created_at"
36 t.datetime "updated_at"
37 t.datetime "updated_at"
37 end
38 end
38
39
39 create_table "descriptions", :force => true do |t|
40 create_table "descriptions", :force => true do |t|
40 t.text "body"
41 t.text "body"
41 t.boolean "markdowned"
42 t.boolean "markdowned"
42 t.datetime "created_at"
43 t.datetime "created_at"
43 t.datetime "updated_at"
44 t.datetime "updated_at"
44 end
45 end
45
46
46 create_table "grader_processes", :force => true do |t|
47 create_table "grader_processes", :force => true do |t|
47 t.string "host", :limit => 20
48 t.string "host", :limit => 20
48 t.integer "pid"
49 t.integer "pid"
49 t.string "mode"
50 t.string "mode"
50 t.boolean "active"
51 t.boolean "active"
51 t.datetime "created_at"
52 t.datetime "created_at"
52 t.datetime "updated_at"
53 t.datetime "updated_at"
53 t.integer "task_id"
54 t.integer "task_id"
54 t.string "task_type"
55 t.string "task_type"
55 t.boolean "terminated"
56 t.boolean "terminated"
56 end
57 end
57
58
58 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
59 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
59
60
60 create_table "languages", :force => true do |t|
61 create_table "languages", :force => true do |t|
61 t.string "name", :limit => 10
62 t.string "name", :limit => 10
62 t.string "pretty_name"
63 t.string "pretty_name"
63 t.string "ext", :limit => 10
64 t.string "ext", :limit => 10
64 t.string "common_ext"
65 t.string "common_ext"
65 end
66 end
66
67
67 create_table "messages", :force => true do |t|
68 create_table "messages", :force => true do |t|
68 t.integer "sender_id"
69 t.integer "sender_id"
69 t.integer "receiver_id"
70 t.integer "receiver_id"
70 t.integer "replying_message_id"
71 t.integer "replying_message_id"
71 t.text "body"
72 t.text "body"
72 t.boolean "replied"
73 t.boolean "replied"
73 t.datetime "created_at"
74 t.datetime "created_at"
74 t.datetime "updated_at"
75 t.datetime "updated_at"
75 end
76 end
76
77
77 create_table "problems", :force => true do |t|
78 create_table "problems", :force => true do |t|
78 t.string "name", :limit => 30
79 t.string "name", :limit => 30
@@ -84,121 +85,149
84 t.integer "description_id"
85 t.integer "description_id"
85 t.boolean "test_allowed"
86 t.boolean "test_allowed"
86 t.boolean "output_only"
87 t.boolean "output_only"
87 end
88 end
88
89
89 create_table "rights", :force => true do |t|
90 create_table "rights", :force => true do |t|
90 t.string "name"
91 t.string "name"
91 t.string "controller"
92 t.string "controller"
92 t.string "action"
93 t.string "action"
93 end
94 end
94
95
95 create_table "rights_roles", :id => false, :force => true do |t|
96 create_table "rights_roles", :id => false, :force => true do |t|
96 t.integer "right_id"
97 t.integer "right_id"
97 t.integer "role_id"
98 t.integer "role_id"
98 end
99 end
99
100
100 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
101 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
101
102
102 create_table "roles", :force => true do |t|
103 create_table "roles", :force => true do |t|
103 t.string "name"
104 t.string "name"
104 end
105 end
105
106
106 create_table "roles_users", :id => false, :force => true do |t|
107 create_table "roles_users", :id => false, :force => true do |t|
107 t.integer "role_id"
108 t.integer "role_id"
108 t.integer "user_id"
109 t.integer "user_id"
109 end
110 end
110
111
111 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
112 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
112
113
113 create_table "sessions", :force => true do |t|
114 create_table "sessions", :force => true do |t|
114 t.string "session_id"
115 t.string "session_id"
115 t.text "data"
116 t.text "data"
116 t.datetime "updated_at"
117 t.datetime "updated_at"
117 end
118 end
118
119
119 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
120 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
120 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
121 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
121
122
122 create_table "sites", :force => true do |t|
123 create_table "sites", :force => true do |t|
123 t.string "name"
124 t.string "name"
124 t.boolean "started"
125 t.boolean "started"
125 t.datetime "start_time"
126 t.datetime "start_time"
126 t.datetime "created_at"
127 t.datetime "created_at"
127 t.datetime "updated_at"
128 t.datetime "updated_at"
128 t.integer "country_id"
129 t.integer "country_id"
129 t.string "password"
130 t.string "password"
130 end
131 end
131
132
133 + create_table "submission_statuses", :force => true do |t|
134 + t.integer "user_id"
135 + t.integer "problem_id"
136 + t.boolean "passed"
137 + t.integer "submission_count"
138 + t.datetime "created_at"
139 + t.datetime "updated_at"
140 + end
141 +
132 create_table "submissions", :force => true do |t|
142 create_table "submissions", :force => true do |t|
133 t.integer "user_id"
143 t.integer "user_id"
134 t.integer "problem_id"
144 t.integer "problem_id"
135 t.integer "language_id"
145 t.integer "language_id"
136 t.text "source"
146 t.text "source"
137 t.binary "binary"
147 t.binary "binary"
138 t.datetime "submitted_at"
148 t.datetime "submitted_at"
139 t.datetime "compiled_at"
149 t.datetime "compiled_at"
140 t.text "compiler_message"
150 t.text "compiler_message"
141 t.datetime "graded_at"
151 t.datetime "graded_at"
142 t.integer "points"
152 t.integer "points"
143 t.text "grader_comment"
153 t.text "grader_comment"
144 t.integer "number"
154 t.integer "number"
145 t.string "source_filename"
155 t.string "source_filename"
146 end
156 end
147
157
148 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
158 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
149 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
159 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
150
160
151 create_table "tasks", :force => true do |t|
161 create_table "tasks", :force => true do |t|
152 t.integer "submission_id"
162 t.integer "submission_id"
153 t.datetime "created_at"
163 t.datetime "created_at"
154 t.integer "status"
164 t.integer "status"
155 t.datetime "updated_at"
165 t.datetime "updated_at"
156 end
166 end
157
167
168 + create_table "test_pair_assignments", :force => true do |t|
169 + t.integer "user_id"
170 + t.integer "problem_id"
171 + t.integer "test_pair_id"
172 + t.integer "test_pair_number"
173 + t.integer "request_number"
174 + t.datetime "created_at"
175 + t.datetime "updated_at"
176 + t.boolean "submitted"
177 + end
178 +
158 create_table "test_pairs", :force => true do |t|
179 create_table "test_pairs", :force => true do |t|
159 t.integer "problem_id"
180 t.integer "problem_id"
160 t.text "input"
181 t.text "input"
161 t.text "solution"
182 t.text "solution"
162 t.datetime "created_at"
183 t.datetime "created_at"
163 t.datetime "updated_at"
184 t.datetime "updated_at"
185 + t.integer "number"
164 end
186 end
165
187
166 create_table "test_requests", :force => true do |t|
188 create_table "test_requests", :force => true do |t|
167 t.integer "user_id"
189 t.integer "user_id"
168 t.integer "problem_id"
190 t.integer "problem_id"
169 t.integer "submission_id"
191 t.integer "submission_id"
170 t.string "input_file_name"
192 t.string "input_file_name"
171 t.string "output_file_name"
193 t.string "output_file_name"
172 t.string "running_stat"
194 t.string "running_stat"
173 t.integer "status"
195 t.integer "status"
174 t.datetime "updated_at"
196 t.datetime "updated_at"
175 t.datetime "submitted_at"
197 t.datetime "submitted_at"
176 t.datetime "compiled_at"
198 t.datetime "compiled_at"
177 t.text "compiler_message"
199 t.text "compiler_message"
178 t.datetime "graded_at"
200 t.datetime "graded_at"
179 t.string "grader_comment"
201 t.string "grader_comment"
180 t.datetime "created_at"
202 t.datetime "created_at"
181 t.float "running_time"
203 t.float "running_time"
182 t.string "exit_status"
204 t.string "exit_status"
183 t.integer "memory_usage"
205 t.integer "memory_usage"
184 end
206 end
185
207
186 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
208 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
187
209
210 + create_table "user_contest_stats", :force => true do |t|
211 + t.integer "user_id"
212 + t.datetime "started_at"
213 + t.datetime "created_at"
214 + t.datetime "updated_at"
215 + end
216 +
188 create_table "users", :force => true do |t|
217 create_table "users", :force => true do |t|
189 t.string "login", :limit => 50
218 t.string "login", :limit => 50
190 t.string "full_name"
219 t.string "full_name"
191 t.string "hashed_password"
220 t.string "hashed_password"
192 t.string "salt", :limit => 5
221 t.string "salt", :limit => 5
193 t.string "alias"
222 t.string "alias"
194 t.string "email"
223 t.string "email"
195 t.integer "site_id"
224 t.integer "site_id"
196 t.integer "country_id"
225 t.integer "country_id"
197 t.boolean "activated", :default => false
226 t.boolean "activated", :default => false
198 t.datetime "created_at"
227 t.datetime "created_at"
199 t.datetime "updated_at"
228 t.datetime "updated_at"
200 end
229 end
201
230
202 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
231 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
203
232
204 end
233 end
You need to be logged in to leave comments. Login now