Description:
added level to problems, randoms problem from each level
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r255:b7ca2d765156 - - 9 files changed: 87 inserted, 7 deleted

@@ -0,0 +1,9
1 + class AddLevelToProblems < ActiveRecord::Migration
2 + def self.up
3 + add_column :problems, :level, :integer, :default => 0
4 + end
5 +
6 + def self.down
7 + remove_column :problems, :level, :integer
8 + end
9 + end
@@ -1,13 +1,37
1 1 class CodejomController < ApplicationController
2 2
3 3 before_filter :admin_authorization
4 - before_filter :authenticate
5 4
6 5 def index
7 6 @user = User.find(session[:user_id])
8 7 @problems = Problem.find(:all)
9 - @available_problems = @problems.find_all {|p| not p.available }
8 + @levels = @problems.collect {|p| p.level}.uniq.sort
9 + @available_problems = {}
10 + @levels.each do |level|
11 + @available_problems[level] = []
12 + end
13 + @problems.find_all {|p| not p.available }.each do |problem|
14 + @available_problems[problem.level] << problem
15 + end
10 16 @activated_problems = @problems.find_all {|p| p.available }
11 17 end
12 18
19 + def random_problem
20 + level = params[:id].to_i
21 +
22 + problems = Problem.unavailable.level(level).all
23 + puts problems
24 + if problems.length!=0
25 + if problems.length != 1
26 + problem = problems[rand(problems.length)]
27 + else
28 + problem = problems[0]
29 + end
30 + problem.available = true
31 + problem.save
32 + end
33 +
34 + redirect_to :action => 'index'
35 + end
36 +
13 37 end
@@ -1,56 +1,59
1 1 class ProblemsController < ApplicationController
2 2
3 3 before_filter :authenticate, :authorization
4 4
5 5 in_place_edit_for :problem, :name
6 6 in_place_edit_for :problem, :full_name
7 7 in_place_edit_for :problem, :full_score
8 8
9 + # for codejom
10 + in_place_edit_for :problem, :level
11 +
9 12 def index
10 13 list
11 14 render :action => 'list'
12 15 end
13 16
14 17 # GETs should be safe (see http://www.w3.org/2001/tag/doc/whenToUseGet.html)
15 18 verify :method => :post, :only => [ :destroy,
16 19 :create, :quick_create,
17 20 :do_manage,
18 21 :do_import,
19 22 :update ],
20 23 :redirect_to => { :action => :list }
21 24
22 25 def list
23 26 @problems = Problem.find(:all, :order => 'date_added DESC')
24 27 end
25 28
26 29 def show
27 30 @problem = Problem.find(params[:id])
28 31 end
29 32
30 33 def new
31 34 @problem = Problem.new
32 35 @description = nil
33 36 end
34 37
35 38 def create
36 39 @problem = Problem.new(params[:problem])
37 40 @description = Description.new(params[:description])
38 41 if @description.body!=''
39 42 if !@description.save
40 43 render :action => new and return
41 44 end
42 45 else
43 46 @description = nil
44 47 end
45 48 @problem.description = @description
46 49 if @problem.save
47 50 flash[:notice] = 'Problem was successfully created.'
48 51 redirect_to :action => 'list'
49 52 else
50 53 render :action => 'new'
51 54 end
52 55 end
53 56
54 57 def quick_create
55 58 @problem = Problem.new(params[:problem])
56 59 @problem.full_name = @problem.name if @problem.full_name == ''
@@ -1,53 +1,60
1 1 class Problem < ActiveRecord::Base
2 2
3 3 belongs_to :description
4 4 has_many :test_pairs, :dependent => :delete_all
5 5
6 + named_scope :level, lambda { |level|
7 + { :conditions => { :level => level }}
8 + }
9 +
10 + named_scope :unavailable, { :conditions => { :available => false }}
11 +
12 +
6 13 validates_presence_of :name
7 14 validates_format_of :name, :with => /^\w+$/
8 15 validates_presence_of :full_name
9 16
10 17 DEFAULT_TIME_LIMIT = 1
11 18 DEFAULT_MEMORY_LIMIT = 32
12 19
13 20 def test_pair_count
14 21 @test_pair_count ||= test_pairs.size
15 22 end
16 23
17 24 def uses_random_test_pair?
18 25 test_pair_count != 0
19 26 end
20 27
21 28 def random_test_pair(forbidden_numbers=nil)
22 29 if forbidden_numbers.length < test_pair_count
23 30 begin
24 31 test_num = 1 + rand(test_pair_count)
25 32 end while forbidden_numbers!=nil and forbidden_numbers.include? test_num
26 33 else
27 34 test_num = 1 + rand(test_pair_count)
28 35 end
29 36 test_pairs.find_by_number test_num
30 37 end
31 38
32 39 def self.find_available_problems
33 40 find(:all, :conditions => {:available => true}, :order => "date_added DESC")
34 41 end
35 42
36 43 # TODO: may try to optimize this using cache
37 44 def self.available_problem_count
38 45 return Problem.find_available_problems.length
39 46 end
40 47
41 48 def self.create_from_import_form_params(params, old_problem=nil)
42 49 problem = old_problem || Problem.new
43 50 import_params = Problem.extract_params_and_check(params, problem)
44 51
45 52 if not problem.valid?
46 53 return problem, 'Error importing'
47 54 end
48 55
49 56 problem.full_score = 100
50 57 problem.date_added = Time.new
51 58 problem.test_allowed = true
52 59 problem.output_only = false
53 60 problem.available = false
@@ -1,11 +1,23
1 1 %h1 Code Jom Control Panel
2 2
3 - %h2= "Available problems (#{@available_problems.length})"
4 - %ul
5 - - @available_problems.each do |problem|
6 - %li= problem.name
3 + %h2 Available problems
4 + %table{:class => "codejom-problems"}
5 + %tr
6 + - @levels.each do |level|
7 + %th= "Level #{level} (#{@available_problems[level].length})"
8 + %tr
9 + - @levels.each do |level|
10 + %td
11 + - @available_problems[level].each do |problem|
12 + = problem.name
13 + %br/
14 + %tr
15 + - @levels.each do |level|
16 + %td{:class => 'random-button'}
17 + - form_tag :action => 'random_problem', :id => level do
18 + = submit_tag 'Random'
7 19
8 20 %h2= "Activated problems (#{@activated_problems.length})"
9 21 - @activated_problems.each do |problem|
10 22 = problem.name
11 23
@@ -1,58 +1,60
1 1 <% content_for :head do %>
2 2 <%= stylesheet_link_tag 'problems' %>
3 3 <%= javascript_include_tag :defaults %>
4 4 <% end %>
5 5
6 6 <h1>Listing problems</h1>
7 7
8 8 <p>
9 9 <%= link_to '[New problem]', :action => 'new' %>
10 10 <%= link_to '[Manage problems]', :action => 'manage' %>
11 11 <%= link_to '[Import problems]', :action => 'import' %>
12 12 <%= link_to '[Turn off all problems]', :action => 'turn_all_off' %>
13 13 <%= link_to '[Turn on all problems]', :action => 'turn_all_on' %>
14 14 </p>
15 15
16 16 <div class="submitbox">
17 17 <% form_tag :action => 'quick_create' do %>
18 18 <b>Quick New:</b>
19 19 <label for="problem_name">Name</label>
20 20 <%= text_field 'problem', 'name' %> |
21 21 <label for="problem_full_name">Full name</label>
22 22 <%= text_field 'problem', 'full_name' %>
23 23 <%= submit_tag "Create" %>
24 24 <% end %>
25 25 </div>
26 26
27 27 <table>
28 28 <tr>
29 29 <th>Name</th>
30 30 <th>Full name</th>
31 + <th>Level</th>
31 32 <th>Full score</th>
32 33 <th>Date added</th>
33 34 <th>Avail?</th>
34 35 <th>Test?</th>
35 36 </tr>
36 37
37 38 <% for problem in @problems %>
38 39 <tr id="prob-<%= problem.id %>" name="prob-<%= problem.id %>" class="<%= (problem.available) ? "available" : "not-available" %>">
39 40 <% @problem=problem %>
40 41 <td><%= in_place_editor_field :problem, :name, {}, :rows=>1 %></td>
41 42 <td><%= in_place_editor_field :problem, :full_name, {}, :rows=>1 %></td>
43 + <td><%= in_place_editor_field :problem, :level, {}, :rows=>1 %></td>
42 44 <td><%= in_place_editor_field :problem, :full_score, {}, :rows=>1 %></td>
43 45 <td><%= problem.date_added %></td>
44 46 <td id="prob-<%= problem.id %>-avail"><%= problem.available %></td>
45 47 <td><%= problem.test_allowed %></td>
46 48
47 49 <td><%= link_to_remote '[Toggle]', :url => {:action => 'toggle', :id => problem.id } %></td>
48 50 <td><%= link_to '[Stat]', :action => 'stat', :id => problem.id %></td>
49 51 <td><%= link_to '[Show]', :action => 'show', :id => problem %></td>
50 52 <td><%= link_to '[Edit]', :action => 'edit', :id => problem %></td>
51 53 <td><%= link_to '[Destroy]', { :action => 'destroy', :id => problem }, :confirm => 'Are you sure?', :method => :post %></td>
52 54 </tr>
53 55 <% end %>
54 56 </table>
55 57
56 58 <br />
57 59
58 60 <%= link_to '[New problem]', :action => 'new' %>
@@ -1,143 +1,144
1 1 # This file is auto-generated from the current state of the database. Instead of editing this file,
2 2 # please use the migrations feature of Active Record to incrementally modify your database, and
3 3 # then regenerate this schema definition.
4 4 #
5 5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
6 6 # to create the application database on another system, you should be using db:schema:load, not running
7 7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
8 8 # you'll amass, the slower it'll run and the greater likelihood for issues).
9 9 #
10 10 # It's strongly recommended to check this file into your version control system.
11 11
12 - ActiveRecord::Schema.define(:version => 20100129041917) do
12 + ActiveRecord::Schema.define(:version => 20100209145331) do
13 13
14 14 create_table "announcements", :force => true do |t|
15 15 t.string "author"
16 16 t.text "body"
17 17 t.boolean "published"
18 18 t.datetime "created_at"
19 19 t.datetime "updated_at"
20 20 t.boolean "frontpage", :default => false
21 21 t.boolean "contest_only", :default => false
22 22 t.string "title"
23 23 end
24 24
25 25 create_table "codejom_statuses", :force => true do |t|
26 26 t.integer "user_id"
27 27 t.boolean "alive"
28 28 t.integer "num_problems_passed"
29 29 t.datetime "created_at"
30 30 t.datetime "updated_at"
31 31 end
32 32
33 33 create_table "configurations", :force => true do |t|
34 34 t.string "key"
35 35 t.string "value_type"
36 36 t.string "value"
37 37 t.datetime "created_at"
38 38 t.datetime "updated_at"
39 39 t.text "description"
40 40 end
41 41
42 42 create_table "countries", :force => true do |t|
43 43 t.string "name"
44 44 t.datetime "created_at"
45 45 t.datetime "updated_at"
46 46 end
47 47
48 48 create_table "descriptions", :force => true do |t|
49 49 t.text "body"
50 50 t.boolean "markdowned"
51 51 t.datetime "created_at"
52 52 t.datetime "updated_at"
53 53 end
54 54
55 55 create_table "grader_processes", :force => true do |t|
56 56 t.string "host", :limit => 20
57 57 t.integer "pid"
58 58 t.string "mode"
59 59 t.boolean "active"
60 60 t.datetime "created_at"
61 61 t.datetime "updated_at"
62 62 t.integer "task_id"
63 63 t.string "task_type"
64 64 t.boolean "terminated"
65 65 end
66 66
67 67 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
68 68
69 69 create_table "languages", :force => true do |t|
70 70 t.string "name", :limit => 10
71 71 t.string "pretty_name"
72 72 t.string "ext", :limit => 10
73 73 t.string "common_ext"
74 74 end
75 75
76 76 create_table "messages", :force => true do |t|
77 77 t.integer "sender_id"
78 78 t.integer "receiver_id"
79 79 t.integer "replying_message_id"
80 80 t.text "body"
81 81 t.boolean "replied"
82 82 t.datetime "created_at"
83 83 t.datetime "updated_at"
84 84 end
85 85
86 86 create_table "problems", :force => true do |t|
87 87 t.string "name", :limit => 30
88 88 t.string "full_name"
89 89 t.integer "full_score"
90 90 t.date "date_added"
91 91 t.boolean "available"
92 92 t.string "url"
93 93 t.integer "description_id"
94 94 t.boolean "test_allowed"
95 95 t.boolean "output_only"
96 + t.integer "level", :default => 0
96 97 end
97 98
98 99 create_table "rights", :force => true do |t|
99 100 t.string "name"
100 101 t.string "controller"
101 102 t.string "action"
102 103 end
103 104
104 105 create_table "rights_roles", :id => false, :force => true do |t|
105 106 t.integer "right_id"
106 107 t.integer "role_id"
107 108 end
108 109
109 110 add_index "rights_roles", ["role_id"], :name => "index_rights_roles_on_role_id"
110 111
111 112 create_table "roles", :force => true do |t|
112 113 t.string "name"
113 114 end
114 115
115 116 create_table "roles_users", :id => false, :force => true do |t|
116 117 t.integer "role_id"
117 118 t.integer "user_id"
118 119 end
119 120
120 121 add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id"
121 122
122 123 create_table "sessions", :force => true do |t|
123 124 t.string "session_id"
124 125 t.text "data"
125 126 t.datetime "updated_at"
126 127 end
127 128
128 129 add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
129 130 add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
130 131
131 132 create_table "sites", :force => true do |t|
132 133 t.string "name"
133 134 t.boolean "started"
134 135 t.datetime "start_time"
135 136 t.datetime "created_at"
136 137 t.datetime "updated_at"
137 138 t.integer "country_id"
138 139 t.string "password"
139 140 end
140 141
141 142 create_table "submission_statuses", :force => true do |t|
142 143 t.integer "user_id"
143 144 t.integer "problem_id"
@@ -232,48 +232,58
232 232 margin: 10px 0;
233 233 font-size: 12px;
234 234 line-height: 1.5em; }
235 235
236 236 .test-desc {
237 237 border: 1px dotted gray;
238 238 background: #f5f5f5;
239 239 padding: 5px;
240 240 margin: 10px 0;
241 241 font-size: 12px;
242 242 line-height: 1.5em; }
243 243
244 244 .problem-list {
245 245 width: 200px;
246 246 float: left; }
247 247
248 248 .problem-bar {
249 249 margin-top: 5px;
250 250 padding: 5px;
251 251 background: #e0e0e0; }
252 252 .problem-bar span.problem-title {
253 253 font-weight: bold;
254 254 font-size: 110%; }
255 255
256 256 .problem-content {
257 257 float: left;
258 258 margin-left: 10px;
259 259 width: 700px; }
260 260
261 261 .problem-panel {
262 262 border: 1px black solid;
263 263 padding: 5px; }
264 264 .problem-panel .problem-form {
265 265 border: 1px dotted #99aaee;
266 266 background: #eeeeff; }
267 267
268 268 .notice-bar {
269 269 margin-top: 3px;
270 270 margin-bottom: 3px;
271 271 text-align: center; }
272 272 .notice-bar span.notice {
273 273 color: white;
274 274 font-weight: bold;
275 275 background: #000070;
276 276 padding: 3px 20px 3px 20px;
277 277 -moz-border-radius: 2px;
278 278 -webkit-border-radius: 5px;
279 279 border-radius: 5px; }
280 +
281 + table.codejom-problems th {
282 + background: #000070;
283 + color: white; }
284 + table.codejom-problems td {
285 + width: 200px;
286 + vertical-align: top;
287 + text-align: center; }
288 + table.codejom-problems td.random-button {
289 + background: lightgrey; }
@@ -279,48 +279,60
279 279
280 280 .test-desc
281 281 border: 1px dotted gray
282 282 background: #f5f5f5
283 283 padding: 5px
284 284 margin: 10px 0
285 285 font-size: 12px
286 286 line-height: 1.5em
287 287
288 288 .problem-list
289 289 width: 200px
290 290 float: left
291 291
292 292 .problem-bar
293 293 margin-top: 5px
294 294 padding: 5px
295 295 background: #e0e0e0
296 296
297 297 span.problem-title
298 298 font-weight: bold
299 299 font-size: 110%
300 300
301 301 .problem-content
302 302 float: left
303 303 margin-left: 10px
304 304 width: 700px
305 305
306 306 .problem-panel
307 307 border: 1px black solid
308 308 padding: 5px
309 309
310 310 .problem-form
311 311 border: 1px dotted #99aaee
312 312 background: #eeeeff
313 313
314 314 .notice-bar
315 315 margin-top: 3px
316 316 margin-bottom: 3px
317 317 text-align: center
318 318
319 319 span.notice
320 320 color: white
321 321 font-weight: bold
322 322 background: #000070
323 323 padding: 3px 20px 3px 20px
324 324 -moz-border-radius: 2px
325 325 -webkit-border-radius: 5px
326 326 border-radius: 5px
327 +
328 + table.codejom-problems
329 + th
330 + background: #000070
331 + color: white
332 + td
333 + width: 200px
334 + vertical-align: top
335 + text-align: center
336 +
337 + &.random-button
338 + background: lightgrey No newline at end of file
You need to be logged in to leave comments. Login now