tournament 3.0.3 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +5 -0
- data/lib/tournament/bracket.rb +9 -5
- data/lib/tournament/pool.rb +15 -10
- data/lib/tournament.rb +1 -1
- data/webgui/app/controllers/reports_controller.rb +10 -4
- data/webgui/app/controllers/users_controller.rb +61 -0
- data/webgui/app/models/user.rb +31 -3
- data/webgui/app/models/user_mailer.rb +7 -0
- data/webgui/app/views/sessions/new.html.erb +2 -0
- data/webgui/app/views/user_mailer/password_reset_notification.erb +7 -0
- data/webgui/app/views/users/lost_password.html.erb +20 -0
- data/webgui/app/views/users/reset_password.html.erb +15 -0
- data/webgui/config/environments/development.rb +1 -1
- data/webgui/config/routes.rb +8 -6
- data/webgui/db/migrate/20100312053540_add_password_reset_code.rb +9 -0
- data/webgui/db/schema.rb +92 -0
- data/webgui/doc/README_FOR_APP +47 -4
- data/webgui/lib/tasks/possibility.rake +1 -1
- data/webgui/vendor/plugins/restful_authentication/LICENSE +20 -0
- data/webgui/vendor/plugins/restful_authentication/README.textile +25 -25
- data/webgui/vendor/plugins/restful_authentication/generators/authenticated/authenticated_generator.rb +19 -19
- data/webgui/vendor/plugins/restful_authentication/generators/authenticated/templates/authenticated_test_helper.rb +1 -1
- data/webgui/vendor/plugins/restful_authentication/generators/authenticated/templates/features/accounts.feature +109 -0
- data/webgui/vendor/plugins/restful_authentication/generators/authenticated/templates/{stories/users/sessions.story → features/sessions.feature} +44 -44
- data/webgui/vendor/plugins/restful_authentication/generators/authenticated/templates/features/step_definitions/ra_env.rb +9 -0
- data/webgui/vendor/plugins/restful_authentication/generators/authenticated/templates/features/step_definitions/ra_navigation_steps.rb +48 -0
- data/webgui/vendor/plugins/restful_authentication/generators/authenticated/templates/features/step_definitions/ra_resource_steps.rb +178 -0
- data/webgui/vendor/plugins/restful_authentication/generators/authenticated/templates/features/step_definitions/ra_response_steps.rb +169 -0
- data/webgui/vendor/plugins/restful_authentication/generators/authenticated/templates/{stories/rest_auth_stories_helper.rb → features/step_definitions/rest_auth_features_helper.rb} +5 -5
- data/webgui/vendor/plugins/restful_authentication/generators/authenticated/templates/features/step_definitions/user_steps.rb +131 -0
- data/webgui/vendor/plugins/restful_authentication/generators/authenticated/templates/model.rb +2 -2
- metadata +17 -11
- data/webgui/vendor/plugins/restful_authentication/generators/authenticated/templates/stories/rest_auth_stories.rb +0 -22
- data/webgui/vendor/plugins/restful_authentication/generators/authenticated/templates/stories/steps/ra_navigation_steps.rb +0 -49
- data/webgui/vendor/plugins/restful_authentication/generators/authenticated/templates/stories/steps/ra_resource_steps.rb +0 -179
- data/webgui/vendor/plugins/restful_authentication/generators/authenticated/templates/stories/steps/ra_response_steps.rb +0 -171
- data/webgui/vendor/plugins/restful_authentication/generators/authenticated/templates/stories/steps/user_steps.rb +0 -153
- data/webgui/vendor/plugins/restful_authentication/generators/authenticated/templates/stories/users/accounts.story +0 -186
data/History.txt
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
== 3.1.0 / 2009-03-12
|
2
|
+
* Account for multiple pools when saving/loading possibility yaml file.
|
3
|
+
* Update restful_authentication to latest version.
|
4
|
+
* Add ability to reset passwords.
|
5
|
+
|
1
6
|
== 3.0.3 / 2009-03-11
|
2
7
|
* Fix bug with bad string encoding and prince xml for pdf generation.
|
3
8
|
|
data/lib/tournament/bracket.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
# Class representing a bracket in a tournament.
|
2
2
|
class Tournament::Bracket
|
3
|
-
|
4
|
-
attr_reader :
|
5
|
-
|
6
|
-
attr_reader :
|
3
|
+
# The name of the bracket
|
4
|
+
attr_reader :name
|
5
|
+
# The teams in the bracket
|
6
|
+
attr_reader :teams
|
7
|
+
# The number of rounds in the bracket
|
8
|
+
attr_reader :rounds
|
9
|
+
# The winners of each game in the bracket
|
10
|
+
attr_reader :winners
|
7
11
|
|
8
12
|
# Marker for an unknown team
|
9
13
|
UNKNOWN_TEAM = :unk unless defined?(UNKNOWN_TEAM)
|
@@ -69,7 +73,7 @@ class Tournament::Bracket
|
|
69
73
|
|
70
74
|
# Returns the number of teams left in the bracket.
|
71
75
|
def teams_left
|
72
|
-
return 1 + @winners.inject(0) { |memo, arr| arr.inject(memo) {|
|
76
|
+
return 1 + @winners.inject(0) { |memo, arr| arr.inject(memo) {|memo2, team| memo2 += (team == UNKNOWN_TEAM ? 1 : 0)} }
|
73
77
|
end
|
74
78
|
|
75
79
|
# Returns the number of possible outcomes for the bracket
|
data/lib/tournament/pool.rb
CHANGED
@@ -3,11 +3,16 @@
|
|
3
3
|
# and champions of Region 3 and Region 4 play each
|
4
4
|
# other in the final four.
|
5
5
|
class Tournament::Pool
|
6
|
-
|
7
|
-
attr_reader :
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
# The regions in the pool.
|
7
|
+
attr_reader :regions
|
8
|
+
# Tournament::Entry objects for the participants
|
9
|
+
attr_reader :entries
|
10
|
+
# Hash of payouts by rank
|
11
|
+
attr_reader :payouts
|
12
|
+
# The entry fee
|
13
|
+
attr_accessor :entry_fee
|
14
|
+
# The scoring strategy for the pool
|
15
|
+
attr_reader :scoring_strategy
|
11
16
|
|
12
17
|
# Create a new empty pool with no Regions or Entries
|
13
18
|
def initialize
|
@@ -286,9 +291,9 @@ class Tournament::Pool
|
|
286
291
|
picks = (1..num_picks).map {|n| Tournament::Bracket.random_bracket(b.teams)}
|
287
292
|
# Play out the bracket
|
288
293
|
32.times { |n| b.set_winner(1,n+1, b.matchup(1, n+1)[rand(2)])}
|
289
|
-
|
290
|
-
8.times { |n| b.set_winner(3,n+1, b.matchup(3, n+1)[rand(2)])}
|
291
|
-
|
294
|
+
10.times { |n| b.set_winner(2,n+1, b.matchup(2, n+1)[rand(2)])}
|
295
|
+
# 8.times { |n| b.set_winner(3,n+1, b.matchup(3, n+1)[rand(2)])}
|
296
|
+
#4.times { |n| b.set_winner(4,n+1, b.matchup(4, n+1)[rand(2)])}
|
292
297
|
#2.times { |n| b.set_winner(5,n+1, b.matchup(5, n+1)[rand(2)])}
|
293
298
|
#1.times { |n| b.set_winner(6,n+1, b.matchup(6, n+1)[rand(2)])}
|
294
299
|
picks.each_with_index {|p, idx| pool.add_entry Tournament::Entry.new("picker_#{idx}", p) }
|
@@ -377,8 +382,8 @@ class Tournament::Pool
|
|
377
382
|
else
|
378
383
|
out << fmt2 % [round, round_total, scores_str_arr[0]] << "\n"
|
379
384
|
end
|
380
|
-
scores_str_arr[1..-1].each do |
|
381
|
-
out << fmt3 %
|
385
|
+
scores_str_arr[1..-1].each do |ss2|
|
386
|
+
out << fmt3 % ss2 << "\n"
|
382
387
|
end
|
383
388
|
else
|
384
389
|
out << fmt2 % [round, round_total, scores_str] << "\n"
|
data/lib/tournament.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class ReportsController < ApplicationController
|
2
|
-
|
2
|
+
STATS_DATAFILE_NAME = "stats_%d.yml" unless defined?(STATS_DATAFILE_NAME)
|
3
3
|
layout 'report'
|
4
4
|
def show
|
5
5
|
@pool = Pool.find(params[:id])
|
@@ -9,11 +9,13 @@ class ReportsController < ApplicationController
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def possibility
|
12
|
-
|
12
|
+
pool_id = params[:id]
|
13
|
+
my_data_file = self.stats_data_file(pool_id)
|
14
|
+
if !File.exist?(my_data_file)
|
13
15
|
@message = "The statistics data has not yet been generated. Please try again later or send an email to #{ADMIN_EMAIL}."
|
14
16
|
@stats = []
|
15
17
|
else
|
16
|
-
@stats = YAML.load_file(
|
18
|
+
@stats = YAML.load_file(my_data_file)
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
@@ -51,11 +53,15 @@ class ReportsController < ApplicationController
|
|
51
53
|
output.flush
|
52
54
|
else
|
53
55
|
data = stats_thread[:stats]
|
54
|
-
File.open(
|
56
|
+
File.open(self.stats_data_file(@pool.id), "w") {|f| f.write YAML.dump(data)}
|
55
57
|
output.write "Generated file!"
|
56
58
|
end
|
57
59
|
end
|
58
60
|
render :text => reporter
|
59
61
|
end
|
60
62
|
|
63
|
+
def stats_data_file(pool_id)
|
64
|
+
File.expand_path(File.join(RAILS_ROOT, 'db', STATS_DATAFILE_NAME % pool_id))
|
65
|
+
end
|
66
|
+
|
61
67
|
end
|
@@ -54,4 +54,65 @@ class UsersController < ApplicationController
|
|
54
54
|
redirect_back_or_default(root_path)
|
55
55
|
end
|
56
56
|
end
|
57
|
+
|
58
|
+
def lost_password
|
59
|
+
case request.method
|
60
|
+
when :post
|
61
|
+
logout_keeping_session!
|
62
|
+
@user = User.new(params[:user])
|
63
|
+
@user.confirming_email = true
|
64
|
+
@user.updating_email = false
|
65
|
+
if valid_for_attributes(@user, ["email","email_confirmation"])
|
66
|
+
user = User.find_by_email(params[:user][:email])
|
67
|
+
if user
|
68
|
+
user.create_password_reset_code
|
69
|
+
UserMailer.deliver_password_reset_notification(user, reset_password_path(:reset_code => user.password_reset_code, :only_path => false))
|
70
|
+
end
|
71
|
+
flash[:notice] = "Reset code sent to #{params[:user][:email]}"
|
72
|
+
redirect_back_or_default('/')
|
73
|
+
else
|
74
|
+
flash[:error] = "Please enter a valid email address"
|
75
|
+
end
|
76
|
+
when :get
|
77
|
+
@user = User.new
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def reset_password
|
82
|
+
@user = User.find_by_password_reset_code(params[:reset_code]) unless params[:reset_code].nil?
|
83
|
+
if !@user
|
84
|
+
flash[:error] = "Reset password token invalid, please contact support."
|
85
|
+
redirect_to('/')
|
86
|
+
return
|
87
|
+
else
|
88
|
+
@user.crypted_password = nil
|
89
|
+
end
|
90
|
+
if request.post?
|
91
|
+
if @user.update_attributes(:password => params[:user][:password], :password_confirmation => params[:user][:password_confirmation])
|
92
|
+
#self.current_user = @user
|
93
|
+
@user.delete_password_reset_code
|
94
|
+
flash[:notice] = "Password updated successfully for #{@user.email} - You may now log in using your new password."
|
95
|
+
redirect_back_or_default('/')
|
96
|
+
else
|
97
|
+
render :action => :reset_password
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Might be a good addition to AR::Base
|
103
|
+
def valid_for_attributes( model, attributes )
|
104
|
+
unless model.valid?
|
105
|
+
errors = model.errors
|
106
|
+
our_errors = Array.new
|
107
|
+
errors.each do |attr,error|
|
108
|
+
if attributes.include? attr
|
109
|
+
our_errors << [attr,error]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
errors.clear
|
113
|
+
our_errors.each { |attr,error| errors.add(attr,error) }
|
114
|
+
return false unless errors.empty?
|
115
|
+
end
|
116
|
+
return true
|
117
|
+
end
|
57
118
|
end
|
data/webgui/app/models/user.rb
CHANGED
@@ -9,6 +9,8 @@ class User < ActiveRecord::Base
|
|
9
9
|
has_many :pools
|
10
10
|
has_and_belongs_to_many :roles
|
11
11
|
|
12
|
+
attr_accessor :updating_email, :confirming_email
|
13
|
+
|
12
14
|
validates_presence_of :login
|
13
15
|
validates_length_of :login, :within => 3..40
|
14
16
|
validates_uniqueness_of :login
|
@@ -19,7 +21,9 @@ class User < ActiveRecord::Base
|
|
19
21
|
|
20
22
|
validates_presence_of :email
|
21
23
|
validates_length_of :email, :within => 6..100 #r@a.wk
|
22
|
-
validates_uniqueness_of :email
|
24
|
+
validates_uniqueness_of :email, :if => :updating_email?
|
25
|
+
validates_presence_of :email_confirmation, :if => :confirming_email
|
26
|
+
validates_confirmation_of :email, :if => :confirming_email
|
23
27
|
validates_format_of :email, :with => Authentication.email_regex, :message => Authentication.bad_email_message
|
24
28
|
|
25
29
|
before_create :make_activation_code
|
@@ -27,7 +31,7 @@ class User < ActiveRecord::Base
|
|
27
31
|
# HACK HACK HACK -- how to do attr_accessible from here?
|
28
32
|
# prevents a user from submitting a crafted form that bypasses activation
|
29
33
|
# anything else you want your user to change should be added here.
|
30
|
-
attr_accessible :login, :email, :name, :password, :password_confirmation
|
34
|
+
attr_accessible :login, :email, :email_confirmation, :name, :password, :password_confirmation
|
31
35
|
|
32
36
|
# Return all users with admin role
|
33
37
|
def self.admin_users
|
@@ -87,11 +91,35 @@ class User < ActiveRecord::Base
|
|
87
91
|
def email=(value)
|
88
92
|
write_attribute :email, (value ? value.downcase : nil)
|
89
93
|
end
|
94
|
+
|
95
|
+
def create_password_reset_code
|
96
|
+
@password_reset = true
|
97
|
+
self.password_reset_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
|
98
|
+
self.save(false)
|
99
|
+
end
|
100
|
+
|
101
|
+
def password_recently_reset?
|
102
|
+
@password_reset
|
103
|
+
end
|
104
|
+
|
105
|
+
def delete_password_reset_code
|
106
|
+
self.password_reset_code = nil
|
107
|
+
self.save(false)
|
108
|
+
end
|
90
109
|
|
91
110
|
protected
|
92
111
|
|
93
112
|
def make_activation_code
|
94
|
-
|
113
|
+
self.activation_code = self.class.make_token
|
114
|
+
end
|
115
|
+
|
116
|
+
def updating_email?
|
117
|
+
# validate_uniqueness_of email unless specifically set to false
|
118
|
+
if updating_email == false
|
119
|
+
return false
|
120
|
+
else
|
121
|
+
return true
|
122
|
+
end
|
95
123
|
end
|
96
124
|
|
97
125
|
|
@@ -21,9 +21,16 @@ class UserMailer < ActionMailer::Base
|
|
21
21
|
@body[:content] = content
|
22
22
|
@body[:url] = home_url
|
23
23
|
end
|
24
|
+
|
25
|
+
def password_reset_notification(user, reset_url)
|
26
|
+
setup_email(user)
|
27
|
+
@subject = 'Link to reset your password'
|
28
|
+
@body[:url] = reset_url
|
29
|
+
end
|
24
30
|
|
25
31
|
protected
|
26
32
|
def setup_email(user)
|
33
|
+
@user = user
|
27
34
|
@recipients = user.email
|
28
35
|
@from = ADMIN_EMAIL
|
29
36
|
@subject = "[#{TOURNAMENT_TITLE}] "
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<h1>Lost Password</h1>
|
2
|
+
<p>
|
3
|
+
Please enter the email address that you registered with. Once you click
|
4
|
+
on the Send button, we will send you an email that allows you to change
|
5
|
+
your password.
|
6
|
+
</p>
|
7
|
+
<%= error_messages_for :user, :header_message => "Please review the following errors:", :message => '' %>
|
8
|
+
<% form_for :user do |f| -%>
|
9
|
+
<table>
|
10
|
+
<tr>
|
11
|
+
<td align="right"><%= label_tag 'email' %></td>
|
12
|
+
<td><%= f.text_field :email %></td>
|
13
|
+
</tr>
|
14
|
+
<tr>
|
15
|
+
<td align="right"><%= label_tag 'email_confirmation' %></td>
|
16
|
+
<td><%= f.text_field :email_confirmation %></td>
|
17
|
+
</tr>
|
18
|
+
</table>
|
19
|
+
<p><%= submit_tag 'Send' %></p>
|
20
|
+
<% end -%>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<%= error_messages_for :user %>
|
2
|
+
|
3
|
+
<h1>Choose a new password</h1>
|
4
|
+
|
5
|
+
<% form_for :user do |f| -%>
|
6
|
+
<div>
|
7
|
+
New Password: <%= f.password_field :password %>
|
8
|
+
</div>
|
9
|
+
<div>
|
10
|
+
Confirm Password: <%= f.password_field :password_confirmation %>
|
11
|
+
</div>
|
12
|
+
<div>
|
13
|
+
<%= submit_tag 'Change Password' %>
|
14
|
+
</div>
|
15
|
+
<% end -%>
|
data/webgui/config/routes.rb
CHANGED
@@ -35,12 +35,14 @@ ActionController::Routing::Routes.draw do |map|
|
|
35
35
|
|
36
36
|
# See how all your routes lay out with "rake routes"
|
37
37
|
|
38
|
-
# restful_authentication
|
39
|
-
map.logout '
|
40
|
-
map.login '
|
41
|
-
map.register '
|
42
|
-
map.signup '
|
43
|
-
map.activate '
|
38
|
+
# restful_authentication routes
|
39
|
+
map.logout 'logout', :controller => 'sessions', :action => 'destroy'
|
40
|
+
map.login 'login', :controller => 'sessions', :action => 'new'
|
41
|
+
map.register 'register', :controller => 'users', :action => 'create'
|
42
|
+
map.signup 'signup', :controller => 'users', :action => 'new'
|
43
|
+
map.activate 'activate/:activation_code', :controller => 'users', :action => 'activate', :activation_code => nil
|
44
|
+
map.reset_password 'reset_password/:reset_code', :controller => 'users', :action => 'reset_password'
|
45
|
+
map.lost_password 'lost_password', :controller => 'users', :action => 'lost_password'
|
44
46
|
map.resources :users
|
45
47
|
map.resource :session
|
46
48
|
|
data/webgui/db/schema.rb
ADDED
@@ -0,0 +1,92 @@
|
|
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.
|
4
|
+
#
|
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
|
8
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
9
|
+
#
|
10
|
+
# It's strongly recommended to check this file into your version control system.
|
11
|
+
|
12
|
+
ActiveRecord::Schema.define(:version => 20100312053540) do
|
13
|
+
|
14
|
+
create_table "entries", :force => true do |t|
|
15
|
+
t.string "name", :limit => 64, :null => false
|
16
|
+
t.binary "data"
|
17
|
+
t.datetime "created_at"
|
18
|
+
t.datetime "updated_at"
|
19
|
+
t.integer "tie_break"
|
20
|
+
t.integer "user_id", :default => 1, :null => false
|
21
|
+
t.integer "pool_id"
|
22
|
+
t.boolean "completed", :default => false, :null => false
|
23
|
+
end
|
24
|
+
|
25
|
+
add_index "entries", ["pool_id"], :name => "index_entries_on_pool_id"
|
26
|
+
add_index "entries", ["user_id"], :name => "index_entries_on_user_id"
|
27
|
+
|
28
|
+
create_table "pools", :force => true do |t|
|
29
|
+
t.string "name", :null => false
|
30
|
+
t.binary "data"
|
31
|
+
t.boolean "started", :default => false, :null => false
|
32
|
+
t.datetime "starts_at"
|
33
|
+
t.datetime "created_at"
|
34
|
+
t.datetime "updated_at"
|
35
|
+
t.integer "user_id"
|
36
|
+
t.boolean "active", :default => false, :null => false
|
37
|
+
end
|
38
|
+
|
39
|
+
create_table "regions", :force => true do |t|
|
40
|
+
t.integer "pool_id"
|
41
|
+
t.string "name"
|
42
|
+
t.integer "position"
|
43
|
+
t.datetime "created_at"
|
44
|
+
t.datetime "updated_at"
|
45
|
+
end
|
46
|
+
|
47
|
+
create_table "roles", :force => true do |t|
|
48
|
+
t.string "name", :limit => 32
|
49
|
+
t.datetime "created_at"
|
50
|
+
t.datetime "updated_at"
|
51
|
+
t.integer "position", :default => 0, :null => false
|
52
|
+
end
|
53
|
+
|
54
|
+
create_table "roles_users", :id => false, :force => true do |t|
|
55
|
+
t.integer "role_id"
|
56
|
+
t.integer "user_id"
|
57
|
+
end
|
58
|
+
|
59
|
+
create_table "seedings", :force => true do |t|
|
60
|
+
t.integer "pool_id"
|
61
|
+
t.integer "team_id"
|
62
|
+
t.string "region"
|
63
|
+
t.integer "seed"
|
64
|
+
t.datetime "created_at"
|
65
|
+
t.datetime "updated_at"
|
66
|
+
end
|
67
|
+
|
68
|
+
create_table "teams", :force => true do |t|
|
69
|
+
t.string "name"
|
70
|
+
t.string "short_name"
|
71
|
+
t.datetime "created_at"
|
72
|
+
t.datetime "updated_at"
|
73
|
+
end
|
74
|
+
|
75
|
+
create_table "users", :force => true do |t|
|
76
|
+
t.string "login", :limit => 40
|
77
|
+
t.string "name", :limit => 100, :default => ""
|
78
|
+
t.string "email", :limit => 100
|
79
|
+
t.string "crypted_password", :limit => 40
|
80
|
+
t.string "salt", :limit => 40
|
81
|
+
t.datetime "created_at"
|
82
|
+
t.datetime "updated_at"
|
83
|
+
t.string "remember_token", :limit => 40
|
84
|
+
t.datetime "remember_token_expires_at"
|
85
|
+
t.string "activation_code", :limit => 40
|
86
|
+
t.datetime "activated_at"
|
87
|
+
t.string "password_reset_code", :limit => 40
|
88
|
+
end
|
89
|
+
|
90
|
+
add_index "users", ["login"], :name => "index_users_on_login", :unique => true
|
91
|
+
|
92
|
+
end
|
data/webgui/doc/README_FOR_APP
CHANGED
@@ -1,5 +1,48 @@
|
|
1
|
-
|
1
|
+
= USING THE WEB GUI:
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
Load the entry page in your brower. Log in as the admin user you
|
4
|
+
configured during installation. Click on on the 'All Pools' link on
|
5
|
+
the right sidebar. Create a new pool and fill in the information.
|
6
|
+
Each time you save this form, a new blank payouts line will be added
|
7
|
+
so that you can configure as many payouts as you desire.
|
8
|
+
|
9
|
+
After the basic pool configuration is set up, click on the 'Teams'
|
10
|
+
link in the right sidebar. You are presented with four region
|
11
|
+
brackets to fill in. Keep in mind that the pink region champs will
|
12
|
+
play each other in the final four and the light blue region champs
|
13
|
+
will play each other in the final four so you can get the bracket
|
14
|
+
right. The web application is preconfigured with over 300 NCAA
|
15
|
+
schools. The team name fields are auto-complete fields -- type in
|
16
|
+
a few letters and pause and you will be presented with a list of
|
17
|
+
matching teams. The Short Name field should be a three letter
|
18
|
+
abbreviation for the team. The abbreviations have to be unique
|
19
|
+
across the entire tournament field.
|
20
|
+
|
21
|
+
Once the teams are configured, go back to the pool basic information
|
22
|
+
form, click the Active check box and save the form. The pool is now
|
23
|
+
ready for entries to be added to it. Invite your friends to join the pool
|
24
|
+
by giving them the url for the entry page. They will be asked to
|
25
|
+
register. After registering and logging in, they will be able to
|
26
|
+
submit entries to your pool.
|
27
|
+
|
28
|
+
As the tournament progresses, use the 'Tournament Bracket' link
|
29
|
+
on the right sidebar to record the winning teams.
|
30
|
+
|
31
|
+
Use the report links to run reports, etc.
|
32
|
+
|
33
|
+
== POSSIBILITY REPORT
|
34
|
+
|
35
|
+
After about 21 teams are left in the tournament, you can run the
|
36
|
+
possibility report. This report runs through every possible way the
|
37
|
+
tournament can come out and ranks each entry against the possiblity.
|
38
|
+
The report lists the "chance to win" for each entry. The chance
|
39
|
+
to win is the percentage of possible outcomes that would result in
|
40
|
+
that entry coming in first.
|
41
|
+
|
42
|
+
The possibility report requires that a rake task be run on the
|
43
|
+
web server. It is very processor intensive and can take a long
|
44
|
+
time to complete. To generate the possibility report data file,
|
45
|
+
run the following command from the web gui install directory
|
46
|
+
on the server:
|
47
|
+
|
48
|
+
RAILS_ENV=production rake report:possibilities
|
@@ -10,7 +10,7 @@ namespace :report do
|
|
10
10
|
print "\rCalculating: %3d%% +#{hashes.ljust(20, '-')}+ %5d seconds remaining" % [percentage.to_i, remaining]
|
11
11
|
end
|
12
12
|
puts
|
13
|
-
stats_yaml_file = File.join(RAILS_ROOT, 'db',
|
13
|
+
stats_yaml_file = File.join(RAILS_ROOT, 'db', "stats_#{pool_id}.yml")
|
14
14
|
bytes = File.open(stats_yaml_file, "w") {|f| f.write YAML.dump(stats)}
|
15
15
|
puts "Wrote #{bytes} bytes to #{stats_yaml_file} ..."
|
16
16
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 rick olson
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|