Description:
[web] site start/stop supports git-svn-id: http://theory.cpe.ku.ac.th/grader/web/trunk@251 6386c4cd-e34a-4fa8-8920-d93eb39b512e
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r123:39d238830bb8 - - 14 files changed: 252 inserted, 31 deleted

@@ -0,0 +1,35
1 + class SiteController < ApplicationController
2 +
3 + before_filter :site_admin_authorization
4 +
5 + def index
6 + if @site.started
7 + render :action => 'started', :layout => 'empty'
8 + else
9 + render :action => 'prompt', :layout => 'empty'
10 + end
11 + end
12 +
13 + def start
14 + @site.started = true
15 + @site.start_time = Time.new.gmtime
16 + @site.save
17 + redirect_to :action => 'index'
18 + end
19 +
20 + protected
21 + def site_admin_authorization
22 + if session[:site_id]==nil
23 + redirect_to :controller => 'main', :action => 'login' and return
24 + end
25 + begin
26 + @site = Site.find(session[:site_id], :include => :country)
27 + rescue ActiveRecord::RecordNotFound
28 + @site = nil
29 + end
30 + if @site==nil
31 + redirect_to :controller => 'main', :action => 'login' and return
32 + end
33 + end
34 +
35 + end
@@ -0,0 +1,2
1 + module SiteHelper
2 + end
@@ -0,0 +1,56
1 + %h1= Configuration['ui.front.title']
2 +
3 + %b= Configuration['ui.front.welcome_message']
4 + %br/
5 + Please login to see the problem list.
6 + %br/
7 + %br/
8 +
9 + - if flash[:notice]
10 + %hr/
11 + %b= flash[:notice]
12 + %hr/
13 +
14 + %div{ :style => "border: solid 1px gray; padding: 2px; background: #f0f0f0;"}
15 + - form_tag :controller => 'login', :action => 'login' do
16 + %table
17 + %tr
18 + %td{:align => "right"} Login:
19 + %td= text_field_tag 'login'
20 + %tr
21 + %td{:align => "right"} Password:
22 + %td= password_field_tag
23 + = submit_tag 'Login'
24 +
25 + %br/
26 +
27 + %script{:type => 'text/javascript'}
28 + var siteList = new Array();
29 + - @countries.each do |country|
30 + = "siteList[#{country.id}] = new Array();"
31 + - country.sites.each do |site|
32 + = "siteList[#{country.id}][#{site.id}] = \"#{site.name}\";"
33 +
34 + var allSiteList = new Array();
35 + - @site_select.each do |sel|
36 + = "allSiteList[#{sel[1]}]=\"#{sel[0]}\";"
37 +
38 + %script{:type => 'text/javascript', :src => '/javascripts/site_update.js'}
39 +
40 + %div{ :style => "border: solid 1px gray; padding: 2px; background: #f0f0f0;"}
41 + %b For Site Administrator.
42 + %br/
43 + Please select your country and site and login.
44 + .login-box
45 + - form_for :login, nil, :url => {:controller => 'login', :action => 'site_login'} do |f|
46 + Country:
47 + = select :site_country, :id, @country_select_with_all, {}, {:onchange => "updateSiteList();", :onclick => "updateSiteList();" }
48 + Site:
49 + = select :login, :site_id, @site_select
50 + %br/
51 + Password:
52 + = f.password_field :password
53 + = submit_tag "Site Administrator Login"
54 +
55 + %script{:type => 'text/javascript'}
56 + updateSiteList();
@@ -0,0 +1,22
1 + %h2
2 + Contest Administration for site:
3 + = "#{@site.name}, #{@site.country.name}"
4 +
5 +
6 + Current time at the server is
7 + = "#{format_short_time(Time.new.gmtime)} UTC"
8 + (please
9 + = link_to 'refresh', :action => 'index'
10 + to update)
11 + %br/
12 + %br/
13 +
14 + - form_tag :action => 'start' do
15 + When you're ready, you can click the button below to start the contest.
16 + %br/
17 + Please make sure that the contestants are ready.
18 + After the contest is started, it <b>cannot</b> be paused or stopped.
19 + %br/
20 + = submit_tag 'Start the Contest.'
21 +
22 +
@@ -0,0 +1,29
1 + %h2
2 + Contest Administration for site:
3 + = "#{@site.name}, #{@site.country.name}"
4 +
5 + - curr_time = Time.new.gmtime
6 +
7 + - if @site.finished?
8 + %h3 Contest ended.
9 + - else
10 + %h3 Contest started.
11 +
12 + Current time at the server is
13 + = "#{format_short_time(curr_time)} UTC"
14 + (please
15 + = link_to 'refresh', :action => 'index'
16 + to update)
17 + %br/
18 + %br/
19 +
20 + The contest at your site has been started at
21 + = "#{format_short_time(@site.start_time)} UTC"
22 +
23 + %br/
24 +
25 + %h3
26 + Time left:
27 + = "#{Time.at(@site.time_left).gmtime.strftime("%X")}"
28 +
29 +
@@ -0,0 +1,32
1 + function updateSiteList() {
2 + currentCountry = document.getElementById("site_country_id").value;
3 +
4 + sites = siteList[currentCountry];
5 + siteSelect = document.getElementById("login_site_id");
6 + old_len = siteSelect.length;
7 + // clear old box
8 + for(i=0; i<old_len; i++) siteSelect.remove(0);
9 +
10 + if(currentCountry==0) {
11 + for(i=0; i<allSiteList.length; i++) {
12 + if(allSiteList[i]!=null) {
13 + try {
14 + siteSelect.add(new Option(allSiteList[i],""+i,false,false),null);
15 + } catch(ex) {
16 + siteSelect.add(new Option(allSiteList[i],""+i,false,false));
17 + }
18 + }
19 + }
20 + } else {
21 + for(i=0; i<sites.length; i++) {
22 + if(sites[i]!=null) {
23 + try {
24 + siteSelect.add(new Option(sites[i],""+i,false,false),null);
25 + } catch(ex) {
26 + siteSelect.add(new Option(sites[i],""+i,false,false));
27 + }
28 + }
29 + }
30 + }
31 + }
32 + No newline at end of file
@@ -0,0 +1,8
1 + require File.dirname(__FILE__) + '/../test_helper'
2 +
3 + class SiteControllerTest < ActionController::TestCase
4 + # Replace this with your real tests.
5 + def test_truth
6 + assert true
7 + end
8 + end
@@ -12,13 +12,32
12 redirect_to :controller => 'main', :action => 'list'
12 redirect_to :controller => 'main', :action => 'list'
13 if user.admin?
13 if user.admin?
14 session[:admin] = true
14 session[:admin] = true
15 else
15 else
16 session[:admin] = false
16 session[:admin] = false
17 end
17 end
18 else
18 else
19 flash[:notice] = 'Wrong password'
19 flash[:notice] = 'Wrong password'
20 redirect_to :controller => 'main', :action => 'login'
20 redirect_to :controller => 'main', :action => 'login'
21 end
21 end
22 end
22 end
23
23
24 + def site_login
25 + begin
26 + site = Site.find(params[:login][:site_id])
27 + rescue ActiveRecord::RecordNotFound
28 + site = nil
29 + end
30 + if site==nil
31 + flash[:notice] = 'Wrong site'
32 + redirect_to :controller => 'main', :action => 'login' and return
33 + end
34 + if site.password == params[:login][:password]
35 + session[:site_id] = site.id
36 + redirect_to :controller => 'site', :action => 'index'
37 + else
38 + flash[:notice] = 'Wrong site password'
39 + redirect_to :controller => 'main', :action => 'login'
40 + end
41 + end
42 +
24 end
43 end
@@ -1,37 +1,55
1 class MainController < ApplicationController
1 class MainController < ApplicationController
2
2
3 SYSTEM_MODE_CONF_KEY = 'system.mode'
3 SYSTEM_MODE_CONF_KEY = 'system.mode'
4
4
5 before_filter :authenticate, :except => [:index, :login]
5 before_filter :authenticate, :except => [:index, :login]
6 - before_filter :check_viewability
6 + before_filter :check_viewability, :except => [:index, :login]
7
7
8 #
8 #
9 # COMMENT OUT: filter in each action instead
9 # COMMENT OUT: filter in each action instead
10 #
10 #
11 # before_filter :verify_time_limit, :only => [:submit]
11 # before_filter :verify_time_limit, :only => [:submit]
12
12
13 verify :method => :post, :only => [:submit],
13 verify :method => :post, :only => [:submit],
14 :redirect_to => { :action => :index }
14 :redirect_to => { :action => :index }
15
15
16
16
17 def index
17 def index
18 redirect_to :action => 'login'
18 redirect_to :action => 'login'
19 end
19 end
20
20
21 def login
21 def login
22 saved_notice = flash[:notice]
22 saved_notice = flash[:notice]
23 reset_session
23 reset_session
24 flash[:notice] = saved_notice
24 flash[:notice] = saved_notice
25
25
26 + #
27 + # These are for site administrator login
28 + #
29 + @countries = Country.find(:all)
30 + @country_select = @countries.collect { |c| [c.name, c.id] }
31 +
32 + @country_select_with_all = [['Any',0]]
33 + @countries.each do |country|
34 + @country_select_with_all << [country.name, country.id]
35 + end
36 +
37 + @site_select = []
38 + @countries.each do |country|
39 + country.sites.each do |site|
40 + @site_select << ["#{site.name}, #{country.name}", site.id]
41 + end
42 + end
43 +
26 render :action => 'login', :layout => 'empty'
44 render :action => 'login', :layout => 'empty'
27 end
45 end
28
46
29 def list
47 def list
30 prepare_list_information
48 prepare_list_information
31 end
49 end
32
50
33 def help
51 def help
34 @user = User.find(session[:user_id])
52 @user = User.find(session[:user_id])
35 end
53 end
36
54
37 def submit
55 def submit
@@ -78,13 +78,14
78
78
79 # DELETE /sites/1
79 # DELETE /sites/1
80 # DELETE /sites/1.xml
80 # DELETE /sites/1.xml
81 def destroy
81 def destroy
82 @site = Site.find(params[:id])
82 @site = Site.find(params[:id])
83 @site.destroy
83 @site.destroy
84
84
85 respond_to do |format|
85 respond_to do |format|
86 format.html { redirect_to(sites_url) }
86 format.html { redirect_to(sites_url) }
87 format.xml { head :ok }
87 format.xml { head :ok }
88 end
88 end
89 end
89 end
90 +
90 end
91 end
@@ -54,53 +54,60
54 end
54 end
55
55
56 def read_textfile(fname,max_size=2048)
56 def read_textfile(fname,max_size=2048)
57 begin
57 begin
58 File.open(fname).read(max_size)
58 File.open(fname).read(max_size)
59 rescue
59 rescue
60 nil
60 nil
61 end
61 end
62 end
62 end
63
63
64 def user_title_bar(user)
64 def user_title_bar(user)
65 header = ''
65 header = ''
66 + time_left = ''
66
67
67 #
68 #
68 # if the contest is over
69 # if the contest is over
69 - if Configuration[SYSTEM_MODE_CONF_KEY]=='contest' and
70 + if Configuration[SYSTEM_MODE_CONF_KEY]=='contest'
70 - user.site!=nil and user.site.finished?
71 + if user.site!=nil and user.site.finished?
71 - header = <<CONTEST_OVER
72 + header = <<CONTEST_OVER
72 <tr><td colspan="2" align="center">
73 <tr><td colspan="2" align="center">
73 <span class="contest-over-msg">THE CONTEST IS OVER</span>
74 <span class="contest-over-msg">THE CONTEST IS OVER</span>
74 </td></tr>
75 </td></tr>
75 CONTEST_OVER
76 CONTEST_OVER
77 + end
78 + if user.site!=nil
79 + time_left = ". Time left: #{Time.at(user.site.time_left).gmtime.strftime("%X")}"
80 + end
76 end
81 end
77
82
78 #
83 #
79 # if the contest is in the anaysis mode
84 # if the contest is in the anaysis mode
80 if Configuration[SYSTEM_MODE_CONF_KEY]=='analysis'
85 if Configuration[SYSTEM_MODE_CONF_KEY]=='analysis'
81 header = <<ANALYSISMODE
86 header = <<ANALYSISMODE
82 <tr><td colspan="2" align="center">
87 <tr><td colspan="2" align="center">
83 <span class="contest-over-msg">ANALYSIS MODE</span>
88 <span class="contest-over-msg">ANALYSIS MODE</span>
84 </td></tr>
89 </td></tr>
85 ANALYSISMODE
90 ANALYSISMODE
86 end
91 end
87
92
88 #
93 #
89 # build real title bar
94 # build real title bar
90 <<TITLEBAR
95 <<TITLEBAR
91 <div class="title">
96 <div class="title">
92 <table>
97 <table>
93 #{header}
98 #{header}
94 <tr>
99 <tr>
95 <td class="left-col">
100 <td class="left-col">
96 #{user.full_name}<br/>
101 #{user.full_name}<br/>
97 - Current time is #{format_short_time(Time.new.gmtime)} UTC<br/>
102 + Current time is #{format_short_time(Time.new.gmtime)} UTC
103 + #{time_left}
104 + <br/>
98 </td>
105 </td>
99 <td class="right-col">APIO'08</td>
106 <td class="right-col">APIO'08</td>
100 </tr>
107 </tr>
101 </table>
108 </table>
102 </div>
109 </div>
103 TITLEBAR
110 TITLEBAR
104 end
111 end
105
112
106 end
113 end
@@ -1,23 +1,41
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
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 + finish_time = self.start_time + h.hour + m.minute
18 + current_time = Time.now.gmtime
19 +
20 + if current_time > finish_time
21 + return current_time - current_time
22 + else
23 + finish_time - current_time
24 + end
25 + else
26 + nil
27 + end
28 + end
29 +
12 def finished?
30 def finished?
13 if !self.started
31 if !self.started
14 return false
32 return false
15 end
33 end
16
34
17 contest_time = Configuration['contest.time_limit']
35 contest_time = Configuration['contest.time_limit']
18 if tmatch = /(\d+):(\d+)/.match(contest_time)
36 if tmatch = /(\d+):(\d+)/.match(contest_time)
19 h = tmatch[1].to_i
37 h = tmatch[1].to_i
20 m = tmatch[2].to_i
38 m = tmatch[2].to_i
21 return Time.now.gmtime > (self.start_time + h.hour + m.minute)
39 return Time.now.gmtime > (self.start_time + h.hour + m.minute)
22 else
40 else
23 false
41 false
@@ -1,15 +1,14
1 ActionController::Routing::Routes.draw do |map|
1 ActionController::Routing::Routes.draw do |map|
2 map.resources :announcements
2 map.resources :announcements
3 -
4 map.resources :sites
3 map.resources :sites
5
4
6 # The priority is based upon order of creation: first created -> highest priority.
5 # The priority is based upon order of creation: first created -> highest priority.
7
6
8 # Sample of regular route:
7 # Sample of regular route:
9 # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
8 # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
10 # Keep in mind you can assign values other than :controller and :action
9 # Keep in mind you can assign values other than :controller and :action
11
10
12 # Sample of named route:
11 # Sample of named route:
13 # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
12 # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
14 # This route can be invoked with purchase_url(:id => product.id)
13 # This route can be invoked with purchase_url(:id => product.id)
15
14
deleted file
You need to be logged in to leave comments. Login now