diff --git a/app/controllers/application.rb b/app/controllers/application.rb --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -53,5 +53,17 @@ end end + def verify_time_limit + return true if session[:user_id]==nil + user = User.find(session[:user_id], :include => :site) + return true if user==nil or user.site == nil + if user.site.finished? + flash[:notice] = 'Error: the contest on your site is over.' + redirect_to :back + return false + end + return true + end + end diff --git a/app/controllers/main_controller.rb b/app/controllers/main_controller.rb --- a/app/controllers/main_controller.rb +++ b/app/controllers/main_controller.rb @@ -2,6 +2,11 @@ before_filter :authenticate, :except => [:index, :login] +# +# COMMENT OUT: filter in each action instead +# +# before_filter :verify_time_limit, :only => [:submit] + verify :method => :post, :only => [:submit], :redirect_to => { :action => :index } @@ -23,11 +28,20 @@ end def submit + user = User.find(session[:user_id]) + @submission = Submission.new(params[:submission]) - @submission.user_id = session[:user_id] + @submission.user = user @submission.language_id = 0 @submission.source = params['file'].read if params['file']!='' @submission.submitted_at = Time.new + + if user.site!=nil and user.site.finished? + @submission.errors.add_to_base "The contest is over." + prepare_list_information + render :action => 'list' and return + end + if @submission.valid? if @submission.save == false flash[:notice] = 'Error saving your submission' diff --git a/app/controllers/sites_controller.rb b/app/controllers/sites_controller.rb new file mode 100644 --- /dev/null +++ b/app/controllers/sites_controller.rb @@ -0,0 +1,87 @@ +class SitesController < ApplicationController + # GET /sites + # GET /sites.xml + def index + @sites = Site.find(:all) + + respond_to do |format| + format.html # index.html.erb + format.xml { render :xml => @sites } + end + end + + # GET /sites/1 + # GET /sites/1.xml + def show + @site = Site.find(params[:id]) + + respond_to do |format| + format.html # show.html.erb + format.xml { render :xml => @site } + end + end + + # GET /sites/new + # GET /sites/new.xml + def new + @site = Site.new + + respond_to do |format| + format.html # new.html.erb + format.xml { render :xml => @site } + end + end + + # GET /sites/1/edit + def edit + @site = Site.find(params[:id]) + end + + # POST /sites + # POST /sites.xml + def create + @site = Site.new(params[:site]) + @site.clear_start_time_if_not_started + + respond_to do |format| + if @site.save + flash[:notice] = 'Site was successfully created.' + format.html { redirect_to(@site) } + format.xml { render :xml => @site, :status => :created, :location => @site } + else + format.html { render :action => "new" } + format.xml { render :xml => @site.errors, :status => :unprocessable_entity } + end + end + end + + # PUT /sites/1 + # PUT /sites/1.xml + def update + @site = Site.find(params[:id]) + @site.clear_start_time_if_not_started + + respond_to do |format| + if @site.update_attributes(params[:site]) + flash[:notice] = 'Site was successfully updated.' + format.html { redirect_to(@site) } + format.xml { head :ok } + else + format.html { render :action => "edit" } + format.xml { render :xml => @site.errors, :status => :unprocessable_entity } + end + end + end + + # DELETE /sites/1 + # DELETE /sites/1.xml + def destroy + @site = Site.find(params[:id]) + @site.destroy + + respond_to do |format| + format.html { redirect_to(sites_url) } + format.xml { head :ok } + end + end +end diff --git a/app/controllers/test_controller.rb b/app/controllers/test_controller.rb --- a/app/controllers/test_controller.rb +++ b/app/controllers/test_controller.rb @@ -2,6 +2,11 @@ before_filter :authenticate +# +# COMMENT OUT: filter in each action instead +# +# before_filter :verify_time_limit, :only => [:submit] + verify :method => :post, :only => [:submit], :redirect_to => { :action => :index } @@ -13,6 +18,12 @@ def submit @user = User.find(session[:user_id]) + + if @user.site!=nil and @user.site.finished? + flash[:notice] = 'Error saving your test submission: Contest is over.' + redirect_to :action => 'index' and return + end + test_request = TestRequest.new_from_form_params(@user,params[:test_request]) if test_request.save redirect_to :action => 'index' diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -45,9 +45,17 @@ def user_title_bar(user) + if user.site!=nil and user.site.finished? + contest_over_string = < +THE CONTEST IS OVER + +CONTEST_OVER + end < +#{contest_over_string}
#{user.full_name}
diff --git a/app/helpers/sites_helper.rb b/app/helpers/sites_helper.rb new file mode 100644 --- /dev/null +++ b/app/helpers/sites_helper.rb @@ -0,0 +1,2 @@ +module SitesHelper +end diff --git a/app/models/site.rb b/app/models/site.rb new file mode 100644 --- /dev/null +++ b/app/models/site.rb @@ -0,0 +1,24 @@ +class Site < ActiveRecord::Base + + def clear_start_time_if_not_started + if !self.started + self.start_time = nil + end + end + + def finished? + if !self.started + return false + end + + contest_time = Configuration['contest.time_limit'] + if tmatch = /(\d+):(\d+)/.match(contest_time) + h = tmatch[1].to_i + m = tmatch[2].to_i + return Time.now > (self.start_time + h.hour + m.minute) + else + false + end + end + +end diff --git a/app/models/user.rb b/app/models/user.rb --- a/app/models/user.rb +++ b/app/models/user.rb @@ -6,6 +6,8 @@ has_many :test_requests, :order => "submitted_at DESC" + belongs_to :site + validates_presence_of :login validates_presence_of :full_name validates_length_of :full_name, :minimum => 1 diff --git a/app/views/layouts/sites.html.erb b/app/views/layouts/sites.html.erb new file mode 100644 --- /dev/null +++ b/app/views/layouts/sites.html.erb @@ -0,0 +1,17 @@ + + + + + + Sites: <%= controller.action_name %> + <%= stylesheet_link_tag 'scaffold' %> + + + +

<%= flash[:notice] %>

+ +<%= yield %> + + + diff --git a/app/views/sites/edit.html.erb b/app/views/sites/edit.html.erb new file mode 100644 --- /dev/null +++ b/app/views/sites/edit.html.erb @@ -0,0 +1,27 @@ +

Editing site

+ +<%= error_messages_for :site %> + +<% form_for(@site) do |f| %> +

+ Name
+ <%= f.text_field :name %> +

+ +

+ Started
+ <%= f.check_box :started %> +

+ +

+ Start time
+ <%= f.datetime_select :start_time %> +

+ +

+ <%= f.submit "Update" %> +

+<% end %> + +<%= link_to 'Show', @site %> | +<%= link_to 'Back', sites_path %> diff --git a/app/views/sites/index.html.erb b/app/views/sites/index.html.erb new file mode 100644 --- /dev/null +++ b/app/views/sites/index.html.erb @@ -0,0 +1,24 @@ +

Listing sites

+ + + + + + + + +<% for site in @sites %> + + + + + + + + +<% end %> +
NameStartedStart time
<%=h site.name %><%=h site.started %><%=h site.start_time %><%= link_to 'Show', site %><%= link_to 'Edit', edit_site_path(site) %><%= link_to 'Destroy', site, :confirm => 'Are you sure?', :method => :delete %>
+ +
+ +<%= link_to 'New site', new_site_path %> diff --git a/app/views/sites/new.html.erb b/app/views/sites/new.html.erb new file mode 100644 --- /dev/null +++ b/app/views/sites/new.html.erb @@ -0,0 +1,26 @@ +

New site

+ +<%= error_messages_for :site %> + +<% form_for(@site) do |f| %> +

+ Name
+ <%= f.text_field :name %> +

+ +

+ Started
+ <%= f.check_box :started %> +

+ +

+ Start time
+ <%= f.datetime_select :start_time %> +

+ +

+ <%= f.submit "Create" %> +

+<% end %> + +<%= link_to 'Back', sites_path %> diff --git a/app/views/sites/show.html.erb b/app/views/sites/show.html.erb new file mode 100644 --- /dev/null +++ b/app/views/sites/show.html.erb @@ -0,0 +1,18 @@ +

+ Name: + <%=h @site.name %> +

+ +

+ Started: + <%=h @site.started %> +

+ +

+ Start time: + <%=h @site.start_time %> +

+ + +<%= link_to 'Edit', edit_site_path(@site) %> | +<%= link_to 'Back', sites_path %> diff --git a/config/routes.rb b/config/routes.rb --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,6 @@ ActionController::Routing::Routes.draw do |map| + map.resources :sites + # The priority is based upon order of creation: first created -> highest priority. # Sample of regular route: diff --git a/db/migrate/024_create_sites.rb b/db/migrate/024_create_sites.rb new file mode 100644 --- /dev/null +++ b/db/migrate/024_create_sites.rb @@ -0,0 +1,15 @@ +class CreateSites < ActiveRecord::Migration + def self.up + create_table :sites do |t| + t.string :name + t.boolean :started + t.datetime :start_time + + t.timestamps + end + end + + def self.down + drop_table :sites + end +end diff --git a/db/migrate/025_add_site_to_user_and_add_default_site.rb b/db/migrate/025_add_site_to_user_and_add_default_site.rb new file mode 100644 --- /dev/null +++ b/db/migrate/025_add_site_to_user_and_add_default_site.rb @@ -0,0 +1,22 @@ +class AddSiteToUserAndAddDefaultSite < ActiveRecord::Migration + def self.up + default_site = Site.new({:name => 'default', + :started => false}) + default_site.save! + + add_column :users, :site_id, :integer + User.reset_column_information + + User.find(:all).each do |user| + user.site_id = default_site.id + user.save + end + end + + def self.down + remove_column :users, :site_id + + default_site = Site.find_by_name('default') + default_site.destroy + end +end diff --git a/db/schema.rb b/db/schema.rb --- a/db/schema.rb +++ b/db/schema.rb @@ -9,7 +9,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 23) do +ActiveRecord::Schema.define(:version => 25) do create_table "configurations", :force => true do |t| t.string "key" @@ -79,6 +79,14 @@ add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id" add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at" + create_table "sites", :force => true do |t| + t.string "name" + t.boolean "started" + t.datetime "start_time" + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "submissions", :force => true do |t| t.integer "user_id" t.integer "problem_id" @@ -127,12 +135,13 @@ add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id" create_table "users", :force => true do |t| - t.string "login", :limit => 10 - t.string "full_name" - t.string "hashed_password" - t.string "salt", :limit => 5 - t.string "alias" - t.string "email" + t.string "login", :limit => 10 + t.string "full_name" + t.string "hashed_password" + t.string "salt", :limit => 5 + t.string "alias" + t.string "email" + t.integer "site_id" end add_index "users", ["login"], :name => "index_users_on_login", :unique => true diff --git a/public/stylesheets/application.css b/public/stylesheets/application.css --- a/public/stylesheets/application.css +++ b/public/stylesheets/application.css @@ -21,6 +21,12 @@ margin-bottom: 5px; } +div.title span.contest-over-msg { + font-size: 15px; + color: red; + font-weight: bold; +} + div.title table { width: 100%; } diff --git a/public/stylesheets/scaffold.css b/public/stylesheets/scaffold.css --- a/public/stylesheets/scaffold.css +++ b/public/stylesheets/scaffold.css @@ -62,7 +62,7 @@ div.progressBar div.border { background-color: #fff; - border: 1px solid grey; + border: 1px solid gray; width: 100%; } diff --git a/spec/models/site_spec.rb b/spec/models/site_spec.rb new file mode 100644 --- /dev/null +++ b/spec/models/site_spec.rb @@ -0,0 +1,43 @@ + +require File.dirname(__FILE__) + '/../spec_helper' + +describe Site do + + before(:each) do + start_time = Time.local(2008,5,10,9,00) + @site = Site.new({:name => 'Test site', + :started => true, + :start_time => start_time }) + end + + it "should report that the contest is not finished when the contest time limit is not set" do + Configuration.should_receive(:[]).with('contest.time_limit'). + and_return('unlimit') + Time.should_not_receive(:now) + @site.finished?.should == false + end + + it "should report that the contest is finished when the contest is over" do + Configuration.should_receive(:[]).with('contest.time_limit'). + and_return('5:00') + Time.should_receive(:now).and_return(Time.local(2008,5,10,14,01)) + @site.finished?.should == true + end + + it "should report if the contest is finished correctly, when the contest is over, and the contest time contains some minutes" do + Configuration.should_receive(:[]).twice.with('contest.time_limit'). + and_return('5:15') + Time.should_receive(:now). + and_return(Time.local(2008,5,10,14,14),Time.local(2008,5,10,14,16)) + @site.finished?.should == false + @site.finished?.should == true + end + + it "should report that the contest is not finished, when the time is exactly at the finish time" do + Configuration.should_receive(:[]).with('contest.time_limit'). + and_return('5:00') + Time.should_receive(:now).and_return(Time.local(2008,5,10,14,00)) + @site.finished?.should == false + end + +end diff --git a/test/fixtures/sites.yml b/test/fixtures/sites.yml new file mode 100644 --- /dev/null +++ b/test/fixtures/sites.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html + +one: + name: MyString + started: false + start_time: 2008-04-09 14:08:28 + +two: + name: MyString + started: false + start_time: 2008-04-09 14:08:28 diff --git a/test/functional/sites_controller_test.rb b/test/functional/sites_controller_test.rb new file mode 100644 --- /dev/null +++ b/test/functional/sites_controller_test.rb @@ -0,0 +1,45 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class SitesControllerTest < ActionController::TestCase + def test_should_get_index + get :index + assert_response :success + assert_not_nil assigns(:sites) + end + + def test_should_get_new + get :new + assert_response :success + end + + def test_should_create_site + assert_difference('Site.count') do + post :create, :site => { } + end + + assert_redirected_to site_path(assigns(:site)) + end + + def test_should_show_site + get :show, :id => sites(:one).id + assert_response :success + end + + def test_should_get_edit + get :edit, :id => sites(:one).id + assert_response :success + end + + def test_should_update_site + put :update, :id => sites(:one).id, :site => { } + assert_redirected_to site_path(assigns(:site)) + end + + def test_should_destroy_site + assert_difference('Site.count', -1) do + delete :destroy, :id => sites(:one).id + end + + assert_redirected_to sites_path + end +end diff --git a/test/unit/site_test.rb b/test/unit/site_test.rb new file mode 100644 --- /dev/null +++ b/test/unit/site_test.rb @@ -0,0 +1,8 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class SiteTest < ActiveSupport::TestCase + # Replace this with your real tests. + def test_truth + assert true + end +end