Description:
[web] added site and time out basic functionality git-svn-id: http://theory.cpe.ku.ac.th/grader/web/trunk@169 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

r85:f0e9de51d9aa - - 23 files changed: 442 inserted, 9 deleted

@@ -0,0 +1,87
1 + class SitesController < ApplicationController
2 + # GET /sites
3 + # GET /sites.xml
4 + def index
5 + @sites = Site.find(:all)
6 +
7 + respond_to do |format|
8 + format.html # index.html.erb
9 + format.xml { render :xml => @sites }
10 + end
11 + end
12 +
13 + # GET /sites/1
14 + # GET /sites/1.xml
15 + def show
16 + @site = Site.find(params[:id])
17 +
18 + respond_to do |format|
19 + format.html # show.html.erb
20 + format.xml { render :xml => @site }
21 + end
22 + end
23 +
24 + # GET /sites/new
25 + # GET /sites/new.xml
26 + def new
27 + @site = Site.new
28 +
29 + respond_to do |format|
30 + format.html # new.html.erb
31 + format.xml { render :xml => @site }
32 + end
33 + end
34 +
35 + # GET /sites/1/edit
36 + def edit
37 + @site = Site.find(params[:id])
38 + end
39 +
40 + # POST /sites
41 + # POST /sites.xml
42 + def create
43 + @site = Site.new(params[:site])
44 + @site.clear_start_time_if_not_started
45 +
46 + respond_to do |format|
47 + if @site.save
48 + flash[:notice] = 'Site was successfully created.'
49 + format.html { redirect_to(@site) }
50 + format.xml { render :xml => @site, :status => :created, :location => @site }
51 + else
52 + format.html { render :action => "new" }
53 + format.xml { render :xml => @site.errors, :status => :unprocessable_entity }
54 + end
55 + end
56 + end
57 +
58 + # PUT /sites/1
59 + # PUT /sites/1.xml
60 + def update
61 + @site = Site.find(params[:id])
62 + @site.clear_start_time_if_not_started
63 +
64 + respond_to do |format|
65 + if @site.update_attributes(params[:site])
66 + flash[:notice] = 'Site was successfully updated.'
67 + format.html { redirect_to(@site) }
68 + format.xml { head :ok }
69 + else
70 + format.html { render :action => "edit" }
71 + format.xml { render :xml => @site.errors, :status => :unprocessable_entity }
72 + end
73 + end
74 + end
75 +
76 + # DELETE /sites/1
77 + # DELETE /sites/1.xml
78 + def destroy
79 + @site = Site.find(params[:id])
80 + @site.destroy
81 +
82 + respond_to do |format|
83 + format.html { redirect_to(sites_url) }
84 + format.xml { head :ok }
85 + end
86 + end
87 + end
@@ -0,0 +1,2
1 + module SitesHelper
2 + end
@@ -0,0 +1,24
1 + class Site < ActiveRecord::Base
2 +
3 + def clear_start_time_if_not_started
4 + if !self.started
5 + self.start_time = nil
6 + end
7 + end
8 +
9 + def finished?
10 + if !self.started
11 + return false
12 + end
13 +
14 + contest_time = Configuration['contest.time_limit']
15 + if tmatch = /(\d+):(\d+)/.match(contest_time)
16 + h = tmatch[1].to_i
17 + m = tmatch[2].to_i
18 + return Time.now > (self.start_time + h.hour + m.minute)
19 + else
20 + false
21 + end
22 + end
23 +
24 + end
@@ -0,0 +1,17
1 + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2 + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3 +
4 + <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5 + <head>
6 + <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
7 + <title>Sites: <%= controller.action_name %></title>
8 + <%= stylesheet_link_tag 'scaffold' %>
9 + </head>
10 + <body>
11 +
12 + <p style="color: green"><%= flash[:notice] %></p>
13 +
14 + <%= yield %>
15 +
16 + </body>
17 + </html>
@@ -0,0 +1,27
1 + <h1>Editing site</h1>
2 +
3 + <%= error_messages_for :site %>
4 +
5 + <% form_for(@site) do |f| %>
6 + <p>
7 + <b>Name</b><br />
8 + <%= f.text_field :name %>
9 + </p>
10 +
11 + <p>
12 + <b>Started</b><br />
13 + <%= f.check_box :started %>
14 + </p>
15 +
16 + <p>
17 + <b>Start time</b><br />
18 + <%= f.datetime_select :start_time %>
19 + </p>
20 +
21 + <p>
22 + <%= f.submit "Update" %>
23 + </p>
24 + <% end %>
25 +
26 + <%= link_to 'Show', @site %> |
27 + <%= link_to 'Back', sites_path %>
@@ -0,0 +1,24
1 + <h1>Listing sites</h1>
2 +
3 + <table>
4 + <tr>
5 + <th>Name</th>
6 + <th>Started</th>
7 + <th>Start time</th>
8 + </tr>
9 +
10 + <% for site in @sites %>
11 + <tr>
12 + <td><%=h site.name %></td>
13 + <td><%=h site.started %></td>
14 + <td><%=h site.start_time %></td>
15 + <td><%= link_to 'Show', site %></td>
16 + <td><%= link_to 'Edit', edit_site_path(site) %></td>
17 + <td><%= link_to 'Destroy', site, :confirm => 'Are you sure?', :method => :delete %></td>
18 + </tr>
19 + <% end %>
20 + </table>
21 +
22 + <br />
23 +
24 + <%= link_to 'New site', new_site_path %>
@@ -0,0 +1,26
1 + <h1>New site</h1>
2 +
3 + <%= error_messages_for :site %>
4 +
5 + <% form_for(@site) do |f| %>
6 + <p>
7 + <b>Name</b><br />
8 + <%= f.text_field :name %>
9 + </p>
10 +
11 + <p>
12 + <b>Started</b><br />
13 + <%= f.check_box :started %>
14 + </p>
15 +
16 + <p>
17 + <b>Start time</b><br />
18 + <%= f.datetime_select :start_time %>
19 + </p>
20 +
21 + <p>
22 + <%= f.submit "Create" %>
23 + </p>
24 + <% end %>
25 +
26 + <%= link_to 'Back', sites_path %>
@@ -0,0 +1,18
1 + <p>
2 + <b>Name:</b>
3 + <%=h @site.name %>
4 + </p>
5 +
6 + <p>
7 + <b>Started:</b>
8 + <%=h @site.started %>
9 + </p>
10 +
11 + <p>
12 + <b>Start time:</b>
13 + <%=h @site.start_time %>
14 + </p>
15 +
16 +
17 + <%= link_to 'Edit', edit_site_path(@site) %> |
18 + <%= link_to 'Back', sites_path %>
@@ -0,0 +1,15
1 + class CreateSites < ActiveRecord::Migration
2 + def self.up
3 + create_table :sites do |t|
4 + t.string :name
5 + t.boolean :started
6 + t.datetime :start_time
7 +
8 + t.timestamps
9 + end
10 + end
11 +
12 + def self.down
13 + drop_table :sites
14 + end
15 + end
@@ -0,0 +1,22
1 + class AddSiteToUserAndAddDefaultSite < ActiveRecord::Migration
2 + def self.up
3 + default_site = Site.new({:name => 'default',
4 + :started => false})
5 + default_site.save!
6 +
7 + add_column :users, :site_id, :integer
8 + User.reset_column_information
9 +
10 + User.find(:all).each do |user|
11 + user.site_id = default_site.id
12 + user.save
13 + end
14 + end
15 +
16 + def self.down
17 + remove_column :users, :site_id
18 +
19 + default_site = Site.find_by_name('default')
20 + default_site.destroy
21 + end
22 + end
@@ -0,0 +1,43
1 +
2 + require File.dirname(__FILE__) + '/../spec_helper'
3 +
4 + describe Site do
5 +
6 + before(:each) do
7 + start_time = Time.local(2008,5,10,9,00)
8 + @site = Site.new({:name => 'Test site',
9 + :started => true,
10 + :start_time => start_time })
11 + end
12 +
13 + it "should report that the contest is not finished when the contest time limit is not set" do
14 + Configuration.should_receive(:[]).with('contest.time_limit').
15 + and_return('unlimit')
16 + Time.should_not_receive(:now)
17 + @site.finished?.should == false
18 + end
19 +
20 + it "should report that the contest is finished when the contest is over" do
21 + Configuration.should_receive(:[]).with('contest.time_limit').
22 + and_return('5:00')
23 + Time.should_receive(:now).and_return(Time.local(2008,5,10,14,01))
24 + @site.finished?.should == true
25 + end
26 +
27 + it "should report if the contest is finished correctly, when the contest is over, and the contest time contains some minutes" do
28 + Configuration.should_receive(:[]).twice.with('contest.time_limit').
29 + and_return('5:15')
30 + Time.should_receive(:now).
31 + and_return(Time.local(2008,5,10,14,14),Time.local(2008,5,10,14,16))
32 + @site.finished?.should == false
33 + @site.finished?.should == true
34 + end
35 +
36 + it "should report that the contest is not finished, when the time is exactly at the finish time" do
37 + Configuration.should_receive(:[]).with('contest.time_limit').
38 + and_return('5:00')
39 + Time.should_receive(:now).and_return(Time.local(2008,5,10,14,00))
40 + @site.finished?.should == false
41 + end
42 +
43 + end
@@ -0,0 +1,11
1 + # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 +
3 + one:
4 + name: MyString
5 + started: false
6 + start_time: 2008-04-09 14:08:28
7 +
8 + two:
9 + name: MyString
10 + started: false
11 + start_time: 2008-04-09 14:08:28
@@ -0,0 +1,45
1 + require File.dirname(__FILE__) + '/../test_helper'
2 +
3 + class SitesControllerTest < ActionController::TestCase
4 + def test_should_get_index
5 + get :index
6 + assert_response :success
7 + assert_not_nil assigns(:sites)
8 + end
9 +
10 + def test_should_get_new
11 + get :new
12 + assert_response :success
13 + end
14 +
15 + def test_should_create_site
16 + assert_difference('Site.count') do
17 + post :create, :site => { }
18 + end
19 +
20 + assert_redirected_to site_path(assigns(:site))
21 + end
22 +
23 + def test_should_show_site
24 + get :show, :id => sites(:one).id
25 + assert_response :success
26 + end
27 +
28 + def test_should_get_edit
29 + get :edit, :id => sites(:one).id
30 + assert_response :success
31 + end
32 +
33 + def test_should_update_site
34 + put :update, :id => sites(:one).id, :site => { }
35 + assert_redirected_to site_path(assigns(:site))
36 + end
37 +
38 + def test_should_destroy_site
39 + assert_difference('Site.count', -1) do
40 + delete :destroy, :id => sites(:one).id
41 + end
42 +
43 + assert_redirected_to sites_path
44 + end
45 + end
@@ -0,0 +1,8
1 + require File.dirname(__FILE__) + '/../test_helper'
2 +
3 + class SiteTest < ActiveSupport::TestCase
4 + # Replace this with your real tests.
5 + def test_truth
6 + assert true
7 + end
8 + end
@@ -32,26 +32,38
32 redirect_to :controller => 'main', :action => 'login'
32 redirect_to :controller => 'main', :action => 'login'
33 return false
33 return false
34 end
34 end
35 end
35 end
36
36
37 return true
37 return true
38 end
38 end
39
39
40 def authorization
40 def authorization
41 return false unless authenticate
41 return false unless authenticate
42 user = User.find(session[:user_id])
42 user = User.find(session[:user_id])
43 unless user.roles.detect { |role|
43 unless user.roles.detect { |role|
44 role.rights.detect{ |right|
44 role.rights.detect{ |right|
45 right.controller == self.class.controller_name and
45 right.controller == self.class.controller_name and
46 (right.action == 'all' or right.action == action_name)
46 (right.action == 'all' or right.action == action_name)
47 }
47 }
48 }
48 }
49 flash[:notice] = 'You are not authorized to view the page you requested'
49 flash[:notice] = 'You are not authorized to view the page you requested'
50 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
50 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
51 redirect_to :controller => 'main', :action => 'login'
51 redirect_to :controller => 'main', :action => 'login'
52 return false
52 return false
53 end
53 end
54 end
54 end
55
55
56 + def verify_time_limit
57 + return true if session[:user_id]==nil
58 + user = User.find(session[:user_id], :include => :site)
59 + return true if user==nil or user.site == nil
60 + if user.site.finished?
61 + flash[:notice] = 'Error: the contest on your site is over.'
62 + redirect_to :back
63 + return false
64 + end
65 + return true
66 + end
67 +
56 end
68 end
57
69
@@ -1,54 +1,68
1 class MainController < ApplicationController
1 class MainController < ApplicationController
2
2
3 before_filter :authenticate, :except => [:index, :login]
3 before_filter :authenticate, :except => [:index, :login]
4
4
5 + #
6 + # COMMENT OUT: filter in each action instead
7 + #
8 + # before_filter :verify_time_limit, :only => [:submit]
9 +
5 verify :method => :post, :only => [:submit],
10 verify :method => :post, :only => [:submit],
6 :redirect_to => { :action => :index }
11 :redirect_to => { :action => :index }
7
12
8
13
9 def index
14 def index
10 redirect_to :action => 'login'
15 redirect_to :action => 'login'
11 end
16 end
12
17
13 def login
18 def login
14 saved_notice = flash[:notice]
19 saved_notice = flash[:notice]
15 reset_session
20 reset_session
16 flash[:notice] = saved_notice
21 flash[:notice] = saved_notice
17
22
18 render :action => 'login', :layout => 'empty'
23 render :action => 'login', :layout => 'empty'
19 end
24 end
20
25
21 def list
26 def list
22 prepare_list_information
27 prepare_list_information
23 end
28 end
24
29
25 def submit
30 def submit
31 + user = User.find(session[:user_id])
32 +
26 @submission = Submission.new(params[:submission])
33 @submission = Submission.new(params[:submission])
27 - @submission.user_id = session[:user_id]
34 + @submission.user = user
28 @submission.language_id = 0
35 @submission.language_id = 0
29 @submission.source = params['file'].read if params['file']!=''
36 @submission.source = params['file'].read if params['file']!=''
30 @submission.submitted_at = Time.new
37 @submission.submitted_at = Time.new
38 +
39 + if user.site!=nil and user.site.finished?
40 + @submission.errors.add_to_base "The contest is over."
41 + prepare_list_information
42 + render :action => 'list' and return
43 + end
44 +
31 if @submission.valid?
45 if @submission.valid?
32 if @submission.save == false
46 if @submission.save == false
33 flash[:notice] = 'Error saving your submission'
47 flash[:notice] = 'Error saving your submission'
34 elsif Task.create(:submission_id => @submission.id,
48 elsif Task.create(:submission_id => @submission.id,
35 :status => Task::STATUS_INQUEUE) == false
49 :status => Task::STATUS_INQUEUE) == false
36 flash[:notice] = 'Error adding your submission to task queue'
50 flash[:notice] = 'Error adding your submission to task queue'
37 end
51 end
38 else
52 else
39 prepare_list_information
53 prepare_list_information
40 render :action => 'list' and return
54 render :action => 'list' and return
41 end
55 end
42 redirect_to :action => 'list'
56 redirect_to :action => 'list'
43 end
57 end
44
58
45 def source
59 def source
46 submission = Submission.find(params[:id])
60 submission = Submission.find(params[:id])
47 if submission.user_id == session[:user_id]
61 if submission.user_id == session[:user_id]
48 fname = submission.problem.name + '.' + submission.language.ext
62 fname = submission.problem.name + '.' + submission.language.ext
49 send_data(submission.source,
63 send_data(submission.source,
50 {:filename => fname,
64 {:filename => fname,
51 :type => 'text/plain'})
65 :type => 'text/plain'})
52 else
66 else
53 flash[:notice] = 'Error viewing source'
67 flash[:notice] = 'Error viewing source'
54 redirect_to :action => 'list'
68 redirect_to :action => 'list'
@@ -1,39 +1,50
1 class TestController < ApplicationController
1 class TestController < ApplicationController
2
2
3 before_filter :authenticate
3 before_filter :authenticate
4
4
5 + #
6 + # COMMENT OUT: filter in each action instead
7 + #
8 + # before_filter :verify_time_limit, :only => [:submit]
9 +
5 verify :method => :post, :only => [:submit],
10 verify :method => :post, :only => [:submit],
6 :redirect_to => { :action => :index }
11 :redirect_to => { :action => :index }
7
12
8 def index
13 def index
9 @user = User.find(session[:user_id])
14 @user = User.find(session[:user_id])
10 prepare_index_information
15 prepare_index_information
11 @test_requests = @user.test_requests
16 @test_requests = @user.test_requests
12 end
17 end
13
18
14 def submit
19 def submit
15 @user = User.find(session[:user_id])
20 @user = User.find(session[:user_id])
21 +
22 + if @user.site!=nil and @user.site.finished?
23 + flash[:notice] = 'Error saving your test submission: Contest is over.'
24 + redirect_to :action => 'index' and return
25 + end
26 +
16 test_request = TestRequest.new_from_form_params(@user,params[:test_request])
27 test_request = TestRequest.new_from_form_params(@user,params[:test_request])
17 if test_request.save
28 if test_request.save
18 redirect_to :action => 'index'
29 redirect_to :action => 'index'
19 else
30 else
20 flash[:notice] = 'Error saving your test submission'
31 flash[:notice] = 'Error saving your test submission'
21 redirect_to :action => 'index'
32 redirect_to :action => 'index'
22 end
33 end
23 end
34 end
24
35
25 def read
36 def read
26 user = User.find(session[:user_id])
37 user = User.find(session[:user_id])
27 begin
38 begin
28 test_request = TestRequest.find(params[:id])
39 test_request = TestRequest.find(params[:id])
29 rescue
40 rescue
30 test_request = nil
41 test_request = nil
31 end
42 end
32 if test_request==nil or test_request.user_id != user.id
43 if test_request==nil or test_request.user_id != user.id
33 flash[:notice] = 'Invalid output'
44 flash[:notice] = 'Invalid output'
34 redirect_to :action => 'index'
45 redirect_to :action => 'index'
35 return
46 return
36 end
47 end
37 if test_request.output_file_name!=nil
48 if test_request.output_file_name!=nil
38 data = File.open(test_request.output_file_name).read(2048)
49 data = File.open(test_request.output_file_name).read(2048)
39 if data==nil
50 if data==nil
@@ -24,40 +24,48
24 append_to menu_items, '[Log out]', 'main', 'login'
24 append_to menu_items, '[Log out]', 'main', 'login'
25
25
26 menu_items
26 menu_items
27 end
27 end
28
28
29 def append_to(option,label, controller, action)
29 def append_to(option,label, controller, action)
30 option << ' ' if option!=''
30 option << ' ' if option!=''
31 option << link_to_unless_current(label,
31 option << link_to_unless_current(label,
32 :controller => controller,
32 :controller => controller,
33 :action => action)
33 :action => action)
34 end
34 end
35
35
36 def format_short_time(time)
36 def format_short_time(time)
37 now = Time.now
37 now = Time.now
38 st = ''
38 st = ''
39 if (time.yday != now.yday) or
39 if (time.yday != now.yday) or
40 (time.year != now.year)
40 (time.year != now.year)
41 st = time.strftime("%x ")
41 st = time.strftime("%x ")
42 end
42 end
43 st + time.strftime("%X")
43 st + time.strftime("%X")
44 end
44 end
45
45
46
46
47 def user_title_bar(user)
47 def user_title_bar(user)
48 + if user.site!=nil and user.site.finished?
49 + contest_over_string = <<CONTEST_OVER
50 + <tr><td colspan="2" align="center">
51 + <span class="contest-over-msg">THE CONTEST IS OVER</span>
52 + </td></tr>
53 + CONTEST_OVER
54 + end
48 <<TITLEBAR
55 <<TITLEBAR
49 <div class="title">
56 <div class="title">
50 <table>
57 <table>
58 + #{contest_over_string}
51 <tr>
59 <tr>
52 <td class="left-col">
60 <td class="left-col">
53 #{user.full_name}<br/>
61 #{user.full_name}<br/>
54 Current time is #{format_short_time(Time.new)}<br/>
62 Current time is #{format_short_time(Time.new)}<br/>
55 </td>
63 </td>
56 <td class="right-col">APIO'08</td>
64 <td class="right-col">APIO'08</td>
57 </tr>
65 </tr>
58 </table>
66 </table>
59 </div>
67 </div>
60 TITLEBAR
68 TITLEBAR
61 end
69 end
62
70
63 end
71 end
@@ -1,32 +1,34
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 + belongs_to :site
10 +
9 validates_presence_of :login
11 validates_presence_of :login
10 validates_presence_of :full_name
12 validates_presence_of :full_name
11 validates_length_of :full_name, :minimum => 1
13 validates_length_of :full_name, :minimum => 1
12
14
13 validates_presence_of :password, :if => :password_required?
15 validates_presence_of :password, :if => :password_required?
14 validates_length_of :password, :within => 4..20, :if => :password_required?
16 validates_length_of :password, :within => 4..20, :if => :password_required?
15 validates_confirmation_of :password, :if => :password_required?
17 validates_confirmation_of :password, :if => :password_required?
16
18
17 attr_accessor :password
19 attr_accessor :password
18
20
19 before_save :encrypt_new_password
21 before_save :encrypt_new_password
20
22
21 def self.authenticate(login, password)
23 def self.authenticate(login, password)
22 user = find_by_login(login)
24 user = find_by_login(login)
23 return user if user && user.authenticated?(password)
25 return user if user && user.authenticated?(password)
24 end
26 end
25
27
26 def authenticated?(password)
28 def authenticated?(password)
27 hashed_password == User.encrypt(password,self.salt)
29 hashed_password == User.encrypt(password,self.salt)
28 end
30 end
29
31
30 def admin?
32 def admin?
31 self.roles.detect {|r| r.name == 'admin' }
33 self.roles.detect {|r| r.name == 'admin' }
32 end
34 end
@@ -1,23 +1,25
1 ActionController::Routing::Routes.draw do |map|
1 ActionController::Routing::Routes.draw do |map|
2 + map.resources :sites
3 +
2 # The priority is based upon order of creation: first created -> highest priority.
4 # The priority is based upon order of creation: first created -> highest priority.
3
5
4 # Sample of regular route:
6 # Sample of regular route:
5 # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
7 # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
6 # Keep in mind you can assign values other than :controller and :action
8 # Keep in mind you can assign values other than :controller and :action
7
9
8 # Sample of named route:
10 # Sample of named route:
9 # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
11 # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
10 # This route can be invoked with purchase_url(:id => product.id)
12 # This route can be invoked with purchase_url(:id => product.id)
11
13
12 # You can have the root of your site routed by hooking up ''
14 # You can have the root of your site routed by hooking up ''
13 # -- just remember to delete public/index.html.
15 # -- just remember to delete public/index.html.
14 map.connect '', :controller => 'main', :action => 'login'
16 map.connect '', :controller => 'main', :action => 'login'
15
17
16 # Allow downloading Web Service WSDL as a file with an extension
18 # Allow downloading Web Service WSDL as a file with an extension
17 # instead of a file named 'wsdl'
19 # instead of a file named 'wsdl'
18 map.connect ':controller/service.wsdl', :action => 'wsdl'
20 map.connect ':controller/service.wsdl', :action => 'wsdl'
19
21
20 # Install the default route as the lowest priority.
22 # Install the default route as the lowest priority.
21 map.connect ':controller/:action/:id.:format'
23 map.connect ':controller/:action/:id.:format'
22 map.connect ':controller/:action/:id'
24 map.connect ':controller/:action/:id'
23 end
25 end
@@ -1,36 +1,36
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 ActiveRecord to incrementally modify your database, and
2 # please use the migrations feature of ActiveRecord 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 => 23) do
12 + ActiveRecord::Schema.define(:version => 25) do
13
13
14 create_table "configurations", :force => true do |t|
14 create_table "configurations", :force => true do |t|
15 t.string "key"
15 t.string "key"
16 t.string "value_type"
16 t.string "value_type"
17 t.string "value"
17 t.string "value"
18 t.datetime "created_at"
18 t.datetime "created_at"
19 t.datetime "updated_at"
19 t.datetime "updated_at"
20 end
20 end
21
21
22 create_table "grader_processes", :force => true do |t|
22 create_table "grader_processes", :force => true do |t|
23 t.string "host", :limit => 20
23 t.string "host", :limit => 20
24 t.integer "pid"
24 t.integer "pid"
25 t.string "mode"
25 t.string "mode"
26 t.boolean "active"
26 t.boolean "active"
27 t.datetime "created_at"
27 t.datetime "created_at"
28 t.datetime "updated_at"
28 t.datetime "updated_at"
29 t.integer "task_id"
29 t.integer "task_id"
30 end
30 end
31
31
32 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
32 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
33
33
34 create_table "languages", :force => true do |t|
34 create_table "languages", :force => true do |t|
35 t.string "name", :limit => 10
35 t.string "name", :limit => 10
36 t.string "pretty_name"
36 t.string "pretty_name"
@@ -58,83 +58,92
58 end
58 end
59
59
60 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
60 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
61
61
62 create_table "roles", :force => true do |t|
62 create_table "roles", :force => true do |t|
63 t.string "name"
63 t.string "name"
64 end
64 end
65
65
66 create_table "roles_users", :id => false, :force => true do |t|
66 create_table "roles_users", :id => false, :force => true do |t|
67 t.integer "role_id"
67 t.integer "role_id"
68 t.integer "user_id"
68 t.integer "user_id"
69 end
69 end
70
70
71 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
71 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
72
72
73 create_table "sessions", :force => true do |t|
73 create_table "sessions", :force => true do |t|
74 t.string "session_id"
74 t.string "session_id"
75 t.text "data"
75 t.text "data"
76 t.datetime "updated_at"
76 t.datetime "updated_at"
77 end
77 end
78
78
79 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
79 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
80 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
80 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
81
81
82 + create_table "sites", :force => true do |t|
83 + t.string "name"
84 + t.boolean "started"
85 + t.datetime "start_time"
86 + t.datetime "created_at"
87 + t.datetime "updated_at"
88 + end
89 +
82 create_table "submissions", :force => true do |t|
90 create_table "submissions", :force => true do |t|
83 t.integer "user_id"
91 t.integer "user_id"
84 t.integer "problem_id"
92 t.integer "problem_id"
85 t.integer "language_id"
93 t.integer "language_id"
86 t.text "source"
94 t.text "source"
87 t.binary "binary"
95 t.binary "binary"
88 t.datetime "submitted_at"
96 t.datetime "submitted_at"
89 t.datetime "compiled_at"
97 t.datetime "compiled_at"
90 t.text "compiler_message"
98 t.text "compiler_message"
91 t.datetime "graded_at"
99 t.datetime "graded_at"
92 t.integer "points"
100 t.integer "points"
93 t.text "grader_comment"
101 t.text "grader_comment"
94 t.integer "number"
102 t.integer "number"
95 end
103 end
96
104
97 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
105 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
98 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
106 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
99
107
100 create_table "tasks", :force => true do |t|
108 create_table "tasks", :force => true do |t|
101 t.integer "submission_id"
109 t.integer "submission_id"
102 t.datetime "created_at"
110 t.datetime "created_at"
103 t.integer "status"
111 t.integer "status"
104 t.datetime "updated_at"
112 t.datetime "updated_at"
105 end
113 end
106
114
107 create_table "test_requests", :force => true do |t|
115 create_table "test_requests", :force => true do |t|
108 t.integer "user_id"
116 t.integer "user_id"
109 t.integer "problem_id"
117 t.integer "problem_id"
110 t.integer "submission_id"
118 t.integer "submission_id"
111 t.string "input_file_name"
119 t.string "input_file_name"
112 t.string "output_file_name"
120 t.string "output_file_name"
113 t.string "running_stat"
121 t.string "running_stat"
114 t.integer "status"
122 t.integer "status"
115 t.datetime "updated_at"
123 t.datetime "updated_at"
116 t.datetime "submitted_at"
124 t.datetime "submitted_at"
117 t.datetime "compiled_at"
125 t.datetime "compiled_at"
118 t.text "compiler_message"
126 t.text "compiler_message"
119 t.datetime "graded_at"
127 t.datetime "graded_at"
120 t.string "grader_comment"
128 t.string "grader_comment"
121 t.datetime "created_at"
129 t.datetime "created_at"
122 t.float "running_time"
130 t.float "running_time"
123 t.string "exit_status"
131 t.string "exit_status"
124 t.integer "memory_usage"
132 t.integer "memory_usage"
125 end
133 end
126
134
127 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
135 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
128
136
129 create_table "users", :force => true do |t|
137 create_table "users", :force => true do |t|
130 - t.string "login", :limit => 10
138 + t.string "login", :limit => 10
131 - t.string "full_name"
139 + t.string "full_name"
132 - t.string "hashed_password"
140 + t.string "hashed_password"
133 - t.string "salt", :limit => 5
141 + t.string "salt", :limit => 5
134 - t.string "alias"
142 + t.string "alias"
135 - t.string "email"
143 + t.string "email"
144 + t.integer "site_id"
136 end
145 end
137
146
138 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
147 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
139
148
140 end
149 end
@@ -1,47 +1,53
1 /* Normal text */
1 /* Normal text */
2 p {
2 p {
3 font-size: 12px;
3 font-size: 12px;
4 }
4 }
5
5
6 /* This is the main menu bad*/
6 /* This is the main menu bad*/
7 div.userbar {
7 div.userbar {
8 border-top: thin solid grey;
8 border-top: thin solid grey;
9 border-bottom: thin solid grey;
9 border-bottom: thin solid grey;
10 text-align: right;
10 text-align: right;
11 font-size: 12px;
11 font-size: 12px;
12 }
12 }
13
13
14 /* This is the top bar, displaying user's full name */
14 /* This is the top bar, displaying user's full name */
15 div.title {
15 div.title {
16 font-size: 12px;
16 font-size: 12px;
17 background: #ddffdd;
17 background: #ddffdd;
18 border: 1px solid black;
18 border: 1px solid black;
19 padding: 2px;
19 padding: 2px;
20 margin-top: 3px;
20 margin-top: 3px;
21 margin-bottom: 5px;
21 margin-bottom: 5px;
22 }
22 }
23
23
24 + div.title span.contest-over-msg {
25 + font-size: 15px;
26 + color: red;
27 + font-weight: bold;
28 + }
29 +
24 div.title table {
30 div.title table {
25 width: 100%;
31 width: 100%;
26 }
32 }
27
33
28 div.title td.left-col {
34 div.title td.left-col {
29 text-align: left;
35 text-align: left;
30 vertical-align: top;
36 vertical-align: top;
31 }
37 }
32
38
33 div.title td.right-col {
39 div.title td.right-col {
34 text-align: right;
40 text-align: right;
35 vertical-align: top;
41 vertical-align: top;
36 }
42 }
37
43
38 /* Standard table with header and rows with alternating background */
44 /* Standard table with header and rows with alternating background */
39 table.info {
45 table.info {
40 border: 1px solid black;
46 border: 1px solid black;
41 border-collapse: collapse;
47 border-collapse: collapse;
42 font-size: 12px;
48 font-size: 12px;
43 }
49 }
44
50
45 table.info th {
51 table.info th {
46 border: 1px solid black;
52 border: 1px solid black;
47 }
53 }
@@ -41,34 +41,34
41 color: #fff;
41 color: #fff;
42 }
42 }
43
43
44 #errorExplanation p {
44 #errorExplanation p {
45 color: #333;
45 color: #333;
46 margin-bottom: 0;
46 margin-bottom: 0;
47 padding: 5px;
47 padding: 5px;
48 }
48 }
49
49
50 #errorExplanation ul li {
50 #errorExplanation ul li {
51 font-size: 12px;
51 font-size: 12px;
52 list-style: square;
52 list-style: square;
53 }
53 }
54
54
55 div.uploadStatus {
55 div.uploadStatus {
56 margin: 5px;
56 margin: 5px;
57 }
57 }
58
58
59 div.progressBar {
59 div.progressBar {
60 margin: 5px;
60 margin: 5px;
61 }
61 }
62
62
63 div.progressBar div.border {
63 div.progressBar div.border {
64 background-color: #fff;
64 background-color: #fff;
65 - border: 1px solid grey;
65 + border: 1px solid gray;
66 width: 100%;
66 width: 100%;
67 }
67 }
68
68
69 div.progressBar div.background {
69 div.progressBar div.background {
70 background-color: #333;
70 background-color: #333;
71 height: 18px;
71 height: 18px;
72 width: 0%;
72 width: 0%;
73 }
73 }
74
74
You need to be logged in to leave comments. Login now