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: 251 inserted, 30 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
@@ -1,24 +1,43
1 1 class LoginController < ApplicationController
2 2
3 3 def index
4 4 # show login screen
5 5 reset_session
6 6 redirect_to :controller => 'main', :action => 'login'
7 7 end
8 8
9 9 def login
10 10 if user = User.authenticate(params[:login], params[:password])
11 11 session[:user_id] = user.id
12 12 redirect_to :controller => 'main', :action => 'list'
13 13 if user.admin?
14 14 session[:admin] = true
15 15 else
16 16 session[:admin] = false
17 17 end
18 18 else
19 19 flash[:notice] = 'Wrong password'
20 20 redirect_to :controller => 'main', :action => 'login'
21 21 end
22 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
24 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 +
43 + end
@@ -1,121 +1,139
1 1 class MainController < ApplicationController
2 2
3 3 SYSTEM_MODE_CONF_KEY = 'system.mode'
4 4
5 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 9 # COMMENT OUT: filter in each action instead
10 10 #
11 11 # before_filter :verify_time_limit, :only => [:submit]
12 12
13 13 verify :method => :post, :only => [:submit],
14 14 :redirect_to => { :action => :index }
15 15
16 16
17 17 def index
18 18 redirect_to :action => 'login'
19 19 end
20 20
21 21 def login
22 22 saved_notice = flash[:notice]
23 23 reset_session
24 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 44 render :action => 'login', :layout => 'empty'
27 45 end
28 46
29 47 def list
30 48 prepare_list_information
31 49 end
32 50
33 51 def help
34 52 @user = User.find(session[:user_id])
35 53 end
36 54
37 55 def submit
38 56 user = User.find(session[:user_id])
39 57
40 58 @submission = Submission.new(params[:submission])
41 59 @submission.user = user
42 60 @submission.language_id = 0
43 61 if params['file']!=''
44 62 @submission.source = params['file'].read
45 63 @submission.source_filename = params['file'].original_filename
46 64 end
47 65 @submission.submitted_at = Time.new.gmtime
48 66
49 67 if Configuration[SYSTEM_MODE_CONF_KEY]=='contest' and
50 68 user.site!=nil and user.site.finished?
51 69 @submission.errors.add_to_base "The contest is over."
52 70 prepare_list_information
53 71 render :action => 'list' and return
54 72 end
55 73
56 74 if @submission.valid?
57 75 if @submission.save == false
58 76 flash[:notice] = 'Error saving your submission'
59 77 elsif Task.create(:submission_id => @submission.id,
60 78 :status => Task::STATUS_INQUEUE) == false
61 79 flash[:notice] = 'Error adding your submission to task queue'
62 80 end
63 81 else
64 82 prepare_list_information
65 83 render :action => 'list' and return
66 84 end
67 85 redirect_to :action => 'list'
68 86 end
69 87
70 88 def source
71 89 submission = Submission.find(params[:id])
72 90 if submission.user_id == session[:user_id]
73 91 if submission.problem.output_only
74 92 fname = submission.source_filename
75 93 else
76 94 fname = submission.problem.name + '.' + submission.language.ext
77 95 end
78 96 send_data(submission.source,
79 97 {:filename => fname,
80 98 :type => 'text/plain'})
81 99 else
82 100 flash[:notice] = 'Error viewing source'
83 101 redirect_to :action => 'list'
84 102 end
85 103 end
86 104
87 105 def compiler_msg
88 106 @submission = Submission.find(params[:id])
89 107 if @submission.user_id == session[:user_id]
90 108 render :action => 'compiler_msg', :layout => 'empty'
91 109 else
92 110 flash[:notice] = 'Error viewing source'
93 111 redirect_to :action => 'list'
94 112 end
95 113 end
96 114
97 115 def submission
98 116 @user = User.find(session[:user_id])
99 117 @problems = Problem.find_available_problems
100 118 if params[:id]==nil
101 119 @problem = nil
102 120 @submissions = nil
103 121 else
104 122 @problem = Problem.find_by_name(params[:id])
105 123 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
106 124 end
107 125 end
108 126
109 127 def error
110 128 @user = User.find(session[:user_id])
111 129 end
112 130
113 131 protected
114 132 def prepare_list_information
115 133 @problems = Problem.find_available_problems
116 134 @prob_submissions = Array.new
117 135 @user = User.find(session[:user_id])
118 136 @problems.each do |p|
119 137 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
120 138 if sub!=nil
121 139 @prob_submissions << { :count => sub.number, :submission => sub }
@@ -1,90 +1,91
1 1 class SitesController < ApplicationController
2 2
3 3 before_filter :admin_authorization
4 4
5 5 # GET /sites
6 6 # GET /sites.xml
7 7 def index
8 8 @sites = Site.find(:all)
9 9
10 10 respond_to do |format|
11 11 format.html # index.html.erb
12 12 format.xml { render :xml => @sites }
13 13 end
14 14 end
15 15
16 16 # GET /sites/1
17 17 # GET /sites/1.xml
18 18 def show
19 19 @site = Site.find(params[:id])
20 20
21 21 respond_to do |format|
22 22 format.html # show.html.erb
23 23 format.xml { render :xml => @site }
24 24 end
25 25 end
26 26
27 27 # GET /sites/new
28 28 # GET /sites/new.xml
29 29 def new
30 30 @site = Site.new
31 31
32 32 respond_to do |format|
33 33 format.html # new.html.erb
34 34 format.xml { render :xml => @site }
35 35 end
36 36 end
37 37
38 38 # GET /sites/1/edit
39 39 def edit
40 40 @site = Site.find(params[:id])
41 41 end
42 42
43 43 # POST /sites
44 44 # POST /sites.xml
45 45 def create
46 46 @site = Site.new(params[:site])
47 47 @site.clear_start_time_if_not_started
48 48
49 49 respond_to do |format|
50 50 if @site.save
51 51 flash[:notice] = 'Site was successfully created.'
52 52 format.html { redirect_to(@site) }
53 53 format.xml { render :xml => @site, :status => :created, :location => @site }
54 54 else
55 55 format.html { render :action => "new" }
56 56 format.xml { render :xml => @site.errors, :status => :unprocessable_entity }
57 57 end
58 58 end
59 59 end
60 60
61 61 # PUT /sites/1
62 62 # PUT /sites/1.xml
63 63 def update
64 64 @site = Site.find(params[:id])
65 65 @site.clear_start_time_if_not_started
66 66
67 67 respond_to do |format|
68 68 if @site.update_attributes(params[:site])
69 69 flash[:notice] = 'Site was successfully updated.'
70 70 format.html { redirect_to(@site) }
71 71 format.xml { head :ok }
72 72 else
73 73 format.html { render :action => "edit" }
74 74 format.xml { render :xml => @site.errors, :status => :unprocessable_entity }
75 75 end
76 76 end
77 77 end
78 78
79 79 # DELETE /sites/1
80 80 # DELETE /sites/1.xml
81 81 def destroy
82 82 @site = Site.find(params[:id])
83 83 @site.destroy
84 84
85 85 respond_to do |format|
86 86 format.html { redirect_to(sites_url) }
87 87 format.xml { head :ok }
88 88 end
89 89 end
90 +
90 91 end
@@ -1,106 +1,113
1 1 # Methods added to this helper will be available to all templates in the application.
2 2 module ApplicationHelper
3 3
4 4 SYSTEM_MODE_CONF_KEY = 'system.mode'
5 5
6 6 def user_header
7 7 menu_items = ''
8 8 user = User.find(session[:user_id])
9 9
10 10 if (user!=nil) and (session[:admin])
11 11 # admin menu
12 12 menu_items << "<b>Administrative task:</b> "
13 13 append_to menu_items, '[Announcements]', 'announcements', 'index'
14 14 append_to menu_items, '[Msg console]', 'messages', 'console'
15 15 append_to menu_items, '[Problem admin]', 'problems', 'index'
16 16 append_to menu_items, '[User admin]', 'user_admin', 'index'
17 17 append_to menu_items, '[User stat]', 'user_admin', 'user_stat'
18 18 append_to menu_items, '[Graders]', 'graders', 'list'
19 19 append_to menu_items, '[Site config]', 'configurations', 'index'
20 20 menu_items << "<br/>"
21 21 end
22 22
23 23 # main page
24 24 append_to menu_items, '[Main]', 'main', 'list'
25 25 append_to menu_items, '[Messages]', 'messages', 'list'
26 26
27 27 if (user!=nil) and (Configuration.show_tasks_to?(user))
28 28 append_to menu_items, '[Tasks]', 'tasks', 'list'
29 29 append_to menu_items, '[Submissions]', 'main', 'submission'
30 30 append_to menu_items, '[Test]', 'test', 'index'
31 31 end
32 32 append_to menu_items, '[Help]', 'main', 'help'
33 33 #append_to menu_items, '[Settings]', 'users', 'index'
34 34 append_to menu_items, '[Log out]', 'main', 'login'
35 35
36 36 menu_items
37 37 end
38 38
39 39 def append_to(option,label, controller, action)
40 40 option << ' ' if option!=''
41 41 option << link_to_unless_current(label,
42 42 :controller => controller,
43 43 :action => action)
44 44 end
45 45
46 46 def format_short_time(time)
47 47 now = Time.now.gmtime
48 48 st = ''
49 49 if (time.yday != now.yday) or
50 50 (time.year != now.year)
51 51 st = time.strftime("%x ")
52 52 end
53 53 st + time.strftime("%X")
54 54 end
55 55
56 56 def read_textfile(fname,max_size=2048)
57 57 begin
58 58 File.open(fname).read(max_size)
59 59 rescue
60 60 nil
61 61 end
62 62 end
63 63
64 64 def user_title_bar(user)
65 65 header = ''
66 + time_left = ''
66 67
67 68 #
68 69 # if the contest is over
69 - if Configuration[SYSTEM_MODE_CONF_KEY]=='contest' and
70 - user.site!=nil and user.site.finished?
70 + if Configuration[SYSTEM_MODE_CONF_KEY]=='contest'
71 + if user.site!=nil and user.site.finished?
71 72 header = <<CONTEST_OVER
72 73 <tr><td colspan="2" align="center">
73 74 <span class="contest-over-msg">THE CONTEST IS OVER</span>
74 75 </td></tr>
75 76 CONTEST_OVER
76 77 end
78 + if user.site!=nil
79 + time_left = ". Time left: #{Time.at(user.site.time_left).gmtime.strftime("%X")}"
80 + end
81 + end
77 82
78 83 #
79 84 # if the contest is in the anaysis mode
80 85 if Configuration[SYSTEM_MODE_CONF_KEY]=='analysis'
81 86 header = <<ANALYSISMODE
82 87 <tr><td colspan="2" align="center">
83 88 <span class="contest-over-msg">ANALYSIS MODE</span>
84 89 </td></tr>
85 90 ANALYSISMODE
86 91 end
87 92
88 93 #
89 94 # build real title bar
90 95 <<TITLEBAR
91 96 <div class="title">
92 97 <table>
93 98 #{header}
94 99 <tr>
95 100 <td class="left-col">
96 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 105 </td>
99 106 <td class="right-col">APIO'08</td>
100 107 </tr>
101 108 </table>
102 109 </div>
103 110 TITLEBAR
104 111 end
105 112
106 113 end
@@ -1,27 +1,45
1 1 class Site < ActiveRecord::Base
2 2
3 3 belongs_to :country
4 4 has_many :users
5 5
6 6 def clear_start_time_if_not_started
7 7 if !self.started
8 8 self.start_time = nil
9 9 end
10 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 30 def finished?
13 31 if !self.started
14 32 return false
15 33 end
16 34
17 35 contest_time = Configuration['contest.time_limit']
18 36 if tmatch = /(\d+):(\d+)/.match(contest_time)
19 37 h = tmatch[1].to_i
20 38 m = tmatch[2].to_i
21 39 return Time.now.gmtime > (self.start_time + h.hour + m.minute)
22 40 else
23 41 false
24 42 end
25 43 end
26 44
27 45 end
@@ -1,27 +1,26
1 1 ActionController::Routing::Routes.draw do |map|
2 2 map.resources :announcements
3 -
4 3 map.resources :sites
5 4
6 5 # The priority is based upon order of creation: first created -> highest priority.
7 6
8 7 # Sample of regular route:
9 8 # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
10 9 # Keep in mind you can assign values other than :controller and :action
11 10
12 11 # Sample of named route:
13 12 # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
14 13 # This route can be invoked with purchase_url(:id => product.id)
15 14
16 15 # You can have the root of your site routed by hooking up ''
17 16 # -- just remember to delete public/index.html.
18 17 map.connect '', :controller => 'main', :action => 'login'
19 18
20 19 # Allow downloading Web Service WSDL as a file with an extension
21 20 # instead of a file named 'wsdl'
22 21 map.connect ':controller/service.wsdl', :action => 'wsdl'
23 22
24 23 # Install the default route as the lowest priority.
25 24 map.connect ':controller/:action/:id.:format'
26 25 map.connect ':controller/:action/:id'
27 26 end
deleted file
You need to be logged in to leave comments. Login now