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
@@ -8,50 +8,62
8 8 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
9 9
10 10 def authorization_by_roles(allowed_roles)
11 11 return false unless authenticate
12 12 user = User.find(session[:user_id])
13 13 unless user.roles.detect { |role| allowed_roles.member?(role.name) }
14 14 flash[:notice] = 'You are not authorized to view the page you requested'
15 15 redirect_to :controller => 'main', :action => 'login'
16 16 return false
17 17 end
18 18 end
19 19
20 20 protected
21 21 def authenticate
22 22 unless session[:user_id]
23 23 redirect_to :controller => 'main', :action => 'login'
24 24 return false
25 25 end
26 26
27 27 Configuration.reload
28 28 # check if run in single user mode
29 29 if (Configuration[SINGLE_USER_MODE_CONF_KEY])
30 30 user = User.find(session[:user_id])
31 31 if user==nil or user.login != 'root'
32 32 redirect_to :controller => 'main', :action => 'login'
33 33 return false
34 34 end
35 35 end
36 36
37 37 return true
38 38 end
39 39
40 40 def authorization
41 41 return false unless authenticate
42 42 user = User.find(session[:user_id])
43 43 unless user.roles.detect { |role|
44 44 role.rights.detect{ |right|
45 45 right.controller == self.class.controller_name and
46 46 (right.action == 'all' or right.action == action_name)
47 47 }
48 48 }
49 49 flash[:notice] = 'You are not authorized to view the page you requested'
50 50 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
51 51 redirect_to :controller => 'main', :action => 'login'
52 52 return false
53 53 end
54 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 68 end
57 69
@@ -1,78 +1,92
1 1 class MainController < ApplicationController
2 2
3 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 10 verify :method => :post, :only => [:submit],
6 11 :redirect_to => { :action => :index }
7 12
8 13
9 14 def index
10 15 redirect_to :action => 'login'
11 16 end
12 17
13 18 def login
14 19 saved_notice = flash[:notice]
15 20 reset_session
16 21 flash[:notice] = saved_notice
17 22
18 23 render :action => 'login', :layout => 'empty'
19 24 end
20 25
21 26 def list
22 27 prepare_list_information
23 28 end
24 29
25 30 def submit
31 + user = User.find(session[:user_id])
32 +
26 33 @submission = Submission.new(params[:submission])
27 - @submission.user_id = session[:user_id]
34 + @submission.user = user
28 35 @submission.language_id = 0
29 36 @submission.source = params['file'].read if params['file']!=''
30 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 45 if @submission.valid?
32 46 if @submission.save == false
33 47 flash[:notice] = 'Error saving your submission'
34 48 elsif Task.create(:submission_id => @submission.id,
35 49 :status => Task::STATUS_INQUEUE) == false
36 50 flash[:notice] = 'Error adding your submission to task queue'
37 51 end
38 52 else
39 53 prepare_list_information
40 54 render :action => 'list' and return
41 55 end
42 56 redirect_to :action => 'list'
43 57 end
44 58
45 59 def source
46 60 submission = Submission.find(params[:id])
47 61 if submission.user_id == session[:user_id]
48 62 fname = submission.problem.name + '.' + submission.language.ext
49 63 send_data(submission.source,
50 64 {:filename => fname,
51 65 :type => 'text/plain'})
52 66 else
53 67 flash[:notice] = 'Error viewing source'
54 68 redirect_to :action => 'list'
55 69 end
56 70 end
57 71
58 72 def compiler_msg
59 73 @submission = Submission.find(params[:id])
60 74 if @submission.user_id == session[:user_id]
61 75 render :action => 'compiler_msg', :layout => 'empty'
62 76 else
63 77 flash[:notice] = 'Error viewing source'
64 78 redirect_to :action => 'list'
65 79 end
66 80 end
67 81
68 82 def submission
69 83 @user = User.find(session[:user_id])
70 84 @problems = Problem.find_available_problems
71 85 if params[:id]==nil
72 86 @problem = nil
73 87 @submissions = nil
74 88 else
75 89 @problem = Problem.find_by_name(params[:id])
76 90 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
77 91 end
78 92 end
@@ -1,63 +1,74
1 1 class TestController < ApplicationController
2 2
3 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 10 verify :method => :post, :only => [:submit],
6 11 :redirect_to => { :action => :index }
7 12
8 13 def index
9 14 @user = User.find(session[:user_id])
10 15 prepare_index_information
11 16 @test_requests = @user.test_requests
12 17 end
13 18
14 19 def submit
15 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 27 test_request = TestRequest.new_from_form_params(@user,params[:test_request])
17 28 if test_request.save
18 29 redirect_to :action => 'index'
19 30 else
20 31 flash[:notice] = 'Error saving your test submission'
21 32 redirect_to :action => 'index'
22 33 end
23 34 end
24 35
25 36 def read
26 37 user = User.find(session[:user_id])
27 38 begin
28 39 test_request = TestRequest.find(params[:id])
29 40 rescue
30 41 test_request = nil
31 42 end
32 43 if test_request==nil or test_request.user_id != user.id
33 44 flash[:notice] = 'Invalid output'
34 45 redirect_to :action => 'index'
35 46 return
36 47 end
37 48 if test_request.output_file_name!=nil
38 49 data = File.open(test_request.output_file_name).read(2048)
39 50 if data==nil
40 51 data=""
41 52 end
42 53 send_data(data,
43 54 {:filename => 'output.txt',
44 55 :type => 'text/plain'})
45 56 return
46 57 end
47 58 redirect_to :action => 'index'
48 59 end
49 60
50 61 def result
51 62 @user = User.find(session[:user_id])
52 63 begin
53 64 @test_request = TestRequest.find(params[:id])
54 65 rescue
55 66 @test_request = nil
56 67 end
57 68 if @test_request==nil or @test_request.user_id != @user.id
58 69 flash[:notice] = 'Invalid request'
59 70 redirect_to :action => 'index'
60 71 return
61 72 end
62 73 end
63 74
@@ -1,63 +1,71
1 1 # Methods added to this helper will be available to all templates in the application.
2 2 module ApplicationHelper
3 3
4 4 def user_header
5 5 menu_items = ''
6 6 user = User.find(session[:user_id])
7 7
8 8 if (user!=nil) and (user.admin?)
9 9 # admin menu
10 10 menu_items << "<b>Administrative task:</b> "
11 11 append_to menu_items, '[Problem admin]', 'problems', 'index'
12 12 append_to menu_items, '[User admin]', 'user_admin', 'index'
13 13 append_to menu_items, '[User stat]', 'user_admin', 'user_stat'
14 14 #append_to menu_items, '[Graders]', 'graders', 'list'
15 15 append_to menu_items, '[Site config]', 'configurations', 'index'
16 16 menu_items << "<br/>"
17 17 end
18 18
19 19 # main page
20 20 append_to menu_items, '[Main]', 'main', 'list'
21 21 append_to menu_items, '[Submissions]', 'main', 'submission'
22 22 append_to menu_items, '[Test]', 'test', 'index'
23 23 append_to menu_items, '[Settings]', 'users', 'index'
24 24 append_to menu_items, '[Log out]', 'main', 'login'
25 25
26 26 menu_items
27 27 end
28 28
29 29 def append_to(option,label, controller, action)
30 30 option << ' ' if option!=''
31 31 option << link_to_unless_current(label,
32 32 :controller => controller,
33 33 :action => action)
34 34 end
35 35
36 36 def format_short_time(time)
37 37 now = Time.now
38 38 st = ''
39 39 if (time.yday != now.yday) or
40 40 (time.year != now.year)
41 41 st = time.strftime("%x ")
42 42 end
43 43 st + time.strftime("%X")
44 44 end
45 45
46 46
47 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 55 <<TITLEBAR
49 56 <div class="title">
50 57 <table>
58 + #{contest_over_string}
51 59 <tr>
52 60 <td class="left-col">
53 61 #{user.full_name}<br/>
54 62 Current time is #{format_short_time(Time.new)}<br/>
55 63 </td>
56 64 <td class="right-col">APIO'08</td>
57 65 </tr>
58 66 </table>
59 67 </div>
60 68 TITLEBAR
61 69 end
62 70
63 71 end
@@ -1,56 +1,58
1 1 require 'digest/sha1'
2 2
3 3 class User < ActiveRecord::Base
4 4
5 5 has_and_belongs_to_many :roles
6 6
7 7 has_many :test_requests, :order => "submitted_at DESC"
8 8
9 + belongs_to :site
10 +
9 11 validates_presence_of :login
10 12 validates_presence_of :full_name
11 13 validates_length_of :full_name, :minimum => 1
12 14
13 15 validates_presence_of :password, :if => :password_required?
14 16 validates_length_of :password, :within => 4..20, :if => :password_required?
15 17 validates_confirmation_of :password, :if => :password_required?
16 18
17 19 attr_accessor :password
18 20
19 21 before_save :encrypt_new_password
20 22
21 23 def self.authenticate(login, password)
22 24 user = find_by_login(login)
23 25 return user if user && user.authenticated?(password)
24 26 end
25 27
26 28 def authenticated?(password)
27 29 hashed_password == User.encrypt(password,self.salt)
28 30 end
29 31
30 32 def admin?
31 33 self.roles.detect {|r| r.name == 'admin' }
32 34 end
33 35
34 36 def email_for_editing
35 37 if self.email==nil
36 38 "(unknown)"
37 39 elsif self.email==''
38 40 "(blank)"
39 41 else
40 42 self.email
41 43 end
42 44 end
43 45
44 46 def email_for_editing=(e)
45 47 self.email=e
46 48 end
47 49
48 50 def alias_for_editing
49 51 if self.alias==nil
50 52 "(unknown)"
51 53 elsif self.alias==''
52 54 "(blank)"
53 55 else
54 56 self.alias
55 57 end
56 58 end
@@ -1,23 +1,25
1 1 ActionController::Routing::Routes.draw do |map|
2 + map.resources :sites
3 +
2 4 # The priority is based upon order of creation: first created -> highest priority.
3 5
4 6 # Sample of regular route:
5 7 # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
6 8 # Keep in mind you can assign values other than :controller and :action
7 9
8 10 # Sample of named route:
9 11 # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
10 12 # This route can be invoked with purchase_url(:id => product.id)
11 13
12 14 # You can have the root of your site routed by hooking up ''
13 15 # -- just remember to delete public/index.html.
14 16 map.connect '', :controller => 'main', :action => 'login'
15 17
16 18 # Allow downloading Web Service WSDL as a file with an extension
17 19 # instead of a file named 'wsdl'
18 20 map.connect ':controller/service.wsdl', :action => 'wsdl'
19 21
20 22 # Install the default route as the lowest priority.
21 23 map.connect ':controller/:action/:id.:format'
22 24 map.connect ':controller/:action/:id'
23 25 end
@@ -1,140 +1,149
1 1 # This file is auto-generated from the current state of the database. Instead of editing this file,
2 2 # please use the migrations feature of ActiveRecord to incrementally modify your database, and
3 3 # then regenerate this schema definition.
4 4 #
5 5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
6 6 # to create the application database on another system, you should be using db:schema:load, not running
7 7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
8 8 # you'll amass, the slower it'll run and the greater likelihood for issues).
9 9 #
10 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 14 create_table "configurations", :force => true do |t|
15 15 t.string "key"
16 16 t.string "value_type"
17 17 t.string "value"
18 18 t.datetime "created_at"
19 19 t.datetime "updated_at"
20 20 end
21 21
22 22 create_table "grader_processes", :force => true do |t|
23 23 t.string "host", :limit => 20
24 24 t.integer "pid"
25 25 t.string "mode"
26 26 t.boolean "active"
27 27 t.datetime "created_at"
28 28 t.datetime "updated_at"
29 29 t.integer "task_id"
30 30 end
31 31
32 32 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
33 33
34 34 create_table "languages", :force => true do |t|
35 35 t.string "name", :limit => 10
36 36 t.string "pretty_name"
37 37 t.string "ext", :limit => 10
38 38 end
39 39
40 40 create_table "problems", :force => true do |t|
41 41 t.string "name", :limit => 30
42 42 t.string "full_name"
43 43 t.integer "full_score"
44 44 t.date "date_added"
45 45 t.boolean "available"
46 46 t.string "url"
47 47 end
48 48
49 49 create_table "rights", :force => true do |t|
50 50 t.string "name"
51 51 t.string "controller"
52 52 t.string "action"
53 53 end
54 54
55 55 create_table "rights_roles", :id => false, :force => true do |t|
56 56 t.integer "right_id"
57 57 t.integer "role_id"
58 58 end
59 59
60 60 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
61 61
62 62 create_table "roles", :force => true do |t|
63 63 t.string "name"
64 64 end
65 65
66 66 create_table "roles_users", :id => false, :force => true do |t|
67 67 t.integer "role_id"
68 68 t.integer "user_id"
69 69 end
70 70
71 71 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
72 72
73 73 create_table "sessions", :force => true do |t|
74 74 t.string "session_id"
75 75 t.text "data"
76 76 t.datetime "updated_at"
77 77 end
78 78
79 79 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
80 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 90 create_table "submissions", :force => true do |t|
83 91 t.integer "user_id"
84 92 t.integer "problem_id"
85 93 t.integer "language_id"
86 94 t.text "source"
87 95 t.binary "binary"
88 96 t.datetime "submitted_at"
89 97 t.datetime "compiled_at"
90 98 t.text "compiler_message"
91 99 t.datetime "graded_at"
92 100 t.integer "points"
93 101 t.text "grader_comment"
94 102 t.integer "number"
95 103 end
96 104
97 105 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
98 106 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
99 107
100 108 create_table "tasks", :force => true do |t|
101 109 t.integer "submission_id"
102 110 t.datetime "created_at"
103 111 t.integer "status"
104 112 t.datetime "updated_at"
105 113 end
106 114
107 115 create_table "test_requests", :force => true do |t|
108 116 t.integer "user_id"
109 117 t.integer "problem_id"
110 118 t.integer "submission_id"
111 119 t.string "input_file_name"
112 120 t.string "output_file_name"
113 121 t.string "running_stat"
114 122 t.integer "status"
115 123 t.datetime "updated_at"
116 124 t.datetime "submitted_at"
117 125 t.datetime "compiled_at"
118 126 t.text "compiler_message"
119 127 t.datetime "graded_at"
120 128 t.string "grader_comment"
121 129 t.datetime "created_at"
122 130 t.float "running_time"
123 131 t.string "exit_status"
124 132 t.integer "memory_usage"
125 133 end
126 134
127 135 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
128 136
129 137 create_table "users", :force => true do |t|
130 - t.string "login", :limit => 10
131 - t.string "full_name"
132 - t.string "hashed_password"
133 - t.string "salt", :limit => 5
134 - t.string "alias"
135 - t.string "email"
138 + t.string "login", :limit => 10
139 + t.string "full_name"
140 + t.string "hashed_password"
141 + t.string "salt", :limit => 5
142 + t.string "alias"
143 + t.string "email"
144 + t.integer "site_id"
136 145 end
137 146
138 147 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
139 148
140 149 end
@@ -1,71 +1,77
1 1 /* Normal text */
2 2 p {
3 3 font-size: 12px;
4 4 }
5 5
6 6 /* This is the main menu bad*/
7 7 div.userbar {
8 8 border-top: thin solid grey;
9 9 border-bottom: thin solid grey;
10 10 text-align: right;
11 11 font-size: 12px;
12 12 }
13 13
14 14 /* This is the top bar, displaying user's full name */
15 15 div.title {
16 16 font-size: 12px;
17 17 background: #ddffdd;
18 18 border: 1px solid black;
19 19 padding: 2px;
20 20 margin-top: 3px;
21 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 30 div.title table {
25 31 width: 100%;
26 32 }
27 33
28 34 div.title td.left-col {
29 35 text-align: left;
30 36 vertical-align: top;
31 37 }
32 38
33 39 div.title td.right-col {
34 40 text-align: right;
35 41 vertical-align: top;
36 42 }
37 43
38 44 /* Standard table with header and rows with alternating background */
39 45 table.info {
40 46 border: 1px solid black;
41 47 border-collapse: collapse;
42 48 font-size: 12px;
43 49 }
44 50
45 51 table.info th {
46 52 border: 1px solid black;
47 53 }
48 54
49 55 table.info td {
50 56 border-left: 1px solid black;
51 57 border-right: 1px solid black;
52 58 }
53 59
54 60 tr.info-head {
55 61 background: #777777;
56 62 color: white;
57 63 }
58 64
59 65 tr.info-odd {
60 66 background: #dddddd;
61 67 }
62 68
63 69 tr.info-even {
64 70 background: #f0f0f0;
65 71 }
66 72
67 73 /*******************************
68 74 [Main]
69 75 ********************************/
70 76 div.submitbox {
71 77 border: thin solid black;
@@ -17,58 +17,58
17 17 a:hover { color: #fff; background-color:#000; }
18 18
19 19 .fieldWithErrors {
20 20 padding: 2px;
21 21 background-color: red;
22 22 display: table;
23 23 }
24 24
25 25 #errorExplanation {
26 26 width: 400px;
27 27 border: 2px solid red;
28 28 padding: 7px;
29 29 padding-bottom: 12px;
30 30 margin-bottom: 20px;
31 31 background-color: #f0f0f0;
32 32 }
33 33
34 34 #errorExplanation h2 {
35 35 text-align: left;
36 36 font-weight: bold;
37 37 padding: 5px 5px 5px 15px;
38 38 font-size: 12px;
39 39 margin: -7px;
40 40 background-color: #c00;
41 41 color: #fff;
42 42 }
43 43
44 44 #errorExplanation p {
45 45 color: #333;
46 46 margin-bottom: 0;
47 47 padding: 5px;
48 48 }
49 49
50 50 #errorExplanation ul li {
51 51 font-size: 12px;
52 52 list-style: square;
53 53 }
54 54
55 55 div.uploadStatus {
56 56 margin: 5px;
57 57 }
58 58
59 59 div.progressBar {
60 60 margin: 5px;
61 61 }
62 62
63 63 div.progressBar div.border {
64 64 background-color: #fff;
65 - border: 1px solid grey;
65 + border: 1px solid gray;
66 66 width: 100%;
67 67 }
68 68
69 69 div.progressBar div.background {
70 70 background-color: #333;
71 71 height: 18px;
72 72 width: 0%;
73 73 }
74 74
You need to be logged in to leave comments. Login now