Description:
renamed model Configuration to GraderConfiguration, renamed rhtml views to erb, fixed other small errors
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r320:c31111f6e4b5 - - 61 files changed: 696 inserted, 640 deleted

@@ -0,0 +1,176
1 + require 'yaml'
2 +
3 + #
4 + # This class also contains various login of the system.
5 + #
6 + class GraderConfiguration < ActiveRecord::Base
7 +
8 + SYSTEM_MODE_CONF_KEY = 'system.mode'
9 + TEST_REQUEST_EARLY_TIMEOUT_KEY = 'contest.test_request.early_timeout'
10 + MULTICONTESTS_KEY = 'system.multicontests'
11 + CONTEST_TIME_LIMIT_KEY = 'contest.time_limit'
12 +
13 + cattr_accessor :config_cache
14 + cattr_accessor :task_grading_info_cache
15 + cattr_accessor :contest_time_str
16 + cattr_accessor :contest_time
17 +
18 + GraderConfiguration.config_cache = nil
19 + GraderConfiguration.task_grading_info_cache = nil
20 +
21 + def self.config_cached?
22 + (defined? CONFIGURATION_CACHE_ENABLED) and (CONFIGURATION_CACHE_ENABLED)
23 + end
24 +
25 + def self.get(key)
26 + if GraderConfiguration.config_cached?
27 + if GraderConfiguration.config_cache == nil
28 + self.read_config
29 + end
30 + return GraderConfiguration.config_cache[key]
31 + else
32 + return GraderConfiguration.read_one_key(key)
33 + end
34 + end
35 +
36 + def self.[](key)
37 + self.get(key)
38 + end
39 +
40 + def self.reload
41 + self.read_config
42 + end
43 +
44 + def self.clear
45 + GraderConfiguration.config_cache = nil
46 + end
47 +
48 + #
49 + # View decision
50 + #
51 + def self.show_submitbox_to?(user)
52 + mode = get(SYSTEM_MODE_CONF_KEY)
53 + return false if mode=='analysis'
54 + if (mode=='contest')
55 + return false if (user.site!=nil) and
56 + ((user.site.started!=true) or (user.site.finished?))
57 + end
58 + return true
59 + end
60 +
61 + def self.show_tasks_to?(user)
62 + if time_limit_mode?
63 + return false if not user.contest_started?
64 + end
65 + return true
66 + end
67 +
68 + def self.show_grading_result
69 + return (get(SYSTEM_MODE_CONF_KEY)=='analysis')
70 + end
71 +
72 + def self.allow_test_request(user)
73 + mode = get(SYSTEM_MODE_CONF_KEY)
74 + early_timeout = get(TEST_REQUEST_EARLY_TIMEOUT_KEY)
75 + if (mode=='contest')
76 + return false if ((user.site!=nil) and
77 + ((user.site.started!=true) or
78 + (early_timeout and (user.site.time_left < 30.minutes))))
79 + end
80 + return false if mode=='analysis'
81 + return true
82 + end
83 +
84 + def self.task_grading_info
85 + if GraderConfiguration.task_grading_info_cache==nil
86 + read_grading_info
87 + end
88 + return GraderConfiguration.task_grading_info_cache
89 + end
90 +
91 + def self.standard_mode?
92 + return get(SYSTEM_MODE_CONF_KEY) == 'standard'
93 + end
94 +
95 + def self.contest_mode?
96 + return get(SYSTEM_MODE_CONF_KEY) == 'contest'
97 + end
98 +
99 + def self.indv_contest_mode?
100 + return get(SYSTEM_MODE_CONF_KEY) == 'indv-contest'
101 + end
102 +
103 + def self.multicontests?
104 + return get(MULTICONTESTS_KEY) == true
105 + end
106 +
107 + def self.time_limit_mode?
108 + mode = get(SYSTEM_MODE_CONF_KEY)
109 + return ((mode == 'contest') or (mode == 'indv-contest'))
110 + end
111 +
112 + def self.analysis_mode?
113 + return get(SYSTEM_MODE_CONF_KEY) == 'analysis'
114 + end
115 +
116 + def self.contest_time_limit
117 + contest_time_str = GraderConfiguration[CONTEST_TIME_LIMIT_KEY]
118 +
119 + if not defined? GraderConfiguration.contest_time_str
120 + GraderConfiguration.contest_time_str = nil
121 + end
122 +
123 + if GraderConfiguration.contest_time_str != contest_time_str
124 + GraderConfiguration.contest_time_str = contest_time_str
125 + if tmatch = /(\d+):(\d+)/.match(contest_time_str)
126 + h = tmatch[1].to_i
127 + m = tmatch[2].to_i
128 +
129 + GraderConfiguration.contest_time = h.hour + m.minute
130 + else
131 + GraderConfiguration.contest_time = nil
132 + end
133 + end
134 + return GraderConfiguration.contest_time
135 + end
136 +
137 + protected
138 +
139 + def self.convert_type(val,type)
140 + case type
141 + when 'string'
142 + return val
143 +
144 + when 'integer'
145 + return val.to_i
146 +
147 + when 'boolean'
148 + return (val=='true')
149 + end
150 + end
151 +
152 + def self.read_config
153 + GraderConfiguration.config_cache = {}
154 + GraderConfiguration.find(:all).each do |conf|
155 + key = conf.key
156 + val = conf.value
157 + GraderConfiguration.config_cache[key] = GraderConfiguration.convert_type(val,conf.value_type)
158 + end
159 + end
160 +
161 + def self.read_one_key(key)
162 + conf = GraderConfiguration.find_by_key(key)
163 + if conf
164 + return GraderConfiguration.convert_type(conf.value,conf.value_type)
165 + else
166 + return nil
167 + end
168 + end
169 +
170 + def self.read_grading_info
171 + f = File.open(TASK_GRADING_INFO_FILENAME)
172 + GraderConfiguration.task_grading_info_cache = YAML.load(f)
173 + f.close
174 + end
175 +
176 + end
@@ -0,0 +1,52
1 + <%= error_messages_for 'problem' %>
2 +
3 + <!--[form:problem]-->
4 + <p><label for="problem_name">Name</label><br/>
5 + <%= text_field 'problem', 'name' %></p>
6 +
7 + <p><label for="problem_full_name">Full name</label><br/>
8 + <%= text_field 'problem', 'full_name' %></p>
9 +
10 + <p><label for="problem_full_score">Full score</label><br/>
11 + <%= text_field 'problem', 'full_score' %></p>
12 +
13 + <p><label for="problem_date_added">Date added</label><br/>
14 + <%= date_select 'problem', 'date_added' %></p>
15 +
16 + <%
17 + # TODO: these should be put in model Problem, but I can't think of
18 + # nice default values for them. These values look fine only
19 + # in this case (of lazily adding new problems).
20 + @problem.available = true if @problem!=nil and @problem.available==nil
21 + @problem.test_allowed = true if @problem!=nil and @problem.test_allowed==nil
22 + @problem.output_only = false if @problem!=nil and @problem.output_only==nil
23 + %>
24 +
25 + <p>
26 + <label for="problem_available">Available?</label>
27 + <%= check_box :problem, :available %>
28 +
29 + <label for="problem_test_allowed">Test allowed?</label>
30 + <%= check_box :problem, :test_allowed %>
31 +
32 + <label for="problem_output_only">Output only?</label>
33 + <%= check_box :problem, :output_only %>
34 + </p>
35 +
36 + <%= error_messages_for 'description' %>
37 +
38 + <p><label for="description_body">Description</label><br/>
39 + <%= text_area :description, :body, :rows => 10, :cols => 80 %></p>
40 +
41 + <p><label for="description_markdowned">Markdowned?</label>
42 + <%= select "description",
43 + "markdowned",
44 + [['True',true],['False',false]],
45 + {:selected => (@description) ? @description.markdowned : false }
46 + %></p>
47 +
48 + <p><label for="problem_url">URL</label><br/>
49 + <%= text_field 'problem', 'url' %></p>
50 +
51 +
52 + <!--[eoform:problem]-->
@@ -0,0 +1,9
1 + <h1>Editing problem</h1>
2 +
3 + <%= form_tag :action => 'update', :id => @problem do %>
4 + <%= render :partial => 'form' %>
5 + <%= submit_tag 'Edit' %>
6 + <% end %>
7 +
8 + <%= link_to 'Show', :action => 'show', :id => @problem %> |
9 + <%= link_to 'Back', :action => 'list' %>
@@ -0,0 +1,67
1 + <% content_for :head do %>
2 + <%= stylesheet_link_tag 'problems' %>
3 + <%= javascript_include_tag :defaults %>
4 + <% end %>
5 +
6 + <h1>Listing problems</h1>
7 +
8 + <p>
9 + <%= link_to '[New problem]', :action => 'new' %>
10 + <%= link_to '[Manage problems]', :action => 'manage' %>
11 + <%= link_to '[Import problems]', :action => 'import' %>
12 + <%= link_to '[Turn off all problems]', :action => 'turn_all_off' %>
13 + <%= link_to '[Turn on all problems]', :action => 'turn_all_on' %>
14 + </p>
15 +
16 + <div class="submitbox">
17 + <%= form_tag :action => 'quick_create' do %>
18 + <b>Quick New:</b>
19 + <label for="problem_name">Name</label>
20 + <%= text_field 'problem', 'name' %> |
21 + <label for="problem_full_name">Full name</label>
22 + <%= text_field 'problem', 'full_name' %>
23 + <%= submit_tag "Create" %>
24 + <% end %>
25 + </div>
26 +
27 + <table>
28 + <tr>
29 + <th>Name</th>
30 + <th>Full name</th>
31 + <th>Full score</th>
32 + <th>Date added</th>
33 + <th>Avail?</th>
34 + <th>Test?</th>
35 + <% if GraderConfiguration.multicontests? %>
36 + <th>Contests</th>
37 + <% end %>
38 + </tr>
39 +
40 + <% for problem in @problems %>
41 + <tr id="prob-<%= problem.id %>" name="prob-<%= problem.id %>" class="<%= (problem.available) ? "available" : "not-available" %>">
42 + <% @problem=problem %>
43 + <td><%= in_place_editor_field :problem, :name, {}, :rows=>1 %></td>
44 + <td><%= in_place_editor_field :problem, :full_name, {}, :rows=>1 %></td>
45 + <td><%= in_place_editor_field :problem, :full_score, {}, :rows=>1 %></td>
46 + <td><%= problem.date_added %></td>
47 + <td id="prob-<%= problem.id %>-avail"><%= problem.available %></td>
48 + <td><%= problem.test_allowed %></td>
49 +
50 + <% if GraderConfiguration.multicontests? %>
51 + <td>
52 + <%= problem.contests.collect { |c| c.name }.join(', ') %>
53 + </td>
54 + <% end %>
55 +
56 + <td><%= link_to_remote '[Toggle]', :url => {:action => 'toggle', :id => problem.id } %></td>
57 + <td><%= link_to '[Stat]', :action => 'stat', :id => problem.id %></td>
58 + <td><%= link_to '[Show]', :action => 'show', :id => problem %></td>
59 + <td><%= link_to '[Edit]', :action => 'edit', :id => problem %></td>
60 + <td><%= link_to '[Destroy]', { :action => 'destroy', :id => problem }, :confirm => 'Are you sure?', :method => :post %></td>
61 + </tr>
62 + <% end %>
63 + </table>
64 +
65 + <br />
66 +
67 + <%= link_to '[New problem]', :action => 'new' %>
@@ -0,0 +1,8
1 + <h1>New problem</h1>
2 +
3 + <%= form_tag :action => 'create' do %>
4 + <%= render :partial => 'form' %>
5 + <%= submit_tag "Create" %>
6 + <% end %>
7 +
8 + <%= link_to 'Back', :action => 'list' %>
@@ -0,0 +1,28
1 + <h1>Problem stat: <%= @problem.name %></h1>
2 +
3 + <i>This is just a hack. Really not efficient.</i><br/><br/>
4 +
5 + <% if @submissions!=nil %>
6 + <table class="info">
7 + <tr class="info-head">
8 + <th>login</th>
9 + <th>name</th>
10 + <th>submitted_at</th>
11 + <th>points</th>
12 + <th>comment</th>
13 + </tr>
14 + <% count = 0 %>
15 + <% @submissions.each do |sub| %>
16 + <tr class="<%= (count % 2 ==0) ? "info-even" : "info-odd" %>">
17 + <td><%= sub.user.login %></td>
18 + <td><%= sub.user.full_name if sub.user %></td>
19 + <td><%= sub.submitted_at.to_s %></td>
20 + <td><%= sub.points %></td>
21 + <td><div style="font-family: monospace"><%= sub.grader_comment %></div></td>
22 + </tr>
23 + <% count += 1 %>
24 + <% end %>
25 + </table>
26 + <% else %>
27 + No submission
28 + <% end %>
@@ -0,0 +1,22
1 + <%= error_messages_for 'user' %>
2 +
3 + <!--[form:user]-->
4 + <p><label for="user_name">Login</label><br/>
5 + <%= text_field 'user', 'login' %></p>
6 +
7 + <p><label for="user_name">Full name</label><br/>
8 + <%= text_field 'user', 'full_name' %></p>
9 +
10 + <p><label for="password">Password</label><br/>
11 + <%= password_field 'user', 'password' %></p>
12 +
13 + <p><label for="password_confirmation">Password (confirm)</label><br/>
14 + <%= password_field 'user', 'password_confirmation' %></p>
15 +
16 + <p><label for="user_email">E-mail</label><br/>
17 + <%= text_field 'user', 'email' %></p>
18 +
19 + <p><label for="user_alias">Alias</label><br/>
20 + <%= text_field 'user', 'alias' %></p>
21 + <!--[eoform:user]-->
22 +
@@ -0,0 +1,9
1 + <h1>Editing user</h1>
2 +
3 + <%= form_tag :action => 'update', :id => @user do %>
4 + <%= render :partial => 'form' %>
5 + <%= submit_tag 'Edit' %>
6 + <% end %>
7 +
8 + <%= link_to 'Show', :action => 'show', :id => @user %> |
9 + <%= link_to 'Back', :action => 'list' %>
@@ -0,0 +1,86
1 + <h1>Listing users</h1>
2 +
3 + <div class="submitbox">
4 + <b>Quick add</b>
5 + <%= form_tag :action => 'create' do %>
6 + <table border="0">
7 + <tr>
8 + <td><label for="user_login">Login</label></td>
9 + <td><label for="user_full_name">Full name</label></td>
10 + <td><label for="user_password">Password</label></td>
11 + <td><label for="user_password_confirmation">Confirm</label></td>
12 + <td><label for="user_email">Email</label></td>
13 + </tr>
14 + <tr>
15 + <td><%= text_field 'user', 'login', :size => 10 %></td>
16 + <td><%= text_field 'user', 'full_name', :size => 30 %></td>
17 + <td><%= password_field 'user', 'password', :size => 10 %></td>
18 + <td><%= password_field 'user', 'password_confirmation', :size => 10 %></td>
19 + <td><%= text_field 'user', 'email', :size => 15 %></td>
20 + <td><%= submit_tag "Create" %></td>
21 + </tr>
22 + </table>
23 + <% end %>
24 + <br/>
25 + <b>Import from site management</b>
26 + <%= form_tag({:action => 'import'}, :multipart => true) do %>
27 + File: <%= file_field_tag 'file' %> <%= submit_tag 'Import' %>
28 + <% end %>
29 + <br/>
30 + <b>What else: </b>
31 + <%= link_to '[New user]', :action => 'new' %>
32 + <%= link_to '[New list of users]', :action => 'new_list' %>
33 + <%= link_to '[View administrators]', :action => 'admin' %>
34 + <%= link_to '[Random passwords]', :action => 'random_all_passwords' %>
35 + <%= link_to '[View active users]', :action => 'active' %>
36 + <%= link_to '[Mass mailing]', :action => 'mass_mailing' %>
37 + <% if GraderConfiguration.multicontests? %>
38 + <br/><b>Multi-contest:</b>
39 + <%= link_to '[Manage bulk users in contests]', :action => 'contest_management' %>
40 + View users in:
41 + <% @contests.each do |contest| %>
42 + <%= link_to "[#{contest.name}]", :action => 'contests', :id => contest.id %>
43 + <% end %>
44 + <%= link_to "[no contest]", :action => 'contests', :id => 'none' %>
45 + <% end %>
46 + </div>
47 +
48 + Total <%= @user_count %> users |
49 + <% if !@paginated %>
50 + Display all users.
51 + <%= link_to '[show in pages]', :action => 'list', :page => '1' %>
52 + <% else %>
53 + Display in pages.
54 + <%= link_to '[display all]', :action => 'list', :page => 'all' %> |
55 + <%= will_paginate @users, :container => false %>
56 + <% end %>
57 + <table class="info">
58 + <tr class="info-head">
59 + <% for column in User.content_columns %>
60 + <% if !@hidden_columns.index(column.name) %>
61 + <th><%= column.human_name %></th>
62 + <% end %>
63 + <% end %>
64 + <th></th>
65 + <th></th>
66 + <th></th>
67 + </tr>
68 +
69 + <% for user in @users %>
70 + <tr class="info-<%= cycle("odd","even") %>">
71 + <% for column in User.content_columns %>
72 + <% if !@hidden_columns.index(column.name) %>
73 + <td><%=h user.send(column.name) %></td>
74 + <% end %>
75 + <% end %>
76 + <td><%= link_to 'Show', :action => 'show', :id => user %></td>
77 + <td><%= link_to 'Edit', :action => 'edit', :id => user %></td>
78 + <td><%= link_to 'Destroy', { :action => 'destroy', :id => user }, :confirm => 'Are you sure?', :method => :post %></td>
79 + </tr>
80 + <% end %>
81 + </table>
82 +
83 + <br />
84 +
85 + <%= link_to '[New user]', :action => 'new' %>
86 + <%= link_to '[New list of users]', :action => 'new_list' %>
@@ -0,0 +1,8
1 + <h1>New user</h1>
2 +
3 + <%= form_tag :action => 'create' do %>
4 + <%= render :partial => 'form' %>
5 + <%= submit_tag "Create" %>
6 + <% end %>
7 +
8 + <%= link_to 'Back', :action => 'list' %>
@@ -0,0 +1,8
1 + <h1>Adding list of users</h1>
2 +
3 + <%= form_tag :action => 'create_from_list' do %>
4 + <%= submit_tag 'create users' %><br/>
5 + List of user information in this format: <tt>user_id,name(,passwd(,alias))</tt><br/>
6 + Note that <tt>passwd</tt> and <tt>alias</tt> is optional.<br/>
7 + <%= text_area_tag 'user_list', nil, :rows => 50, :cols => 80 %>
8 + <% end %>
@@ -0,0 +1,10
1 + <h1>User information</h1>
2 +
3 + <% for column in User.content_columns %>
4 + <p>
5 + <b><%= column.human_name %>:</b> <%=h @user.send(column.name) %>
6 + </p>
7 + <% end %>
8 +
9 + <%= link_to 'Edit', :action => 'edit', :id => @user %> |
10 + <%= link_to 'Back', :action => 'list' %>
@@ -0,0 +1,43
1 + <h1>User grading results</h1>
2 +
3 + <table class="info">
4 + <tr class="info-head">
5 + <th>User</th>
6 + <th>Name</th>
7 + <th>Activated?</th>
8 + <th>Logged in</th>
9 + <th>Contest(s)</th>
10 + <% @problems.each do |p| %>
11 + <th><%= p.name %></th>
12 + <% end %>
13 + <th>Total</th>
14 + <th>Passed</th>
15 + </tr>
16 + <% counter = 0 %>
17 + <% @scorearray.each do |sc| %>
18 + <tr class="<%= (counter %2 ==0) ? "info-even" : "info-odd" %>">
19 + <% total = 0 %>
20 + <% num_passed = 0 %>
21 + <% sc.each_index do |i| %>
22 + <% if i==0 %>
23 + <td><%= sc[i].login %></td>
24 + <td><%= sc[i].full_name %></td>
25 + <td><%= sc[i].activated %></td>
26 + <td>
27 + <%= sc[i].try(:contest_stat).try(:started_at)!=nil ? 'yes' : 'no' %>
28 + </td>
29 + <td>
30 + <%= sc[i].contests.collect {|c| c.name}.join(', ') %>
31 + </td>
32 + <% else %>
33 + <td><%= sc[i][0] %></td>
34 + <% total += sc[i][0] %>
35 + <% num_passed += 1 if sc[i][1] %>
36 + <% end %>
37 + <% end %>
38 + <td><%= total %></td>
39 + <td><%= num_passed %></td>
40 + </tr>
41 + <% counter += 1 %>
42 + <% end %>
43 + </table>
@@ -0,0 +1,5
1 + class RenameConfigurationsToGraderConfigurations < ActiveRecord::Migration
2 + def change
3 + rename_table 'configurations', 'grader_configurations'
4 + end
5 + end
@@ -1,47 +1,48
1 1 source 'https://rubygems.org'
2 2
3 3 gem 'rails', '3.2.8'
4 4
5 5 # Bundle edge Rails instead:
6 6 # gem 'rails', :git => 'git://github.com/rails/rails.git'
7 7
8 8 gem 'mysql2'
9 9
10 10 # Gems used only for assets and not required
11 11 # in production environments by default.
12 12 group :assets do
13 13 gem 'sass-rails', '~> 3.2.3'
14 14 gem 'coffee-rails', '~> 3.2.1'
15 15
16 16 # See https://github.com/sstephenson/execjs#readme for more supported runtimes
17 17 # gem 'therubyracer', :platforms => :ruby
18 18
19 19 gem 'uglifier', '>= 1.0.3'
20 20 end
21 21
22 22 gem 'prototype-rails'
23 23
24 24 # To use ActiveModel has_secure_password
25 25 # gem 'bcrypt-ruby', '~> 3.0.0'
26 26
27 27 # To use Jbuilder templates for JSON
28 28 # gem 'jbuilder'
29 29
30 30 # Use unicorn as the app server
31 31 # gem 'unicorn'
32 32
33 33 # Deploy with Capistrano
34 34 # gem 'capistrano'
35 35
36 36 # To use debugger
37 37 # gem 'debugger'
38 38
39 39 gem "haml"
40 40 gem "tmail"
41 41 gem "rdiscount", :require => "rdiscount"
42 42 gem "test-unit"
43 43 gem 'will_paginate', '~> 3.0.0'
44 + gem 'dynamic_form'
44 45
45 46 group :test, :development do
46 47 gem "rspec-rails", "~> 2.0"
47 48 end
@@ -1,135 +1,137
1 1 GEM
2 2 remote: https://rubygems.org/
3 3 specs:
4 4 actionmailer (3.2.8)
5 5 actionpack (= 3.2.8)
6 6 mail (~> 2.4.4)
7 7 actionpack (3.2.8)
8 8 activemodel (= 3.2.8)
9 9 activesupport (= 3.2.8)
10 10 builder (~> 3.0.0)
11 11 erubis (~> 2.7.0)
12 12 journey (~> 1.0.4)
13 13 rack (~> 1.4.0)
14 14 rack-cache (~> 1.2)
15 15 rack-test (~> 0.6.1)
16 16 sprockets (~> 2.1.3)
17 17 activemodel (3.2.8)
18 18 activesupport (= 3.2.8)
19 19 builder (~> 3.0.0)
20 20 activerecord (3.2.8)
21 21 activemodel (= 3.2.8)
22 22 activesupport (= 3.2.8)
23 23 arel (~> 3.0.2)
24 24 tzinfo (~> 0.3.29)
25 25 activeresource (3.2.8)
26 26 activemodel (= 3.2.8)
27 27 activesupport (= 3.2.8)
28 28 activesupport (3.2.8)
29 29 i18n (~> 0.6)
30 30 multi_json (~> 1.0)
31 31 arel (3.0.2)
32 32 builder (3.0.3)
33 33 coffee-rails (3.2.2)
34 34 coffee-script (>= 2.2.0)
35 35 railties (~> 3.2.0)
36 36 coffee-script (2.2.0)
37 37 coffee-script-source
38 38 execjs
39 39 coffee-script-source (1.3.3)
40 40 diff-lcs (1.1.3)
41 + dynamic_form (1.1.4)
41 42 erubis (2.7.0)
42 43 execjs (1.4.0)
43 44 multi_json (~> 1.0)
44 45 haml (3.1.7)
45 46 hike (1.2.1)
46 47 i18n (0.6.1)
47 48 journey (1.0.4)
48 49 json (1.7.5)
49 50 mail (2.4.4)
50 51 i18n (>= 0.4.0)
51 52 mime-types (~> 1.16)
52 53 treetop (~> 1.4.8)
53 54 mime-types (1.19)
54 55 multi_json (1.3.6)
55 56 mysql2 (0.3.11)
56 57 polyglot (0.3.3)
57 58 prototype-rails (3.2.1)
58 59 rails (~> 3.2)
59 60 rack (1.4.1)
60 61 rack-cache (1.2)
61 62 rack (>= 0.4)
62 63 rack-ssl (1.3.2)
63 64 rack
64 65 rack-test (0.6.2)
65 66 rack (>= 1.0)
66 67 rails (3.2.8)
67 68 actionmailer (= 3.2.8)
68 69 actionpack (= 3.2.8)
69 70 activerecord (= 3.2.8)
70 71 activeresource (= 3.2.8)
71 72 activesupport (= 3.2.8)
72 73 bundler (~> 1.0)
73 74 railties (= 3.2.8)
74 75 railties (3.2.8)
75 76 actionpack (= 3.2.8)
76 77 activesupport (= 3.2.8)
77 78 rack-ssl (~> 1.3.2)
78 79 rake (>= 0.8.7)
79 80 rdoc (~> 3.4)
80 81 thor (>= 0.14.6, < 2.0)
81 82 rake (0.9.2.2)
82 83 rdiscount (1.6.8)
83 84 rdoc (3.12)
84 85 json (~> 1.4)
85 86 rspec (2.11.0)
86 87 rspec-core (~> 2.11.0)
87 88 rspec-expectations (~> 2.11.0)
88 89 rspec-mocks (~> 2.11.0)
89 90 rspec-core (2.11.1)
90 91 rspec-expectations (2.11.3)
91 92 diff-lcs (~> 1.1.3)
92 93 rspec-mocks (2.11.3)
93 94 rspec-rails (2.11.0)
94 95 actionpack (>= 3.0)
95 96 activesupport (>= 3.0)
96 97 railties (>= 3.0)
97 98 rspec (~> 2.11.0)
98 99 sass (3.2.1)
99 100 sass-rails (3.2.5)
100 101 railties (~> 3.2.0)
101 102 sass (>= 3.1.10)
102 103 tilt (~> 1.3)
103 104 sprockets (2.1.3)
104 105 hike (~> 1.2)
105 106 rack (~> 1.0)
106 107 tilt (~> 1.1, != 1.3.0)
107 108 test-unit (2.5.2)
108 109 thor (0.16.0)
109 110 tilt (1.3.3)
110 111 tmail (1.2.7.1)
111 112 treetop (1.4.10)
112 113 polyglot
113 114 polyglot (>= 0.3.1)
114 115 tzinfo (0.3.33)
115 116 uglifier (1.3.0)
116 117 execjs (>= 0.3.0)
117 118 multi_json (~> 1.0, >= 1.0.2)
118 119 will_paginate (3.0.3)
119 120
120 121 PLATFORMS
121 122 ruby
122 123
123 124 DEPENDENCIES
124 125 coffee-rails (~> 3.2.1)
126 + dynamic_form
125 127 haml
126 128 mysql2
127 129 prototype-rails
128 130 rails (= 3.2.8)
129 131 rdiscount
130 132 rspec-rails (~> 2.0)
131 133 sass-rails (~> 3.2.3)
132 134 test-unit
133 135 tmail
134 136 uglifier (>= 1.0.3)
135 137 will_paginate (~> 3.0.0)
@@ -1,83 +1,83
1 1 class ApplicationController < ActionController::Base
2 2 protect_from_forgery
3 3
4 4 SINGLE_USER_MODE_CONF_KEY = 'system.single_user_mode'
5 5
6 6 def admin_authorization
7 7 return false unless authenticate
8 8 user = User.find(session[:user_id], :include => ['roles'])
9 9 redirect_to :controller => 'main', :action => 'login' unless user.admin?
10 10 end
11 11
12 12 def authorization_by_roles(allowed_roles)
13 13 return false unless authenticate
14 14 user = User.find(session[:user_id])
15 15 unless user.roles.detect { |role| allowed_roles.member?(role.name) }
16 16 flash[:notice] = 'You are not authorized to view the page you requested'
17 17 redirect_to :controller => 'main', :action => 'login'
18 18 return false
19 19 end
20 20 end
21 21
22 22 protected
23 23
24 24 def authenticate
25 25 unless session[:user_id]
26 26 redirect_to :controller => 'main', :action => 'login'
27 27 return false
28 28 end
29 29
30 30 # check if run in single user mode
31 - if Configuration[SINGLE_USER_MODE_CONF_KEY]
31 + if GraderConfiguration[SINGLE_USER_MODE_CONF_KEY]
32 32 user = User.find(session[:user_id])
33 33 if user==nil or (not user.admin?)
34 34 flash[:notice] = 'You cannot log in at this time'
35 35 redirect_to :controller => 'main', :action => 'login'
36 36 return false
37 37 end
38 38 return true
39 39 end
40 40
41 - if Configuration.multicontests?
41 + if GraderConfiguration.multicontests?
42 42 user = User.find(session[:user_id])
43 43 return true if user.admin?
44 44 begin
45 45 if user.contest_stat(true).forced_logout
46 46 flash[:notice] = 'You have been automatically logged out.'
47 47 redirect_to :controller => 'main', :action => 'index'
48 48 end
49 49 rescue
50 50 end
51 51 end
52 52 return true
53 53 end
54 54
55 55 def authorization
56 56 return false unless authenticate
57 57 user = User.find(session[:user_id])
58 58 unless user.roles.detect { |role|
59 59 role.rights.detect{ |right|
60 60 right.controller == self.class.controller_name and
61 61 (right.action == 'all' or right.action == action_name)
62 62 }
63 63 }
64 64 flash[:notice] = 'You are not authorized to view the page you requested'
65 65 #request.env['HTTP_REFERER'] ? (redirect_to :back) : (redirect_to :controller => 'login')
66 66 redirect_to :controller => 'main', :action => 'login'
67 67 return false
68 68 end
69 69 end
70 70
71 71 def verify_time_limit
72 72 return true if session[:user_id]==nil
73 73 user = User.find(session[:user_id], :include => :site)
74 74 return true if user==nil or user.site == nil
75 75 if user.contest_finished?
76 76 flash[:notice] = 'Error: the contest you are participating is over.'
77 77 redirect_to :back
78 78 return false
79 79 end
80 80 return true
81 81 end
82 82
83 83 end
@@ -1,20 +1,20
1 1 class ConfigurationsController < ApplicationController
2 2
3 3 before_filter :authenticate
4 4 before_filter { |controller| controller.authorization_by_roles(['admin'])}
5 5
6 6 in_place_edit_for :configuration, :key
7 7 in_place_edit_for :configuration, :type
8 8 in_place_edit_for :configuration, :value
9 9
10 10 def index
11 - @configurations = Configuration.find(:all,
11 + @configurations = GraderConfiguration.find(:all,
12 12 :order => '`key`')
13 13 end
14 14
15 15 def reload
16 - Configuration.reload
16 + GraderConfiguration.reload
17 17 redirect_to :action => 'index'
18 18 end
19 19
20 20 end
@@ -1,50 +1,50
1 1 class ContestManagementController < ApplicationController
2 2
3 3 before_filter :admin_authorization
4 4
5 5 def index
6 6 @num_contests = Contest.count()
7 7 end
8 8
9 9 def user_stat
10 - if not Configuration.indv_contest_mode?
10 + if not GraderConfiguration.indv_contest_mode?
11 11 redirect_to :action => 'index' and return
12 12 end
13 13
14 14 @users = User.find(:all)
15 15 @start_times = {}
16 16 UserContestStat.find(:all).each do |stat|
17 17 @start_times[stat.user_id] = stat.started_at
18 18 end
19 19 end
20 20
21 21 def clear_stat
22 22 user = User.find(params[:id])
23 23 if user.contest_stat!=nil
24 24 user.contest_stat.destroy
25 25 end
26 26 redirect_to :action => 'user_stat'
27 27 end
28 28
29 29 def clear_all_stat
30 - if not Configuration.indv_contest_mode?
30 + if not GraderConfiguration.indv_contest_mode?
31 31 redirect_to :action => 'index' and return
32 32 end
33 33
34 34 UserContestStat.delete_all()
35 35 flash[:notice] = 'All start time statistic cleared.'
36 36 redirect_to :action => 'index'
37 37 end
38 38
39 39 def change_contest_mode
40 40 if ['standard', 'contest', 'indv-contest'].include? params[:id]
41 - config = Configuration.find_by_key('system.mode')
41 + config = GraderConfiguration.find_by_key('system.mode')
42 42 config.value = params[:id]
43 43 config.save
44 44 else
45 45 flash[:notice] = 'Wrong contest mode value'
46 46 end
47 47 redirect_to :action => 'index'
48 48 end
49 49
50 50 end
@@ -1,51 +1,51
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 session[:admin] = user.admin?
13 13
14 14 # clear forced logout flag for multicontests contest change
15 - if Configuration.multicontests?
15 + if GraderConfiguration.multicontests?
16 16 contest_stat = user.contest_stat
17 17 if contest_stat.respond_to? :forced_logout
18 18 if contest_stat.forced_logout
19 19 contest_stat.forced_logout = false
20 20 contest_stat.save
21 21 end
22 22 end
23 23 end
24 24
25 25 redirect_to :controller => 'main', :action => 'list'
26 26 else
27 27 flash[:notice] = 'Wrong password'
28 28 redirect_to :controller => 'main', :action => 'login'
29 29 end
30 30 end
31 31
32 32 def site_login
33 33 begin
34 34 site = Site.find(params[:login][:site_id])
35 35 rescue ActiveRecord::RecordNotFound
36 36 site = nil
37 37 end
38 38 if site==nil
39 39 flash[:notice] = 'Wrong site'
40 40 redirect_to :controller => 'main', :action => 'login' and return
41 41 end
42 42 if (site.password) and (site.password == params[:login][:password])
43 43 session[:site_id] = site.id
44 44 redirect_to :controller => 'site', :action => 'index'
45 45 else
46 46 flash[:notice] = 'Wrong site password'
47 47 redirect_to :controller => 'site', :action => 'login'
48 48 end
49 49 end
50 50
51 51 end
@@ -1,295 +1,295
1 1 class MainController < ApplicationController
2 2
3 3 before_filter :authenticate, :except => [:index, :login]
4 4 before_filter :check_viewability, :except => [:index, :login]
5 5
6 6 append_before_filter :confirm_and_update_start_time,
7 7 :except => [:index,
8 8 :login,
9 9 :confirm_contest_start]
10 10
11 11 # to prevent log in box to be shown when user logged out of the
12 12 # system only in some tab
13 13 prepend_before_filter :reject_announcement_refresh_when_logged_out,
14 14 :only => [:announcements]
15 15
16 16 # COMMENTED OUT: filter in each action instead
17 17 # before_filter :verify_time_limit, :only => [:submit]
18 18
19 19 verify :method => :post, :only => [:submit],
20 20 :redirect_to => { :action => :index }
21 21
22 22 # COMMENT OUT: only need when having high load
23 23 # caches_action :index, :login
24 24
25 25 # NOTE: This method is not actually needed, 'config/routes.rb' has
26 26 # assigned action login as a default action.
27 27 def index
28 28 redirect_to :action => 'login'
29 29 end
30 30
31 31 def login
32 32 saved_notice = flash[:notice]
33 33 reset_session
34 34 flash.now[:notice] = saved_notice
35 35
36 36 # EXPERIMENT:
37 37 # Hide login if in single user mode and the url does not
38 38 # explicitly specify /login
39 39 #
40 40 # logger.info "PATH: #{request.path}"
41 - # if Configuration['system.single_user_mode'] and
41 + # if GraderConfiguration['system.single_user_mode'] and
42 42 # request.path!='/main/login'
43 43 # @hidelogin = true
44 44 # end
45 45
46 46 @announcements = Announcement.find_for_frontpage
47 47 render :action => 'login', :layout => 'empty'
48 48 end
49 49
50 50 def list
51 51 prepare_list_information
52 52 end
53 53
54 54 def help
55 55 @user = User.find(session[:user_id])
56 56 end
57 57
58 58 def submit
59 59 user = User.find(session[:user_id])
60 60
61 61 @submission = Submission.new(params[:submission])
62 62 @submission.user = user
63 63 @submission.language_id = 0
64 64 if (params['file']) and (params['file']!='')
65 65 @submission.source = params['file'].read
66 66 @submission.source_filename = params['file'].original_filename
67 67 end
68 68 @submission.submitted_at = Time.new.gmtime
69 69
70 - if Configuration.time_limit_mode? and user.contest_finished?
70 + if GraderConfiguration.time_limit_mode? and user.contest_finished?
71 71 @submission.errors.add_to_base "The contest is over."
72 72 prepare_list_information
73 73 render :action => 'list' and return
74 74 end
75 75
76 76 if @submission.valid?
77 77 if @submission.save == false
78 78 flash[:notice] = 'Error saving your submission'
79 79 elsif Task.create(:submission_id => @submission.id,
80 80 :status => Task::STATUS_INQUEUE) == false
81 81 flash[:notice] = 'Error adding your submission to task queue'
82 82 end
83 83 else
84 84 prepare_list_information
85 85 render :action => 'list' and return
86 86 end
87 87 redirect_to :action => 'list'
88 88 end
89 89
90 90 def source
91 91 submission = Submission.find(params[:id])
92 92 if ((submission.user_id == session[:user_id]) and
93 93 (submission.problem != nil) and
94 94 (submission.problem.available))
95 95 send_data(submission.source,
96 96 {:filename => submission.download_filename,
97 97 :type => 'text/plain'})
98 98 else
99 99 flash[:notice] = 'Error viewing source'
100 100 redirect_to :action => 'list'
101 101 end
102 102 end
103 103
104 104 def compiler_msg
105 105 @submission = Submission.find(params[:id])
106 106 if @submission.user_id == session[:user_id]
107 107 render :action => 'compiler_msg', :layout => 'empty'
108 108 else
109 109 flash[:notice] = 'Error viewing source'
110 110 redirect_to :action => 'list'
111 111 end
112 112 end
113 113
114 114 def submission
115 115 @user = User.find(session[:user_id])
116 116 @problems = @user.available_problems
117 117 if params[:id]==nil
118 118 @problem = nil
119 119 @submissions = nil
120 120 else
121 121 @problem = Problem.find_by_name(params[:id])
122 122 if not @problem.available
123 123 redirect_to :action => 'list'
124 124 flash[:notice] = 'Error: submissions for that problem are not viewable.'
125 125 return
126 126 end
127 127 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
128 128 end
129 129 end
130 130
131 131 def result
132 - if !Configuration.show_grading_result
132 + if !GraderConfiguration.show_grading_result
133 133 redirect_to :action => 'list' and return
134 134 end
135 135 @user = User.find(session[:user_id])
136 136 @submission = Submission.find(params[:id])
137 137 if @submission.user!=@user
138 138 flash[:notice] = 'You are not allowed to view result of other users.'
139 139 redirect_to :action => 'list' and return
140 140 end
141 141 prepare_grading_result(@submission)
142 142 end
143 143
144 144 def load_output
145 - if !Configuration.show_grading_result or params[:num]==nil
145 + if !GraderConfiguration.show_grading_result or params[:num]==nil
146 146 redirect_to :action => 'list' and return
147 147 end
148 148 @user = User.find(session[:user_id])
149 149 @submission = Submission.find(params[:id])
150 150 if @submission.user!=@user
151 151 flash[:notice] = 'You are not allowed to view result of other users.'
152 152 redirect_to :action => 'list' and return
153 153 end
154 154 case_num = params[:num].to_i
155 155 out_filename = output_filename(@user.login,
156 156 @submission.problem.name,
157 157 @submission.id,
158 158 case_num)
159 159 if !FileTest.exists?(out_filename)
160 160 flash[:notice] = 'Output not found.'
161 161 redirect_to :action => 'list' and return
162 162 end
163 163
164 164 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
165 165 response.headers['Content-Type'] = "application/force-download"
166 166 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
167 167 response.headers["X-Sendfile"] = out_filename
168 168 response.headers['Content-length'] = File.size(out_filename)
169 169 render :nothing => true
170 170 else
171 171 send_file out_filename, :stream => false, :filename => "output-#{case_num}.txt", :type => "text/plain"
172 172 end
173 173 end
174 174
175 175 def error
176 176 @user = User.find(session[:user_id])
177 177 end
178 178
179 179 # announcement refreshing and hiding methods
180 180
181 181 def announcements
182 182 if params.has_key? 'recent'
183 183 prepare_announcements(params[:recent])
184 184 else
185 185 prepare_announcements
186 186 end
187 187 render(:partial => 'announcement',
188 188 :collection => @announcements,
189 189 :locals => {:announcement_effect => true})
190 190 end
191 191
192 192 def confirm_contest_start
193 193 user = User.find(session[:user_id])
194 194 if request.method == :post
195 195 user.update_start_time
196 196 redirect_to :action => 'list'
197 197 else
198 198 @contests = user.contests
199 199 @user = user
200 200 end
201 201 end
202 202
203 203 protected
204 204
205 205 def prepare_announcements(recent=nil)
206 - if Configuration.show_tasks_to?(@user)
206 + if GraderConfiguration.show_tasks_to?(@user)
207 207 @announcements = Announcement.find_published(true)
208 208 else
209 209 @announcements = Announcement.find_published
210 210 end
211 211 if recent!=nil
212 212 recent_id = recent.to_i
213 213 @announcements = @announcements.find_all { |a| a.id > recent_id }
214 214 end
215 215 end
216 216
217 217 def prepare_list_information
218 218 @user = User.find(session[:user_id])
219 - if not Configuration.multicontests?
219 + if not GraderConfiguration.multicontests?
220 220 @problems = @user.available_problems
221 221 else
222 222 @contest_problems = @user.available_problems_group_by_contests
223 223 @problems = @user.available_problems
224 224 end
225 225 @prob_submissions = {}
226 226 @problems.each do |p|
227 227 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
228 228 if sub!=nil
229 229 @prob_submissions[p.id] = { :count => sub.number, :submission => sub }
230 230 else
231 231 @prob_submissions[p.id] = { :count => 0, :submission => nil }
232 232 end
233 233 end
234 234 prepare_announcements
235 235 end
236 236
237 237 def check_viewability
238 238 @user = User.find(session[:user_id])
239 - if (!Configuration.show_tasks_to?(@user)) and
239 + if (!GraderConfiguration.show_tasks_to?(@user)) and
240 240 ((action_name=='submission') or (action_name=='submit'))
241 241 redirect_to :action => 'list' and return
242 242 end
243 243 end
244 244
245 245 def prepare_grading_result(submission)
246 - if Configuration.task_grading_info.has_key? submission.problem.name
247 - grading_info = Configuration.task_grading_info[submission.problem.name]
246 + if GraderConfiguration.task_grading_info.has_key? submission.problem.name
247 + grading_info = GraderConfiguration.task_grading_info[submission.problem.name]
248 248 else
249 249 # guess task info from problem.full_score
250 250 cases = submission.problem.full_score / 10
251 251 grading_info = {
252 252 'testruns' => cases,
253 253 'testcases' => cases
254 254 }
255 255 end
256 256 @test_runs = []
257 257 if grading_info['testruns'].is_a? Integer
258 258 trun_count = grading_info['testruns']
259 259 trun_count.times do |i|
260 260 @test_runs << [ read_grading_result(@user.login,
261 261 submission.problem.name,
262 262 submission.id,
263 263 i+1) ]
264 264 end
265 265 else
266 266 grading_info['testruns'].keys.sort.each do |num|
267 267 run = []
268 268 testrun = grading_info['testruns'][num]
269 269 testrun.each do |c|
270 270 run << read_grading_result(@user.login,
271 271 submission.problem.name,
272 272 submission.id,
273 273 c)
274 274 end
275 275 @test_runs << run
276 276 end
277 277 end
278 278 end
279 279
280 280 def grading_result_dir(user_name, problem_name, submission_id, case_num)
281 281 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
282 282 end
283 283
284 284 def output_filename(user_name, problem_name, submission_id, case_num)
285 285 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
286 286 return "#{dir}/output.txt"
287 287 end
288 288
289 289 def read_grading_result(user_name, problem_name, submission_id, case_num)
290 290 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
291 291 result_file_name = "#{dir}/result"
292 292 if !FileTest.exists?(result_file_name)
293 293 return {:num => case_num, :msg => 'program did not run'}
294 294 else
295 295 results = File.open(result_file_name).readlines
@@ -308,73 +308,73
308 308 :msg => results[0],
309 309 :run_stat => run_stat,
310 310 :output => output_file,
311 311 :output_size => output_size
312 312 }
313 313 end
314 314 end
315 315
316 316 # copied from grader/script/lib/test_request_helper.rb
317 317 def extract_running_stat(results)
318 318 running_stat_line = results[-1]
319 319
320 320 # extract exit status line
321 321 run_stat = ""
322 322 if !(/[Cc]orrect/.match(results[0]))
323 323 run_stat = results[0].chomp
324 324 else
325 325 run_stat = 'Program exited normally'
326 326 end
327 327
328 328 logger.info "Stat line: #{running_stat_line}"
329 329
330 330 # extract running time
331 331 if res = /r(.*)u(.*)s/.match(running_stat_line)
332 332 seconds = (res[1].to_f + res[2].to_f)
333 333 time_stat = "Time used: #{seconds} sec."
334 334 else
335 335 seconds = nil
336 336 time_stat = "Time used: n/a sec."
337 337 end
338 338
339 339 # extract memory usage
340 340 if res = /s(.*)m/.match(running_stat_line)
341 341 memory_used = res[1].to_i
342 342 else
343 343 memory_used = -1
344 344 end
345 345
346 346 return {
347 347 :msg => "#{run_stat}\n#{time_stat}",
348 348 :running_time => seconds,
349 349 :exit_status => run_stat,
350 350 :memory_usage => memory_used
351 351 }
352 352 end
353 353
354 354 def confirm_and_update_start_time
355 355 user = User.find(session[:user_id])
356 - if (Configuration.indv_contest_mode? and
357 - Configuration['contest.confirm_indv_contest_start'] and
356 + if (GraderConfiguration.indv_contest_mode? and
357 + GraderConfiguration['contest.confirm_indv_contest_start'] and
358 358 !user.contest_started?)
359 359 redirect_to :action => 'confirm_contest_start' and return
360 360 end
361 - if not Configuration.analysis_mode?
361 + if not GraderConfiguration.analysis_mode?
362 362 user.update_start_time
363 363 end
364 364 end
365 365
366 366 def reject_announcement_refresh_when_logged_out
367 367 if not session[:user_id]
368 368 render :text => 'Access forbidden', :status => 403
369 369 end
370 370
371 - if Configuration.multicontests?
371 + if GraderConfiguration.multicontests?
372 372 user = User.find(session[:user_id])
373 373 if user.contest_stat.forced_logout
374 374 render :text => 'Access forbidden', :status => 403
375 375 end
376 376 end
377 377 end
378 378
379 379 end
380 380
@@ -1,62 +1,62
1 1 class SiteController < ApplicationController
2 2
3 3 before_filter :site_admin_authorization, :except => 'login'
4 4
5 5 def login
6 6 # Site administrator login
7 7 @countries = Country.find(:all, :include => :sites)
8 8 @country_select = @countries.collect { |c| [c.name, c.id] }
9 9
10 10 @country_select_with_all = [['Any',0]]
11 11 @countries.each do |country|
12 12 @country_select_with_all << [country.name, country.id]
13 13 end
14 14
15 15 @site_select = []
16 16 @countries.each do |country|
17 17 country.sites.each do |site|
18 18 @site_select << ["#{site.name}, #{country.name}", site.id]
19 19 end
20 20 end
21 21
22 - @default_site = Site.first if !Configuration['contest.multisites']
22 + @default_site = Site.first if !GraderConfiguration['contest.multisites']
23 23
24 24 render :action => 'login', :layout => 'empty'
25 25 end
26 26
27 27 def index
28 28 if @site.started
29 29 render :action => 'started', :layout => 'empty'
30 30 else
31 31 render :action => 'prompt', :layout => 'empty'
32 32 end
33 33 end
34 34
35 35 def start
36 36 @site.started = true
37 37 @site.start_time = Time.new.gmtime
38 38 @site.save
39 39 redirect_to :action => 'index'
40 40 end
41 41
42 42 def logout
43 43 reset_session
44 44 redirect_to :controller => 'main', :action => 'login'
45 45 end
46 46
47 47 protected
48 48 def site_admin_authorization
49 49 if session[:site_id]==nil
50 50 redirect_to :controller => 'site', :action => 'login' and return
51 51 end
52 52 begin
53 53 @site = Site.find(session[:site_id], :include => :country)
54 54 rescue ActiveRecord::RecordNotFound
55 55 @site = nil
56 56 end
57 57 if @site==nil
58 58 redirect_to :controller => 'site', :action => 'login' and return
59 59 end
60 60 end
61 61
62 62 end
@@ -21,55 +21,55
21 21 end
22 22
23 23 send_file_to_user(filename, base_filename)
24 24 end
25 25
26 26 # this has problem-level access control
27 27 def download
28 28 problem = Problem.find(params[:id])
29 29 if !problem or !problem.available or !@user.can_view_problem? problem
30 30 redirect_to :action => 'index' and return
31 31 end
32 32
33 33 base_name = params[:file]
34 34 base_filename = File.basename("#{base_name}.#{params[:ext]}")
35 35 filename = "#{Problem.download_file_basedir}/#{params[:id]}/#{base_filename}"
36 36 puts "SENDING: #{filename}"
37 37
38 38 if !FileTest.exists?(filename)
39 39 redirect_to :action => 'index' and return
40 40 end
41 41
42 42 puts "SENDING: #{filename}"
43 43
44 44 send_file_to_user(filename, base_filename)
45 45 end
46 46
47 47 protected
48 48
49 49 def send_file_to_user(filename, base_filename)
50 50 if defined?(USE_APACHE_XSENDFILE) and USE_APACHE_XSENDFILE
51 51 response.headers['Content-Type'] = "application/force-download"
52 52 response.headers['Content-Disposition'] = "attachment; filename=\"#{File.basename(filename)}\""
53 53 response.headers["X-Sendfile"] = filename
54 54 response.headers['Content-length'] = File.size(filename)
55 55 render :nothing => true
56 56 else
57 57 if params[:ext]=='pdf'
58 58 content_type = 'application/pdf'
59 59 else
60 60 content_type = 'application/octet-stream'
61 61 end
62 62
63 63 send_file filename, :stream => false, :filename => base_filename, :type => content_type
64 64 end
65 65 end
66 66
67 67 def check_viewability
68 68 @user = User.find(session[:user_id])
69 - if @user==nil or !Configuration.show_tasks_to?(@user)
69 + if @user==nil or !GraderConfiguration.show_tasks_to?(@user)
70 70 redirect_to :controller => 'main', :action => 'list'
71 71 return false
72 72 end
73 73 end
74 74
75 75 end
@@ -1,118 +1,118
1 1 class TestController < ApplicationController
2 2
3 3 before_filter :authenticate, :check_viewability
4 4
5 5 #
6 6 # COMMENT OUT: filter in each action instead
7 7 #
8 8 # before_filter :verify_time_limit, :only => [:submit]
9 9
10 10 verify :method => :post, :only => [:submit],
11 11 :redirect_to => { :action => :index }
12 12
13 13 def index
14 14 prepare_index_information
15 15 end
16 16
17 17 def submit
18 18 @user = User.find(session[:user_id])
19 19
20 20 @submitted_test_request = TestRequest.new_from_form_params(@user,params[:test_request])
21 21
22 22 if @submitted_test_request.errors.length != 0
23 23 prepare_index_information
24 24 render :action => 'index' and return
25 25 end
26 26
27 - if Configuration.time_limit_mode?
27 + if GraderConfiguration.time_limit_mode?
28 28 if @user.contest_finished?
29 29 @submitted_test_request.errors.add_to_base('Contest is over.')
30 30 prepare_index_information
31 31 render :action => 'index' and return
32 32 end
33 33
34 - if !Configuration.allow_test_request(@user)
34 + if !GraderConfiguration.allow_test_request(@user)
35 35 prepare_index_information
36 36 flash[:notice] = 'Test request is not allowed during the last 30 minutes'
37 37 redirect_to :action => 'index' and return
38 38 end
39 39 end
40 40
41 41 if @submitted_test_request.save
42 42 redirect_to :action => 'index'
43 43 else
44 44 prepare_index_information
45 45 render :action => 'index'
46 46 end
47 47 end
48 48
49 49 def read
50 50 user = User.find(session[:user_id])
51 51 begin
52 52 test_request = TestRequest.find(params[:id])
53 53 rescue
54 54 test_request = nil
55 55 end
56 56 if test_request==nil or test_request.user_id != user.id
57 57 flash[:notice] = 'Invalid output'
58 58 redirect_to :action => 'index'
59 59 return
60 60 end
61 61 if test_request.output_file_name!=nil
62 62 data = File.open(test_request.output_file_name).read(2048)
63 63 if data==nil
64 64 data=""
65 65 end
66 66 send_data(data,
67 67 {:filename => 'output.txt',
68 68 :type => 'text/plain'})
69 69 return
70 70 end
71 71 redirect_to :action => 'index'
72 72 end
73 73
74 74 def result
75 75 @user = User.find(session[:user_id])
76 76 begin
77 77 @test_request = TestRequest.find(params[:id])
78 78 rescue
79 79 @test_request = nil
80 80 end
81 81 if @test_request==nil or @test_request.user_id != @user.id
82 82 flash[:notice] = 'Invalid request'
83 83 redirect_to :action => 'index'
84 84 return
85 85 end
86 86 end
87 87
88 88 protected
89 89
90 90 def prepare_index_information
91 91 @user = User.find(session[:user_id])
92 92 @submissions = Submission.find_last_for_all_available_problems(@user.id)
93 93 all_problems = @submissions.collect { |submission| submission.problem }
94 94 @problems = []
95 95 all_problems.each do |problem|
96 96 if problem.test_allowed
97 97 @problems << problem
98 98 end
99 99 end
100 100 @test_requests = []
101 101 @user.test_requests.each do |ts|
102 102 if ts.problem and ts.problem.available
103 103 @test_requests << ts
104 104 end
105 105 end
106 106 end
107 107
108 108 def check_viewability
109 109 user = User.find(session[:user_id])
110 - if !Configuration.show_tasks_to?(user)
110 + if !GraderConfiguration.show_tasks_to?(user)
111 111 redirect_to :controller => 'main', :action => 'list'
112 112 end
113 - if (!Configuration.show_submitbox_to?(user)) and (action_name=='submit')
113 + if (!GraderConfiguration.show_submitbox_to?(user)) and (action_name=='submit')
114 114 redirect_to :controller => 'test', :action => 'index'
115 115 end
116 116 end
117 117
118 118 end
@@ -1,68 +1,68
1 1 class UserAdminController < ApplicationController
2 2
3 - include MailHelperMethods
3 + #include MailHelperMethods
4 4
5 5 before_filter :admin_authorization
6 6
7 - def index
8 - list
9 - render :action => 'list'
10 - end
11 -
12 7 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
13 8 verify :method => :post, :only => [ :destroy,
14 9 :create, :create_from_list,
15 10 :update,
16 11 :manage_contest,
17 12 :bulk_mail
18 13 ],
19 14 :redirect_to => { :action => :list }
20 15
16 + def index
17 + list
18 + render :action => 'list'
19 + end
20 +
21 21 def list
22 22 @user_count = User.count
23 23 if params[:page] == 'all'
24 24 @users = User.all
25 25 @paginated = false
26 26 else
27 27 @users = User.paginate :page => params[:page]
28 28 @paginated = true
29 29 end
30 30 @hidden_columns = ['hashed_password', 'salt', 'created_at', 'updated_at']
31 31 @contests = Contest.enabled
32 32 end
33 33
34 34 def active
35 35 sessions = ActiveRecord::SessionStore::Session.find(:all, :conditions => ["updated_at >= ?", 60.minutes.ago])
36 36 @users = []
37 37 sessions.each do |session|
38 38 if session.data[:user_id]
39 39 @users << User.find(session.data[:user_id])
40 40 end
41 41 end
42 42 end
43 43
44 44 def show
45 45 @user = User.find(params[:id])
46 46 end
47 47
48 48 def new
49 49 @user = User.new
50 50 end
51 51
52 52 def create
53 53 @user = User.new(params[:user])
54 54 @user.activated = true
55 55 if @user.save
56 56 flash[:notice] = 'User was successfully created.'
57 57 redirect_to :action => 'list'
58 58 else
59 59 render :action => 'new'
60 60 end
61 61 end
62 62
63 63 def create_from_list
64 64 lines = params[:user_list]
65 65
66 66 note = []
67 67
68 68 lines.split("\n").each do |line|
@@ -379,77 +379,77
379 379 site_data.each_pair do |id,site|
380 380 s = Site.find_by_name(site[:name])
381 381 if s!=nil
382 382 @import_log << "Found #{site[:name]}\n"
383 383 else
384 384 s = Site.new(:name => site[:name])
385 385 @import_log << "Created #{site[:name]}\n"
386 386 end
387 387 s.password = site[:password]
388 388 s.country = countries[site[:country_id]]
389 389 s.save
390 390 sites[id] = s
391 391 end
392 392
393 393 # import users
394 394 user_data.each_pair do |id,user|
395 395 u = User.find_by_login(user[:login])
396 396 if u!=nil
397 397 @import_log << "Found #{user[:login]}\n"
398 398 else
399 399 u = User.new(:login => user[:login])
400 400 @import_log << "Created #{user[:login]}\n"
401 401 end
402 402 u.full_name = user[:name]
403 403 u.password = user[:password]
404 404 u.country = countries[user[:country_id]]
405 405 u.site = sites[user[:site_id]]
406 406 u.activated = true
407 407 u.email = "empty-#{u.login}@none.com"
408 408 if not u.save
409 409 @import_log << "Errors\n"
410 410 u.errors.each { |attr,msg| @import_log << "#{attr} - #{msg}\n" }
411 411 end
412 412 end
413 413
414 414 end
415 415
416 416 def logout_users(users)
417 417 users.each do |user|
418 418 contest_stat = user.contest_stat(true)
419 419 if contest_stat and !contest_stat.forced_logout
420 420 contest_stat.forced_logout = true
421 421 contest_stat.save
422 422 end
423 423 end
424 424 end
425 425
426 426 def send_contest_update_notification_email(user, contest)
427 - contest_title_name = Configuration['contest.name']
427 + contest_title_name = GraderConfiguration['contest.name']
428 428 contest_name = contest.name
429 429 subject = t('contest.notification.email_subject', {
430 430 :contest_title_name => contest_title_name,
431 431 :contest_name => contest_name })
432 432 body = t('contest.notification.email_body', {
433 433 :full_name => user.full_name,
434 434 :contest_title_name => contest_title_name,
435 435 :contest_name => contest.name,
436 436 })
437 437
438 438 logger.info body
439 439 send_mail(user.email, subject, body)
440 440 end
441 441
442 442 def find_contest_and_user_from_contest_id(id)
443 443 if id!='none'
444 444 @contest = Contest.find(id)
445 445 else
446 446 @contest = nil
447 447 end
448 448 if @contest
449 449 @users = @contest.users
450 450 else
451 451 @users = User.find_users_with_no_contest
452 452 end
453 453 return [@contest, @users]
454 454 end
455 455 end
@@ -1,158 +1,158
1 1 require 'tmail'
2 2 require 'net/smtp'
3 3
4 4 class UsersController < ApplicationController
5 5
6 - include MailHelperMethods
6 + #include MailHelperMethods
7 7
8 8 before_filter :authenticate, :except => [:new,
9 9 :register,
10 10 :confirm,
11 11 :forget,
12 12 :retrieve_password]
13 13
14 14 before_filter :verify_online_registration, :only => [:new,
15 15 :register,
16 16 :forget,
17 17 :retrieve_password]
18 18
19 19 verify :method => :post, :only => [:chg_passwd],
20 20 :redirect_to => { :action => :index }
21 21
22 22 #in_place_edit_for :user, :alias_for_editing
23 23 #in_place_edit_for :user, :email_for_editing
24 24
25 25 def index
26 - if !Configuration['system.user_setting_enabled']
26 + if !GraderConfiguration['system.user_setting_enabled']
27 27 redirect_to :controller => 'main', :action => 'list'
28 28 else
29 29 @user = User.find(session[:user_id])
30 30 end
31 31 end
32 32
33 33 def chg_passwd
34 34 user = User.find(session[:user_id])
35 35 user.password = params[:passwd]
36 36 user.password_confirmation = params[:passwd_verify]
37 37 if user.save
38 38 flash[:notice] = 'password changed'
39 39 else
40 40 flash[:notice] = 'Error: password changing failed'
41 41 end
42 42 redirect_to :action => 'index'
43 43 end
44 44
45 45 def new
46 46 @user = User.new
47 47 render :action => 'new', :layout => 'empty'
48 48 end
49 49
50 50 def register
51 51 if(params[:cancel])
52 52 redirect_to :controller => 'main', :action => 'login'
53 53 return
54 54 end
55 55 @user = User.new(params[:user])
56 56 @user.password_confirmation = @user.password = User.random_password
57 57 @user.activated = false
58 58 if (@user.valid?) and (@user.save)
59 59 if send_confirmation_email(@user)
60 60 render :action => 'new_splash', :layout => 'empty'
61 61 else
62 - @admin_email = Configuration['system.admin_email']
62 + @admin_email = GraderConfiguration['system.admin_email']
63 63 render :action => 'email_error', :layout => 'empty'
64 64 end
65 65 else
66 66 @user.errors.add_to_base("Email cannot be blank") if @user.email==''
67 67 render :action => 'new', :layout => 'empty'
68 68 end
69 69 end
70 70
71 71 def confirm
72 72 login = params[:login]
73 73 key = params[:activation]
74 74 @user = User.find_by_login(login)
75 75 if (@user) and (@user.verify_activation_key(key))
76 76 if @user.valid? # check uniquenss of email
77 77 @user.activated = true
78 78 @user.save
79 79 @result = :successful
80 80 else
81 81 @result = :email_used
82 82 end
83 83 else
84 84 @result = :failed
85 85 end
86 86 render :action => 'confirm', :layout => 'empty'
87 87 end
88 88
89 89 def forget
90 90 render :action => 'forget', :layout => 'empty'
91 91 end
92 92
93 93 def retrieve_password
94 94 email = params[:email]
95 95 user = User.find_by_email(email)
96 96 if user
97 97 last_updated_time = user.updated_at || user.created_at || (Time.now.gmtime - 1.hour)
98 98 if last_updated_time > Time.now.gmtime - 5.minutes
99 99 flash[:notice] = 'The account has recently created or new password has recently been requested. Please wait for 5 minutes'
100 100 else
101 101 user.password = user.password_confirmation = User.random_password
102 102 user.save
103 103 send_new_password_email(user)
104 104 flash[:notice] = 'New password has been mailed to you.'
105 105 end
106 106 else
107 107 flash[:notice] = I18n.t 'registration.password_retrieval.no_email'
108 108 end
109 109 redirect_to :action => 'forget'
110 110 end
111 111
112 112 protected
113 113
114 114 def verify_online_registration
115 - if !Configuration['system.online_registration']
115 + if !GraderConfiguration['system.online_registration']
116 116 redirect_to :controller => 'main', :action => 'login'
117 117 end
118 118 end
119 119
120 120 def send_confirmation_email(user)
121 - contest_name = Configuration['contest.name']
122 - admin_email = Configuration['system.admin_email']
121 + contest_name = GraderConfiguration['contest.name']
122 + admin_email = GraderConfiguration['system.admin_email']
123 123 activation_url = url_for(:action => 'confirm',
124 124 :login => user.login,
125 125 :activation => user.activation_key)
126 126 home_url = url_for(:controller => 'main', :action => 'index')
127 127 subject = "[#{contest_name}] Confirmation"
128 128 body = t('registration.email_body', {
129 129 :full_name => user.full_name,
130 130 :contest_name => contest_name,
131 131 :login => user.login,
132 132 :password => user.password,
133 133 :activation_url => activation_url,
134 134 :admin_email => admin_email
135 135 })
136 136
137 137 logger.info body
138 138
139 139 send_mail(user.email, subject, body)
140 140 end
141 141
142 142 def send_new_password_email(user)
143 - contest_name = Configuration['contest.name']
144 - admin_email = Configuration['system.admin_email']
143 + contest_name = GraderConfiguration['contest.name']
144 + admin_email = GraderConfiguration['system.admin_email']
145 145 subject = "[#{contest_name}] Password recovery"
146 146 body = t('registration.password_retrieval.email_body', {
147 147 :full_name => user.full_name,
148 148 :contest_name => contest_name,
149 149 :login => user.login,
150 150 :password => user.password,
151 151 :admin_email => admin_email
152 152 })
153 153
154 154 logger.info body
155 155 send_mail(user.email, subject, body)
156 156 end
157 157
158 158 end
@@ -1,127 +1,128
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 (session[:admin])
9 9 # admin menu
10 10 menu_items << "<b>Administrative task:</b> "
11 11 append_to menu_items, '[Announcements]', 'announcements', 'index'
12 12 append_to menu_items, '[Msg console]', 'messages', 'console'
13 13 append_to menu_items, '[Problems]', 'problems', 'index'
14 14 append_to menu_items, '[Users]', 'user_admin', 'index'
15 15 append_to menu_items, '[Results]', 'user_admin', 'user_stat'
16 16 append_to menu_items, '[Graders]', 'graders', 'list'
17 17 append_to menu_items, '[Contests]', 'contest_management', 'index'
18 18 append_to menu_items, '[Sites]', 'sites', 'index'
19 19 append_to menu_items, '[System config]', 'configurations', 'index'
20 20 menu_items << "<br/>"
21 21 end
22 22
23 23 # main page
24 24 append_to menu_items, "[#{I18n.t 'menu.main'}]", 'main', 'list'
25 25 append_to menu_items, "[#{I18n.t 'menu.messages'}]", 'messages', 'list'
26 26
27 - if (user!=nil) and (Configuration.show_tasks_to?(user))
27 + if (user!=nil) and (GraderConfiguration.show_tasks_to?(user))
28 28 append_to menu_items, "[#{I18n.t 'menu.tasks'}]", 'tasks', 'list'
29 29 append_to menu_items, "[#{I18n.t 'menu.submissions'}]", 'main', 'submission'
30 30 append_to menu_items, "[#{I18n.t 'menu.test'}]", 'test', 'index'
31 31 end
32 32 append_to menu_items, "[#{I18n.t 'menu.help'}]", 'main', 'help'
33 33
34 - if Configuration['system.user_setting_enabled']
34 + if GraderConfiguration['system.user_setting_enabled']
35 35 append_to menu_items, "[#{I18n.t 'menu.settings'}]", 'users', 'index'
36 36 end
37 37 append_to menu_items, "[#{I18n.t 'menu.log_out'}]", 'main', 'login'
38 38
39 - menu_items
39 + menu_items.html_safe
40 40 end
41 41
42 42 def append_to(option,label, controller, action)
43 43 option << ' ' if option!=''
44 44 option << link_to_unless_current(label,
45 45 :controller => controller,
46 46 :action => action)
47 47 end
48 48
49 49 def format_short_time(time)
50 50 now = Time.now.gmtime
51 51 st = ''
52 52 if (time.yday != now.yday) or
53 53 (time.year != now.year)
54 54 st = time.strftime("%x ")
55 55 end
56 56 st + time.strftime("%X")
57 57 end
58 58
59 59 def format_short_duration(duration)
60 60 return '' if duration==nil
61 61 d = duration.to_f
62 62 return Time.at(d).gmtime.strftime("%X")
63 63 end
64 64
65 65 def read_textfile(fname,max_size=2048)
66 66 begin
67 67 File.open(fname).read(max_size)
68 68 rescue
69 69 nil
70 70 end
71 71 end
72 72
73 73 def user_title_bar(user)
74 74 header = ''
75 75 time_left = ''
76 76
77 77 #
78 78 # if the contest is over
79 - if Configuration.time_limit_mode?
79 + if GraderConfiguration.time_limit_mode?
80 80 if user.contest_finished?
81 81 header = <<CONTEST_OVER
82 82 <tr><td colspan="2" align="center">
83 83 <span class="contest-over-msg">THE CONTEST IS OVER</span>
84 84 </td></tr>
85 85 CONTEST_OVER
86 86 end
87 87 if !user.contest_started?
88 88 time_left = "&nbsp;&nbsp;" + (t 'title_bar.contest_not_started')
89 89 else
90 90 time_left = "&nbsp;&nbsp;" + (t 'title_bar.remaining_time') +
91 91 " #{format_short_duration(user.contest_time_left)}"
92 92 end
93 93 end
94 94
95 95 #
96 96 # if the contest is in the anaysis mode
97 - if Configuration.analysis_mode?
97 + if GraderConfiguration.analysis_mode?
98 98 header = <<ANALYSISMODE
99 99 <tr><td colspan="2" align="center">
100 100 <span class="contest-over-msg">ANALYSIS MODE</span>
101 101 </td></tr>
102 102 ANALYSISMODE
103 103 end
104 104
105 - contest_name = Configuration['contest.name']
105 + contest_name = GraderConfiguration['contest.name']
106 106
107 107 #
108 108 # build real title bar
109 - <<TITLEBAR
109 + result = <<TITLEBAR
110 110 <div class="title">
111 111 <table>
112 112 #{header}
113 113 <tr>
114 114 <td class="left-col">
115 115 #{user.full_name}<br/>
116 116 #{t 'title_bar.current_time'} #{format_short_time(Time.new)}
117 117 #{time_left}
118 118 <br/>
119 119 </td>
120 120 <td class="right-col">#{contest_name}</td>
121 121 </tr>
122 122 </table>
123 123 </div>
124 124 TITLEBAR
125 + result.html_safe
125 126 end
126 127
127 128 end
@@ -1,46 +1,46
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 12 def time_left
13 - contest_time = Configuration.contest_time_limit
13 + contest_time = GraderConfiguration.contest_time_limit
14 14
15 15 return nil if contest_time == nil
16 16
17 17 return contest_time if !self.started
18 18
19 19 current_time = Time.now.gmtime
20 20 if self.start_time!=nil
21 21 finish_time = self.start_time + contest_time
22 22 else
23 23 finish_time = current_time + contest_time
24 24 end
25 25
26 26 if current_time > finish_time
27 27 return current_time - current_time
28 28 else
29 29 return finish_time - current_time
30 30 end
31 31 end
32 32
33 33 def finished?
34 34 if !self.started
35 35 return false
36 36 end
37 37
38 - contest_time = Configuration.contest_time_limit
38 + contest_time = GraderConfiguration.contest_time_limit
39 39 if contest_time!=nil
40 40 return Time.now.gmtime > (self.start_time + contest_time)
41 41 else
42 42 false
43 43 end
44 44 end
45 45
46 46 end
@@ -91,233 +91,233
91 91 end
92 92
93 93 def alias_for_editing
94 94 if self.alias==nil
95 95 "(unknown)"
96 96 elsif self.alias==''
97 97 "(blank)"
98 98 else
99 99 self.alias
100 100 end
101 101 end
102 102
103 103 def alias_for_editing=(e)
104 104 self.alias=e
105 105 end
106 106
107 107 def activation_key
108 108 if self.hashed_password==nil
109 109 encrypt_new_password
110 110 end
111 111 Digest::SHA1.hexdigest(self.hashed_password)[0..7]
112 112 end
113 113
114 114 def verify_activation_key(key)
115 115 key == activation_key
116 116 end
117 117
118 118 def self.random_password(length=5)
119 119 chars = 'abcdefghjkmnopqrstuvwxyz'
120 120 password = ''
121 121 length.times { password << chars[rand(chars.length - 1)] }
122 122 password
123 123 end
124 124
125 125 def self.find_non_admin_with_prefix(prefix='')
126 126 users = User.find(:all)
127 127 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
128 128 end
129 129
130 130 # Contest information
131 131
132 132 def self.find_users_with_no_contest()
133 133 users = User.find(:all)
134 134 return users.find_all { |u| u.contests.length == 0 }
135 135 end
136 136
137 137
138 138 def contest_time_left
139 - if Configuration.contest_mode?
139 + if GraderConfiguration.contest_mode?
140 140 return nil if site==nil
141 141 return site.time_left
142 - elsif Configuration.indv_contest_mode?
143 - time_limit = Configuration.contest_time_limit
142 + elsif GraderConfiguration.indv_contest_mode?
143 + time_limit = GraderConfiguration.contest_time_limit
144 144 if time_limit == nil
145 145 return nil
146 146 end
147 147 if contest_stat==nil or contest_stat.started_at==nil
148 148 return (Time.now.gmtime + time_limit) - Time.now.gmtime
149 149 else
150 150 finish_time = contest_stat.started_at + time_limit
151 151 current_time = Time.now.gmtime
152 152 if current_time > finish_time
153 153 return 0
154 154 else
155 155 return finish_time - current_time
156 156 end
157 157 end
158 158 else
159 159 return nil
160 160 end
161 161 end
162 162
163 163 def contest_finished?
164 - if Configuration.contest_mode?
164 + if GraderConfiguration.contest_mode?
165 165 return false if site==nil
166 166 return site.finished?
167 - elsif Configuration.indv_contest_mode?
167 + elsif GraderConfiguration.indv_contest_mode?
168 168 return false if self.contest_stat(true)==nil
169 169 return contest_time_left == 0
170 170 else
171 171 return false
172 172 end
173 173 end
174 174
175 175 def contest_started?
176 - if Configuration.indv_contest_mode?
176 + if GraderConfiguration.indv_contest_mode?
177 177 stat = self.contest_stat
178 178 return ((stat != nil) and (stat.started_at != nil))
179 - elsif Configuration.contest_mode?
179 + elsif GraderConfiguration.contest_mode?
180 180 return true if site==nil
181 181 return site.started
182 182 else
183 183 return true
184 184 end
185 185 end
186 186
187 187 def update_start_time
188 188 stat = self.contest_stat
189 189 if stat == nil or stat.started_at == nil
190 190 stat ||= UserContestStat.new(:user => self)
191 191 stat.started_at = Time.now.gmtime
192 192 stat.save
193 193 end
194 194 end
195 195
196 196 def problem_in_user_contests?(problem)
197 197 problem_contests = problem.contests.all
198 198
199 199 if problem_contests.length == 0 # this is public contest
200 200 return true
201 201 end
202 202
203 203 contests.each do |contest|
204 204 if problem_contests.find {|c| c.id == contest.id }
205 205 return true
206 206 end
207 207 end
208 208 return false
209 209 end
210 210
211 211 def available_problems_group_by_contests
212 212 contest_problems = []
213 213 pin = {}
214 214 contests.enabled.each do |contest|
215 215 available_problems = contest.problems.available
216 216 contest_problems << {
217 217 :contest => contest,
218 218 :problems => available_problems
219 219 }
220 220 available_problems.each {|p| pin[p.id] = true}
221 221 end
222 222 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
223 223 contest_problems << {
224 224 :contest => nil,
225 225 :problems => other_avaiable_problems
226 226 }
227 227 return contest_problems
228 228 end
229 229
230 230 def available_problems
231 - if not Configuration.multicontests?
231 + if not GraderConfiguration.multicontests?
232 232 return Problem.find_available_problems
233 233 else
234 234 contest_problems = []
235 235 pin = {}
236 236 contests.enabled.each do |contest|
237 237 contest.problems.available.each do |problem|
238 238 if not pin.has_key? problem.id
239 239 contest_problems << problem
240 240 end
241 241 pin[problem.id] = true
242 242 end
243 243 end
244 244 other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
245 245 return contest_problems + other_avaiable_problems
246 246 end
247 247 end
248 248
249 249 def can_view_problem?(problem)
250 - if not Configuration.multicontests?
250 + if not GraderConfiguration.multicontests?
251 251 return problem.available
252 252 else
253 253 return problem_in_user_contests? problem
254 254 end
255 255 end
256 256
257 257 protected
258 258 def encrypt_new_password
259 259 return if password.blank?
260 260 self.salt = (10+rand(90)).to_s
261 261 self.hashed_password = User.encrypt(self.password,self.salt)
262 262 end
263 263
264 264 def assign_default_site
265 265 # have to catch error when migrating (because self.site is not available).
266 266 begin
267 267 if self.site==nil
268 268 self.site = Site.find_by_name('default')
269 269 if self.site==nil
270 270 self.site = Site.find(1) # when 'default has be renamed'
271 271 end
272 272 end
273 273 rescue
274 274 end
275 275 end
276 276
277 277 def assign_default_contest
278 278 # have to catch error when migrating (because self.site is not available).
279 279 begin
280 280 if self.contests.length == 0
281 - default_contest = Contest.find_by_name(Configuration['contest.default_contest_name'])
281 + default_contest = Contest.find_by_name(GraderConfiguration['contest.default_contest_name'])
282 282 if default_contest
283 283 self.contests = [default_contest]
284 284 end
285 285 end
286 286 rescue
287 287 end
288 288 end
289 289
290 290 def password_required?
291 291 self.hashed_password.blank? || !self.password.blank?
292 292 end
293 293
294 294 def self.encrypt(string,salt)
295 295 Digest::SHA1.hexdigest(salt + string)
296 296 end
297 297
298 298 def uniqueness_of_email_from_activated_users
299 299 user = User.activated_users.find_by_email(self.email)
300 300 if user and (user.login != self.login)
301 301 self.errors.add_to_base("Email has already been taken")
302 302 end
303 303 end
304 304
305 305 def enough_time_interval_between_same_email_registrations
306 306 return if !self.new_record?
307 307 return if self.activated
308 308 open_user = User.find_by_email(self.email,
309 309 :order => 'created_at DESC')
310 310 if open_user and open_user.created_at and
311 311 (open_user.created_at > Time.now.gmtime - 5.minutes)
312 312 self.errors.add_to_base("There are already unactivated registrations with this e-mail address (please wait for 5 minutes)")
313 313 end
314 314 end
315 315
316 316 def email_validation?
317 317 begin
318 318 return VALIDATE_USER_EMAILS
319 319 rescue
320 320 return false
321 321 end
322 322 end
323 323 end
@@ -1,32 +1,32
1 1 - content_for :head do
2 2 = javascript_include_tag :defaults
3 3
4 4 %h1 System configuration
5 5
6 6 %table.info
7 7 %tr.info-head
8 8 %th Key
9 9 %th Type
10 10 %th Value
11 11 %th Description
12 12 - @configurations.each do |conf|
13 13 - @configuration = conf
14 14 %tr{:class => cycle("info-odd", "info-even")}
15 15 %td
16 16 = in_place_editor_field :configuration, :key, {}, :rows=>1
17 17 %td
18 18 = in_place_editor_field :configuration, :value_type, {}, :rows=>1
19 19 %td
20 20 = in_place_editor_field :configuration, :value, {}, :rows=>1
21 21 %td= conf.description
22 22
23 - - if Configuration.config_cached?
23 + - if GraderConfiguration.config_cached?
24 24 %br/
25 25 Your config is saved, but it does not automatically take effect.
26 26 %br/
27 27 If you have one mongrel process running, you can
28 28 = link_to '[click]', :action => 'reload'
29 29 here to reload.
30 30 %br/
31 31 If you have more than one process running, you should restart
32 32 them manually.
@@ -1,31 +1,31
1 1 %h1 Contest management
2 2
3 3 .infobox
4 4
5 5 - if @num_contests>1
6 6 %b Multiple contests:
7 7 = "There are #{@num_contests} contests running."
8 8 - else
9 9 %b Single contest:
10 10 = "[#{link_to 'Add/remove contests', :controller => 'contests', :action => 'index'}]"
11 11
12 12 .infobox
13 13 %b Web interface mode:
14 - - if (not Configuration.contest_mode?) and (not Configuration.indv_contest_mode?)
14 + - if (not GraderConfiguration.contest_mode?) and (not GraderConfiguration.indv_contest_mode?)
15 15 standard mode
16 - - elsif Configuration.contest_mode?
16 + - elsif GraderConfiguration.contest_mode?
17 17 normal contest mode.
18 18 - else
19 19 individual contest mode.
20 20
21 21 %br/
22 22 Change mode to:
23 23 = "[#{link_to 'standard', :action => 'change_contest_mode', :id => 'standard'}]"
24 24 = "[#{link_to 'contest', :action => 'change_contest_mode', :id => 'contest'}]"
25 25 = "[#{link_to 'individual contest', :action => 'change_contest_mode', :id => 'indv-contest'}]"
26 26
27 - - if Configuration.indv_contest_mode?
27 + - if GraderConfiguration.indv_contest_mode?
28 28 = render :partial => 'indv_contest_mode_index'
29 29
30 30 %br/
31 31
@@ -1,14 +1,21
1 1 <!DOCTYPE html>
2 2 <html>
3 3 <head>
4 - <title>CafeGraderWeb</title>
4 + <title><%= GraderConfiguration['contest.name'] %></title>
5 5 <%= stylesheet_link_tag "application", :media => "all" %>
6 6 <%= javascript_include_tag "application" %>
7 7 <%= csrf_meta_tags %>
8 + <%= yield :head %>
8 9 </head>
9 10 <body>
10 11
12 + <div class="userbar">
13 + <%= user_header %>
14 + </div>
15 +
16 + <%= content_tag(:p,flash[:notice],:style => "color:green") if flash[:notice]!=nil %>
17 +
11 18 <%= yield %>
12 19
13 20 </body>
14 21 </html>
@@ -1,15 +1,15
1 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
2 2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3 3
4 4 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5 5 <head>
6 6 <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
7 - <title><%= Configuration['contest.name'] %></title>
7 + <title><%= GraderConfiguration['contest.name'] %></title>
8 8 <%= stylesheet_link_tag 'application' %>
9 9 </head>
10 10 <body>
11 11
12 12 <%= yield %>
13 13
14 14 </body>
15 15 </html>
@@ -1,34 +1,34
1 - %b= Configuration['ui.front.welcome_message']
1 + %b= GraderConfiguration['ui.front.welcome_message']
2 2 %br/
3 3
4 4 - if !@hidelogin
5 5 =t 'login.message'
6 6 %br/
7 7 %br/
8 8
9 9 - if flash[:notice]
10 10 %hr/
11 11 %b= flash[:notice]
12 12 %hr/
13 13
14 14 %div{ :style => "border: solid 1px gray; padding: 4px; background: #eeeeff;"}
15 15 = form_tag :controller => 'login', :action => 'login' do
16 16 %table
17 17 %tr
18 18 %td{:align => "right"}
19 19 ="#{t 'login_label'}:"
20 20 %td= text_field_tag 'login'
21 21 %tr
22 22 %td{:align => "right"}
23 23 ="#{t 'password_label'}:"
24 24 %td= password_field_tag
25 25 = submit_tag t('login.login_submit')
26 26 %br/
27 27
28 - - if Configuration['system.online_registration']
28 + - if GraderConfiguration['system.online_registration']
29 29 =t 'login.participation'
30 30 %b
31 31 = "#{t 'login.please'} "
32 32 = link_to "#{t 'login.register'}", :controller => :users, :action => :new
33 33 %br/
34 34 = link_to "#{t 'login.forget_password'}", :controller => :users, :action => :forget
@@ -1,18 +1,18
1 1
2 2 %tr{:class => ((submission_counter%2==0) ? "info-even" : "info-odd")}
3 3 %td.info{:align => "center"}
4 4 = submission_counter+1
5 5 %td.info= format_short_time(submission.submitted_at)
6 6 %td.info{:align => "center"}
7 7 = link_to('[load]',{:action => 'source', :id => submission.id})
8 8 %td.info
9 9 - if submission.graded_at!=nil
10 10 = "Graded at #{format_short_time(submission.graded_at)}."
11 11 %br/
12 - = "Score: #{(submission.points*100/submission.problem.full_score).to_i} " if Configuration['ui.show_score']
12 + = "Score: #{(submission.points*100/submission.problem.full_score).to_i} " if GraderConfiguration['ui.show_score']
13 13 = " ["
14 14 %tt
15 15 = submission.grader_comment
16 16 = "]"
17 17 %td.info
18 18 = render :partial => 'compiler_message', :locals => {:compiler_message => submission.compiler_message }
@@ -1,26 +1,26
1 1
2 2 - if submission==nil
3 3 = "-"
4 4 - else
5 5 - if submission.graded_at==nil
6 6 =t 'main.submitted_at'
7 7 = format_short_time(submission.submitted_at.localtime)
8 8 - else
9 9 = t 'main.graded_at'
10 10 = "#{format_short_time(submission.graded_at.localtime)}, "
11 - - if Configuration['ui.show_score']
11 + - if GraderConfiguration['ui.show_score']
12 12 = t 'main.score'
13 13 = "#{(submission.points*100/submission.problem.full_score).to_i} "
14 14 = " ["
15 15 %tt
16 16 = submission.grader_comment
17 17 = "]"
18 - - if Configuration.show_grading_result
18 + - if GraderConfiguration.show_grading_result
19 19 = " | "
20 20 = link_to '[detailed result]', :action => 'result', :id => submission.id
21 21 = " | "
22 22 = link_to("[#{t 'main.cmp_msg'}]", {:action => 'compiler_msg', :id => submission.id}, {:popup => true})
23 23 = " | "
24 24 = link_to("[#{t 'main.src_link'}]",{:action => 'source', :id => submission.id})
25 25 = " | "
26 26 = link_to "[#{t 'main.submissions_link'}]", :action => 'submission', :id => problem_name
@@ -1,47 +1,47
1 1 = user_title_bar(@user)
2 2
3 3 .announcementbox
4 4 %span{:class => 'title'}
5 - =t 'help.how_to_submit'
5 + =raw t 'help.how_to_submit'
6 6 .announcement
7 7 %p
8 - =t 'help.must_specify_language'
8 + =raw t 'help.must_specify_language'
9 9
10 10 %p
11 - =t 'help.list_available_language'
11 + =raw t 'help.list_available_language'
12 12
13 13 %table{:border => '1'}
14 14 %tr
15 15 %th{:width => '150px'} C
16 16 %th{:width => '150px'} C++
17 17 %th{:width => '150px'} Pascal
18 18 %tr
19 - %td= "<tt>/*<br/>LANG: C<br/>*/</tt>"
20 - %td= "<tt>/*<br/>LANG: C++<br/>*/</tt>"
21 - %td= "<tt>{<br/>LANG: Pascal<br/>}</tt>"
19 + %td=raw "<tt>/*<br/>LANG: C<br/>*/</tt>"
20 + %td=raw "<tt>/*<br/>LANG: C++<br/>*/</tt>"
21 + %td=raw "<tt>{<br/>LANG: Pascal<br/>}</tt>"
22 22
23 23 %p
24 - =t 'help.accept_only_language_specified'
24 + =raw t 'help.accept_only_language_specified'
25 25
26 26 %p
27 - =t 'help.specifying_task'
27 + =raw t 'help.specifying_task'
28 28
29 29 %p
30 - =t 'help.example_cpp'
30 + =raw t 'help.example_cpp'
31 31
32 32 %table{:border => '1'}
33 33 %tr
34 34 %td{:width => '300px'}
35 35 %tt <tt>/*<br/>LANG: C++<br/>TASK: mobiles<br/>*/</tt>
36 36
37 37 %p
38 - =t 'help.example_pas'
38 + =raw t 'help.example_pas'
39 39
40 40 %table{:border => '1'}
41 41 %tr
42 42 %td{:width => '300px'}
43 43 %tt <tt>{<br/>LANG: Pascal<br/>TASK: mobiles<br/>}</tt>
44 44
45 45 %p
46 - = (t('help.ask_questions_at_messages',:message_link_name => (t 'menu.messages'),:url => url_for(:controller => 'messages', :action => 'list')))
46 + = raw(t('help.ask_questions_at_messages',:message_link_name => (t 'menu.messages'),:url => url_for(:controller => 'messages', :action => 'list')))
47 47
@@ -1,52 +1,52
1 1 - content_for :head do
2 2 = javascript_include_tag :defaults
3 3 = javascript_include_tag 'announcement_refresh.js'
4 4
5 5 = user_title_bar(@user)
6 6
7 7 .announcementbox{:style => (@announcements.length==0 ? "display:none" : "")}
8 8 %span{:class => 'title'}
9 9 Announcements
10 10 #announcementbox-body
11 11 = render :partial => 'announcement', :collection => @announcements
12 12
13 - - if Configuration.show_submitbox_to?(@user)
13 + - if GraderConfiguration.show_submitbox_to?(@user)
14 14 .submitbox
15 15 = error_messages_for 'submission'
16 16 = render :partial => 'submission_box'
17 17
18 18
19 19 %hr/
20 20
21 - - if (Configuration.contest_mode?) and (@user.site!=nil) and (@user.site.started!=true)
21 + - if (GraderConfiguration.contest_mode?) and (@user.site!=nil) and (@user.site.started!=true)
22 22 %p=t 'main.start_soon'
23 23
24 - - if Configuration.show_tasks_to?(@user)
25 - - if not Configuration.multicontests?
24 + - if GraderConfiguration.show_tasks_to?(@user)
25 + - if not GraderConfiguration.multicontests?
26 26 %table.info
27 27 %tr.info-head
28 28 %th
29 29 %th Tasks
30 30 %th # of sub(s)
31 31 %th Results
32 32 = render :partial => 'problem', :collection => @problems
33 33 - else
34 34 - @contest_problems.each do |cp|
35 35 - if cp[:problems].length > 0
36 36 %h2{:class =>'contest-title'}
37 37 = "#{cp[:contest] ? cp[:contest].title : 'Public problems'}"
38 38 %table.info
39 39 %tr.info-head
40 40 %th
41 41 %th Tasks
42 42 %th # of sub(s)
43 43 %th Results
44 44 = render :partial => 'problem', :collection => cp[:problems]
45 45
46 46
47 47 %hr/
48 48
49 49 %script{:type => 'text/javascript'}
50 50 = "Announcement.refreshUrl = '#{url_for :controller => 'main', :action => 'announcements'}';"
51 51 Announcement.registerRefreshEventTimer();
52 52
@@ -1,12 +1,12
1 - %h1= Configuration['ui.front.title']
1 + %h1= GraderConfiguration['ui.front.title']
2 2
3 3 %table
4 4 %tr
5 5 %td
6 6 - if @announcements.length!=0
7 7 .announcementbox{:style => 'margin-top: 0px'}
8 8 %span{:class => 'title'}
9 9 Announcements
10 10 = render :partial => 'announcement', :collection => @announcements
11 11 %td{:style => 'vertical-align: top; width: 40%; padding-left: 20px;'}
12 12 = render :partial => 'login_box'
@@ -1,41 +1,41
1 1 = user_title_bar(@user)
2 2
3 3 %h2
4 4 Grading Result for Task
5 5 = @submission.problem.full_name
6 6
7 7 %p
8 8 = "Submission: #{@submission.number}"
9 9 %br/
10 10 = "Submitted at: #{format_short_time(@submission.submitted_at)}"
11 11 %br/
12 12 = "Graded at #{format_short_time(@submission.graded_at)} "
13 13 %br/
14 - = "score: #{(@submission.points*100/@submission.problem.full_score).to_i} " if Configuration['ui.show_score']
14 + = "score: #{(@submission.points*100/@submission.problem.full_score).to_i} " if GraderConfiguration['ui.show_score']
15 15 = " ["
16 16 %tt
17 17 = @submission.grader_comment
18 18 = "]"
19 19
20 20 %table.info
21 21 %tr.info-head
22 22 %th Runs
23 23 %th Cases
24 24 %th Result
25 25 %th Exit
26 26 %th Time (s)
27 27 %th Memory (KB)
28 28 %th Output
29 29 - r = 0
30 30 - @test_runs.each do |test_run|
31 31 - r += 1
32 32 - case_count = test_run.length
33 33 - first_case = true
34 34 - test_run.each do |test_case|
35 35 %tr{:class => ((r%2==0) ? "info-even" : "info-odd")}
36 36 - if first_case
37 37 %td{:rowspan => case_count}
38 38 = r
39 39 - first_case = false
40 40 = render :partial => 'test_case_result', :locals => {:test_case => test_case}
41 41
@@ -1,44 +1,44
1 1 - content_for :head do
2 2 = stylesheet_link_tag 'problems'
3 3 = javascript_include_tag :defaults
4 4
5 5 %h1 Manage problems
6 6
7 7 %p= link_to '[Back to problem list]', :action => 'list'
8 8
9 9 - form_tag :action=>'do_manage' do
10 10 .submitbox
11 11 What do you want to do?
12 12 %br/
13 13 %ul
14 14 %li
15 15 Change date added to
16 16 = select_date Date.current, :prefix => 'date_added'
17 17 &nbsp;&nbsp;&nbsp;
18 18 = submit_tag 'Change', :name => 'change_date_added'
19 19
20 - - if Configuration.multicontests?
20 + - if GraderConfiguration.multicontests?
21 21 %li
22 22 Add to
23 23 = select("contest","id",Contest.all.collect {|c| [c.title, c.id]})
24 24 = submit_tag 'Add', :name => 'add_to_contest'
25 25
26 26 %table
27 27 %tr
28 28 %th/
29 29 %th Name
30 30 %th Full name
31 31 %th Date added
32 - - if Configuration.multicontests?
32 + - if GraderConfiguration.multicontests?
33 33 %th Contests
34 34
35 35 - for problem in @problems
36 36 %tr{:id => "row-prob-#{problem.id}", :name=> "prob-#{problem.id}"}
37 37 %td= check_box_tag "prob-#{problem.id}"
38 38 %td= problem.name
39 39 %td= problem.full_name
40 40 %td= problem.date_added
41 - - if Configuration.multicontests?
41 + - if GraderConfiguration.multicontests?
42 42 %td
43 43 - problem.contests.each do |contest|
44 44 = "(#{contest.name} [#{link_to 'x', :action => 'remove_contest', :id => problem.id, :contest_id => contest.id }])"
@@ -1,88 +1,88
1 1 <%= user_title_bar(@user) %>
2 2
3 3 <h2><%=t 'test.title' %></h2>
4 4
5 5 <div class="test-desc">
6 6 <%=t 'test.intro' %><br/>
7 - <% if Configuration['contest.test_request.early_timeout'] %>
7 + <% if GraderConfiguration['contest.test_request.early_timeout'] %>
8 8 <%=t 'test.disabled_at_end_announcement' %>
9 9 <% end %>
10 10 </div>
11 11
12 12 <% if @problems.length==0 %>
13 13 There is no submission
14 14 <% else %>
15 15
16 16 <script type="text/javascript">
17 17 var submissionCount = new Array();
18 18 <% @submissions.each do |submission| %>
19 19 submissionCount[<%= submission.problem_id %>]=<%= submission.number %>;
20 20 <% end %>
21 21
22 22 function updateSubmissionList() {
23 23 currentProb = document.getElementById("test_request_problem_id").value;
24 24 count = submissionCount[currentProb];
25 25 submissionSelect = document.getElementById("test_request_submission_number");
26 26 old_len = submissionSelect.length;
27 27 // clear the box
28 28 for(i=0; i<old_len; i++)
29 29 submissionSelect.remove(0);
30 30 for(i=count; i>=1; i--) {
31 31 try {
32 32 submissionSelect.add(new Option(""+i,""+i,false,false),null);
33 33 } catch(ex) {
34 34 submissionSelect.add(new Option(""+i,""+i,false,false));
35 35 }
36 36 }
37 37 }
38 38 </script>
39 39
40 - <% if Configuration.show_submitbox_to?(@user) and Configuration.allow_test_request(@user) %>
40 + <% if GraderConfiguration.show_submitbox_to?(@user) and GraderConfiguration.allow_test_request(@user) %>
41 41 <div class="submitbox">
42 42 <%= error_messages_for 'submitted_test_request' %>
43 43 <% form_for :test_request, nil,
44 44 :url => { :action => 'submit'},
45 45 :html => { :multipart => true } do |f| %>
46 46 <table>
47 47 <tr>
48 48 <td>Task:</td>
49 49 <td>
50 50 <%= select(:test_request,
51 51 :problem_id,
52 52 @problems.collect {|p| [p.name, p.id]}, {},
53 53 { :onclick => "updateSubmissionList();" }) %>
54 54 </td>
55 55 </tr>
56 56 <tr>
57 57 <td>Submission:</td>
58 58 <td>
59 59 <%= select(:test_request,
60 60 :submission_number,
61 61 ((1..@submissions[0].number).collect {|n| [n,n]}).reverse) %>
62 62 </td>
63 63 </tr>
64 64 <tr>
65 65 <td>Input data:</td>
66 66 <td>
67 67 <%= f.file_field :input_file %>
68 68 </td>
69 69 <td>
70 70 (combined size should not exceed 2MB)
71 71 </td>
72 72 </tr>
73 73 <tr>
74 74 <td colspan="2">
75 75 <%= submit_tag 'submit' %>
76 76 </td>
77 77 </tr>
78 78 </table>
79 79 <% end %>
80 80 </div>
81 81 <% end %>
82 82
83 83 <h3>Previous requests</h3>
84 84
85 85 <table class="info">
86 86 <tr class="info-head">
87 87 <th>at</th>
88 88 <th>problem</th>
@@ -1,66 +1,66
1 1 <h1>
2 2 List users in <% if @contest %><%= @contest.title %>
3 3 <% else %>Users not in any contests<% end %>
4 4 </h1>
5 5
6 6 <div class="submitbox">
7 7 <%= link_to '[View all users]', :action => 'list' %>
8 - <% if Configuration.multicontests? %>
8 + <% if GraderConfiguration.multicontests? %>
9 9 <%= link_to '[Manage bulk users in contests]', :action => 'contest_management' %>
10 10 <br/>
11 11 View users in:
12 12 <% @contests.each do |contest| %>
13 13 <%= link_to "[#{contest.name}]", :action => 'contests', :id => contest.id %>
14 14 <% end %>
15 15 <%= link_to "[no contest]", :action => 'contests', :id => 'none' %>
16 16 <% end %>
17 17 <br/>
18 18 <%= form_tag :action => 'assign_from_list' do %>
19 19 <%= hidden_field_tag 'users_contest_id', (@contest ? @contest.id : 'none') %>
20 20 Assign all to
21 21 <%= select("new_contest","id",Contest.all.collect {|c| [c.title, c.id]}) %>
22 22 <%= submit_tag "Assign", :confirm => 'Are you sure?' %>
23 23 <% end %>
24 24 </div>
25 25
26 26 <table class="info">
27 27 <tr class="info-head">
28 28 <th>Login</th>
29 29 <th>Full name</th>
30 30 <th>Email</th>
31 31 <th>Activated?</th>
32 32 <th></th>
33 33 <th></th>
34 34 <th></th>
35 - <% if Configuration.multicontests? %>
35 + <% if GraderConfiguration.multicontests? %>
36 36 <th>Contests</th>
37 37 <th>Other enabled contests</th>
38 38 <% end %>
39 39 </tr>
40 40
41 41 <% for user in @users %>
42 42 <tr class="info-<%= cycle("odd","even") %>">
43 43 <td><%=h user.login %></td>
44 44 <td><%=h user.full_name %></td>
45 45 <td><%=h user.email %></td>
46 46 <td><%=h user.activated %></td>
47 47 <td><%= link_to 'Show', :action => 'show', :id => user %></td>
48 48 <td><%= link_to 'Edit', :action => 'edit', :id => user %></td>
49 49 <td><%= link_to 'Destroy', { :action => 'destroy', :id => user }, :confirm => 'Are you sure?', :method => :post %></td>
50 - <% if Configuration.multicontests? %>
50 + <% if GraderConfiguration.multicontests? %>
51 51 <td>
52 52 <% user.contests.each do |contest| %>
53 53 <%= contest.name %> [<%= link_to 'x', :action => 'remove_from_contest', :id => user.id, :contest_id => contest.id %>]
54 54 <% end %>
55 55 </td>
56 56 <td>
57 57 <% @contests.each do |contest| %>
58 58 <% if not user.contests.all.find {|c| c.id==contest.id } %>
59 59 <%= contest.name %> [<%= link_to '+', :action => 'add_to_contest', :id => user.id, :contest_id => contest.id %>]
60 60 <% end %>
61 61 <% end %>
62 62 </td>
63 63 <% end %>
64 64 </tr>
65 65 <% end %>
66 66 </table>
@@ -1,18 +1,18
1 1 .contest-title
2 2 %h1
3 - = "#{Configuration['contest.name']}: #{t 'registration.password_retrieval.header'}"
3 + = "#{GraderConfiguration['contest.name']}: #{t 'registration.password_retrieval.header'}"
4 4
5 5 - if flash[:notice]
6 6 %hr/
7 7 %b= flash[:notice]
8 8 %hr/
9 9
10 10 %br/
11 11
12 12 - form_tag :action => 'retrieve_password' do
13 13 =t 'registration.password_retrieval.instructions'
14 14 = text_field 'email', nil, :size => 20
15 15 %br/
16 16 = submit_tag(t 'registration.password_retrieval.button_label')
17 17
18 18 = link_to "#{t 'go_back_to'}#{t 'home_page'}", :controller => 'main', :action => 'index'
@@ -1,39 +1,39
1 1 .contest-title
2 2 %h1
3 - = "#{Configuration['contest.name']}: #{t 'registration.title'}"
3 + = "#{GraderConfiguration['contest.name']}: #{t 'registration.title'}"
4 4
5 5 .registration-desc
6 6 =t 'registration.description'
7 7
8 8 = error_messages_for :user, :header_message => (t 'registration.errors.header')
9 9
10 10 %table
11 11 - form_for :user, @user, :url => { :action => 'register' } do |f|
12 12 %tr
13 13 %td{:align => "right"}
14 14 = "#{t 'login_label'}:"
15 15 %td= f.text_field :login
16 16 %tr
17 17 %td
18 18 %td
19 19 %small
20 20 =t 'registration.login_guide'
21 21 %tr
22 22 %td{:align => "right"}
23 23 = "#{t 'full_name_label'}:"
24 24 %td= f.text_field :full_name
25 25 %tr
26 26 %td{:align => "right"}
27 27 = "#{t 'email_label'}:"
28 28 %td= f.text_field :email
29 29 %tr
30 30 %td
31 31 %td
32 32 %small
33 33 =t 'registration.email_guide'
34 34 %tr
35 35 %td/
36 36 %td
37 37 = submit_tag((t 'registration.register'), :name => 'commit')
38 38 = submit_tag((t 'cancel'), :name => 'cancel')
39 39
@@ -9,54 +9,54
9 9 # Bundler.require(:default, :assets, Rails.env)
10 10 end
11 11
12 12 module CafeGrader
13 13 class Application < Rails::Application
14 14 # Settings in config/environments/* take precedence over those specified here.
15 15 # Application configuration should go into files in config/initializers
16 16 # -- all .rb files in that directory are automatically loaded.
17 17
18 18 # Custom directories with classes and modules you want to be autoloadable.
19 19 # config.autoload_paths += %W(#{config.root}/extras)
20 20
21 21 # Only load the plugins named here, in the order given (default is alphabetical).
22 22 # :all can be used as a placeholder for all plugins not explicitly named.
23 23 # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
24 24
25 25 # Activate observers that should always be running.
26 26 # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
27 27
28 28 # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
29 29 # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
30 30 config.time_zone = 'UTC'
31 31
32 32 # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
33 33 # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
34 34 config.i18n.default_locale = :en
35 35
36 36 # Configure the default encoding used in templates for Ruby 1.9.
37 37 config.encoding = "utf-8"
38 38
39 39 # Configure sensitive parameters which will be filtered from the log file.
40 40 config.filter_parameters += [:password]
41 41
42 42 # Enable escaping HTML in JSON.
43 43 config.active_support.escape_html_entities_in_json = true
44 44
45 45 # Use SQL instead of Active Record's schema dumper when creating the database.
46 46 # This is necessary if your schema can't be completely dumped by the schema dumper,
47 47 # like if you have constraints or database-specific column types
48 48 # config.active_record.schema_format = :sql
49 49
50 50 # Enforce whitelist mode for mass assignment.
51 51 # This will create an empty whitelist of attributes available for mass-assignment for all models
52 52 # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
53 53 # parameters by using an attr_accessible or attr_protected declaration.
54 54 config.active_record.whitelist_attributes = true
55 55
56 56 # Enable the asset pipeline
57 - config.assets.enabled = true
57 + config.assets.enabled = false
58 58
59 59 # Version of your assets, change this if you want to expire all your assets
60 60 config.assets.version = '1.0'
61 61 end
62 62 end
@@ -1,233 +1,273
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 Active Record to incrementally modify your database, and
3 - # then regenerate this schema definition.
1 + # encoding: UTF-8
2 + # This file is auto-generated from the current state of the database. Instead
3 + # of editing this file, please use the migrations feature of Active Record to
4 + # incrementally modify your database, and then regenerate this schema definition.
4 5 #
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
7 - # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
6 + # Note that this schema.rb definition is the authoritative source for your
7 + # database schema. If you need to create the application database on another
8 + # system, you should be using db:schema:load, not running all the migrations
9 + # from scratch. The latter is a flawed and unsustainable approach (the more migrations
8 10 # you'll amass, the slower it'll run and the greater likelihood for issues).
9 11 #
10 12 # It's strongly recommended to check this file into your version control system.
11 13
12 - ActiveRecord::Schema.define(:version => 20100506163112) do
14 + ActiveRecord::Schema.define(:version => 20121001033508) do
13 15
14 16 create_table "announcements", :force => true do |t|
15 17 t.string "author"
16 18 t.text "body"
17 19 t.boolean "published"
18 20 t.datetime "created_at"
19 21 t.datetime "updated_at"
20 22 t.boolean "frontpage", :default => false
21 23 t.boolean "contest_only", :default => false
22 24 t.string "title"
23 25 t.string "notes"
24 26 end
25 27
26 - create_table "configurations", :force => true do |t|
27 - t.string "key"
28 - t.string "value_type"
29 - t.string "value"
28 + create_table "codejom_statuses", :force => true do |t|
29 + t.integer "user_id"
30 + t.boolean "alive"
31 + t.integer "num_problems_passed"
30 32 t.datetime "created_at"
31 33 t.datetime "updated_at"
32 - t.text "description"
33 34 end
34 35
35 36 create_table "contests", :force => true do |t|
36 37 t.string "title"
37 38 t.boolean "enabled"
38 39 t.datetime "created_at"
39 40 t.datetime "updated_at"
40 41 t.string "name"
41 42 end
42 43
43 44 create_table "contests_problems", :id => false, :force => true do |t|
44 45 t.integer "contest_id"
45 46 t.integer "problem_id"
46 47 end
47 48
48 49 create_table "contests_users", :id => false, :force => true do |t|
49 50 t.integer "contest_id"
50 51 t.integer "user_id"
51 52 end
52 53
53 54 create_table "countries", :force => true do |t|
54 55 t.string "name"
55 56 t.datetime "created_at"
56 57 t.datetime "updated_at"
57 58 end
58 59
59 60 create_table "descriptions", :force => true do |t|
60 61 t.text "body"
61 62 t.boolean "markdowned"
62 63 t.datetime "created_at"
63 64 t.datetime "updated_at"
64 65 end
65 66
67 + create_table "grader_configurations", :force => true do |t|
68 + t.string "key"
69 + t.string "value_type"
70 + t.string "value"
71 + t.datetime "created_at"
72 + t.datetime "updated_at"
73 + t.text "description"
74 + end
75 +
66 76 create_table "grader_processes", :force => true do |t|
67 77 t.string "host", :limit => 20
68 78 t.integer "pid"
69 79 t.string "mode"
70 80 t.boolean "active"
71 81 t.datetime "created_at"
72 82 t.datetime "updated_at"
73 83 t.integer "task_id"
74 84 t.string "task_type"
75 85 t.boolean "terminated"
76 86 end
77 87
78 88 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
79 89
80 90 create_table "languages", :force => true do |t|
81 91 t.string "name", :limit => 10
82 92 t.string "pretty_name"
83 93 t.string "ext", :limit => 10
84 94 t.string "common_ext"
85 95 end
86 96
87 97 create_table "messages", :force => true do |t|
88 98 t.integer "sender_id"
89 99 t.integer "receiver_id"
90 100 t.integer "replying_message_id"
91 101 t.text "body"
92 102 t.boolean "replied"
93 103 t.datetime "created_at"
94 104 t.datetime "updated_at"
95 105 end
96 106
97 107 create_table "problems", :force => true do |t|
98 108 t.string "name", :limit => 30
99 109 t.string "full_name"
100 110 t.integer "full_score"
101 111 t.date "date_added"
102 112 t.boolean "available"
103 113 t.string "url"
104 114 t.integer "description_id"
105 115 t.boolean "test_allowed"
106 116 t.boolean "output_only"
117 + t.integer "level", :default => 0
118 + t.datetime "updated_at"
107 119 t.string "description_filename"
108 120 end
109 121
110 122 create_table "rights", :force => true do |t|
111 123 t.string "name"
112 124 t.string "controller"
113 125 t.string "action"
114 126 end
115 127
116 128 create_table "rights_roles", :id => false, :force => true do |t|
117 129 t.integer "right_id"
118 130 t.integer "role_id"
119 131 end
120 132
121 133 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
122 134
123 135 create_table "roles", :force => true do |t|
124 136 t.string "name"
125 137 end
126 138
127 139 create_table "roles_users", :id => false, :force => true do |t|
128 140 t.integer "role_id"
129 141 t.integer "user_id"
130 142 end
131 143
132 144 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
133 145
134 146 create_table "sessions", :force => true do |t|
135 147 t.string "session_id"
136 148 t.text "data"
137 149 t.datetime "updated_at"
138 150 end
139 151
140 152 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
141 153 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
142 154
143 155 create_table "sites", :force => true do |t|
144 156 t.string "name"
145 157 t.boolean "started"
146 158 t.datetime "start_time"
147 159 t.datetime "created_at"
148 160 t.datetime "updated_at"
149 161 t.integer "country_id"
150 162 t.string "password"
151 163 end
152 164
165 + create_table "submission_statuses", :force => true do |t|
166 + t.integer "user_id"
167 + t.integer "problem_id"
168 + t.boolean "passed"
169 + t.integer "submission_count"
170 + t.datetime "created_at"
171 + t.datetime "updated_at"
172 + end
173 +
153 174 create_table "submissions", :force => true do |t|
154 175 t.integer "user_id"
155 176 t.integer "problem_id"
156 177 t.integer "language_id"
157 178 t.text "source"
158 179 t.binary "binary"
159 180 t.datetime "submitted_at"
160 181 t.datetime "compiled_at"
161 182 t.text "compiler_message"
162 183 t.datetime "graded_at"
163 184 t.integer "points"
164 185 t.text "grader_comment"
165 186 t.integer "number"
166 187 t.string "source_filename"
167 188 end
168 189
169 190 add_index "submissions", ["user_id", "problem_id", "number"], :name => "index_submissions_on_user_id_and_problem_id_and_number", :unique => true
170 191 add_index "submissions", ["user_id", "problem_id"], :name => "index_submissions_on_user_id_and_problem_id"
171 192
172 193 create_table "tasks", :force => true do |t|
173 194 t.integer "submission_id"
174 195 t.datetime "created_at"
175 196 t.integer "status"
176 197 t.datetime "updated_at"
177 198 end
178 199
200 + create_table "test_pair_assignments", :force => true do |t|
201 + t.integer "user_id"
202 + t.integer "problem_id"
203 + t.integer "test_pair_id"
204 + t.integer "test_pair_number"
205 + t.integer "request_number"
206 + t.datetime "created_at"
207 + t.datetime "updated_at"
208 + t.boolean "submitted"
209 + end
210 +
179 211 create_table "test_pairs", :force => true do |t|
180 212 t.integer "problem_id"
181 213 t.text "input", :limit => 16777215
182 214 t.text "solution", :limit => 16777215
183 215 t.datetime "created_at"
184 216 t.datetime "updated_at"
217 + t.integer "number"
185 218 end
186 219
187 220 create_table "test_requests", :force => true do |t|
188 221 t.integer "user_id"
189 222 t.integer "problem_id"
190 223 t.integer "submission_id"
191 224 t.string "input_file_name"
192 225 t.string "output_file_name"
193 226 t.string "running_stat"
194 227 t.integer "status"
195 228 t.datetime "updated_at"
196 229 t.datetime "submitted_at"
197 230 t.datetime "compiled_at"
198 231 t.text "compiler_message"
199 232 t.datetime "graded_at"
200 233 t.string "grader_comment"
201 234 t.datetime "created_at"
202 235 t.float "running_time"
203 236 t.string "exit_status"
204 237 t.integer "memory_usage"
205 238 end
206 239
207 240 add_index "test_requests", ["user_id", "problem_id"], :name => "index_test_requests_on_user_id_and_problem_id"
208 241
209 242 create_table "user_contest_stats", :force => true do |t|
210 243 t.integer "user_id"
211 244 t.datetime "started_at"
212 245 t.datetime "created_at"
213 246 t.datetime "updated_at"
214 247 t.boolean "forced_logout"
215 248 end
216 249
217 250 create_table "users", :force => true do |t|
218 251 t.string "login", :limit => 50
219 252 t.string "full_name"
220 253 t.string "hashed_password"
221 254 t.string "salt", :limit => 5
222 255 t.string "alias"
223 256 t.string "email"
224 257 t.integer "site_id"
225 258 t.integer "country_id"
226 259 t.boolean "activated", :default => false
227 260 t.datetime "created_at"
228 261 t.datetime "updated_at"
262 + t.string "member1_full_name"
263 + t.string "member2_full_name"
264 + t.string "member3_full_name"
265 + t.boolean "high_school"
266 + t.string "member1_school_name"
267 + t.string "member2_school_name"
268 + t.string "member3_school_name"
229 269 end
230 270
231 271 add_index "users", ["login"], :name => "index_users_on_login", :unique => true
232 272
233 273 end
@@ -78,98 +78,98
78 78 {
79 79 :key => 'system.admin_email',
80 80 :value_type => 'string',
81 81 :default_value => 'admin@admin.email'
82 82 },
83 83
84 84 {
85 85 :key => 'system.user_setting_enabled',
86 86 :value_type => 'boolean',
87 87 :default_value => 'true',
88 88 :description => 'If this option is true, users can change their settings'
89 89 },
90 90
91 91 # If Configuration['contest.test_request.early_timeout'] is true
92 92 # the user will not be able to use test request at 30 minutes
93 93 # before the contest ends.
94 94 {
95 95 :key => 'contest.test_request.early_timeout',
96 96 :value_type => 'boolean',
97 97 :default_value => 'false'
98 98 },
99 99
100 100 {
101 101 :key => 'system.multicontests',
102 102 :value_type => 'boolean',
103 103 :default_value => 'false'
104 104 },
105 105
106 106 {
107 107 :key => 'contest.confirm_indv_contest_start',
108 108 :value_type => 'boolean',
109 109 :default_value => 'false'
110 110 },
111 111
112 112 {
113 113 :key => 'contest.default_contest_name',
114 114 :value_type => 'string',
115 115 :default_value => 'none',
116 116 :description => "New user will be assigned to this contest automatically, if it exists. Set to 'none' if there is no default contest."
117 117 }
118 118
119 119 ]
120 120
121 121
122 122 def create_configuration_key(key,
123 123 value_type,
124 124 default_value,
125 125 description='')
126 - conf = (Configuration.find_by_key(key) ||
127 - Configuration.new(:key => key,
126 + conf = (GraderConfiguration.find_by_key(key) ||
127 + GraderConfiguration.new(:key => key,
128 128 :value_type => value_type,
129 129 :value => default_value))
130 130 conf.description = description
131 131 conf.save
132 132 end
133 133
134 134 def seed_config
135 135 CONFIGURATIONS.each do |conf|
136 136 if conf.has_key? :description
137 137 desc = conf[:description]
138 138 else
139 139 desc = ''
140 140 end
141 141 create_configuration_key(conf[:key],
142 142 conf[:value_type],
143 143 conf[:default_value],
144 144 desc)
145 145 end
146 146 end
147 147
148 148 def seed_roles
149 149 return if Role.find_by_name('admin')
150 150
151 151 role = Role.create(:name => 'admin')
152 152 user_admin_right = Right.create(:name => 'user_admin',
153 153 :controller => 'user_admin',
154 154 :action => 'all')
155 155 problem_admin_right = Right.create(:name=> 'problem_admin',
156 156 :controller => 'problems',
157 157 :action => 'all')
158 158
159 159 graders_right = Right.create(:name => 'graders_admin',
160 160 :controller => 'graders',
161 161 :action => 'all')
162 162
163 163 role.rights << user_admin_right;
164 164 role.rights << problem_admin_right;
165 165 role.rights << graders_right;
166 166 role.save
167 167 end
168 168
169 169 def seed_root
170 170 return if User.find_by_login('root')
171 171
172 172 root = User.new(:login => 'root',
173 173 :full_name => 'Administrator',
174 174 :alias => 'root')
175 175 root.password = 'ioionrails';
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
You need to be logged in to leave comments. Login now