sportdb-play 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.md +3 -0
- data/Manifest.txt +17 -0
- data/README.md +16 -0
- data/Rakefile +30 -0
- data/lib/sportdb/play.rb +39 -0
- data/lib/sportdb/play/models/bonus_point.rb +17 -0
- data/lib/sportdb/play/models/bonus_question.rb +16 -0
- data/lib/sportdb/play/models/bonus_round.rb +15 -0
- data/lib/sportdb/play/models/bonus_tip.rb +16 -0
- data/lib/sportdb/play/models/game.rb +91 -0
- data/lib/sportdb/play/models/play.rb +59 -0
- data/lib/sportdb/play/models/point.rb +55 -0
- data/lib/sportdb/play/models/pool.rb +36 -0
- data/lib/sportdb/play/models/tip.rb +247 -0
- data/lib/sportdb/play/models/user.rb +18 -0
- data/lib/sportdb/play/schema.rb +158 -0
- data/lib/sportdb/play/version.rb +7 -0
- metadata +113 -0
data/History.md
ADDED
data/Manifest.txt
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
History.md
|
|
2
|
+
Manifest.txt
|
|
3
|
+
README.md
|
|
4
|
+
Rakefile
|
|
5
|
+
lib/sportdb/play.rb
|
|
6
|
+
lib/sportdb/play/models/bonus_point.rb
|
|
7
|
+
lib/sportdb/play/models/bonus_question.rb
|
|
8
|
+
lib/sportdb/play/models/bonus_round.rb
|
|
9
|
+
lib/sportdb/play/models/bonus_tip.rb
|
|
10
|
+
lib/sportdb/play/models/game.rb
|
|
11
|
+
lib/sportdb/play/models/play.rb
|
|
12
|
+
lib/sportdb/play/models/point.rb
|
|
13
|
+
lib/sportdb/play/models/pool.rb
|
|
14
|
+
lib/sportdb/play/models/tip.rb
|
|
15
|
+
lib/sportdb/play/models/user.rb
|
|
16
|
+
lib/sportdb/play/schema.rb
|
|
17
|
+
lib/sportdb/play/version.rb
|
data/README.md
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# sport.db-play
|
|
2
|
+
|
|
3
|
+
Open sports database (sport.db) plugin for plays (predictions,
|
|
4
|
+
betting pools, etc.)
|
|
5
|
+
|
|
6
|
+
TBD
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## License
|
|
10
|
+
|
|
11
|
+
The `sport.db-play` scripts are dedicated to the public domain.
|
|
12
|
+
Use it as you please with no restrictions whatsoever.
|
|
13
|
+
|
|
14
|
+
## Questions? Comments?
|
|
15
|
+
|
|
16
|
+
Send them along to the [Open Sports Database & Friends Forum/Mailing List](http://groups.google.com/group/opensport). Thanks!
|
data/Rakefile
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'hoe'
|
|
2
|
+
require './lib/sportdb/play/version.rb'
|
|
3
|
+
|
|
4
|
+
## NB: plugin (hoe-manifest) not required; just used for future testing/development
|
|
5
|
+
Hoe::plugin :manifest # more options for manifests (in the future; not yet)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Hoe.spec 'sportdb-play' do
|
|
9
|
+
|
|
10
|
+
self.version = SportDB::Play::VERSION
|
|
11
|
+
|
|
12
|
+
self.summary = 'sportdb plugin for plays (predictions, betting pool, etc.)'
|
|
13
|
+
self.description = summary
|
|
14
|
+
|
|
15
|
+
self.urls = ['http://geraldb.github.com/sport.db']
|
|
16
|
+
|
|
17
|
+
self.author = 'Gerald Bauer'
|
|
18
|
+
self.email = 'opensport@googlegroups.com'
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## soft deps (dependencies)
|
|
22
|
+
## -- sportdb gem must be installed already
|
|
23
|
+
|
|
24
|
+
self.licenses = ['Public Domain']
|
|
25
|
+
|
|
26
|
+
self.spec_extras = {
|
|
27
|
+
:required_ruby_version => '>= 1.9.2'
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
end
|
data/lib/sportdb/play.rb
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
## NB: do NOT require sportdb (avoid circular loading)
|
|
2
|
+
#### require 'sportdb'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
require 'sportdb/play/version'
|
|
6
|
+
|
|
7
|
+
require 'sportdb/play/schema'
|
|
8
|
+
require 'sportdb/play/models/bonus_point'
|
|
9
|
+
require 'sportdb/play/models/bonus_question'
|
|
10
|
+
require 'sportdb/play/models/bonus_round'
|
|
11
|
+
require 'sportdb/play/models/bonus_tip'
|
|
12
|
+
require 'sportdb/play/models/game'
|
|
13
|
+
require 'sportdb/play/models/play'
|
|
14
|
+
require 'sportdb/play/models/point'
|
|
15
|
+
require 'sportdb/play/models/pool'
|
|
16
|
+
require 'sportdb/play/models/tip'
|
|
17
|
+
require 'sportdb/play/models/user'
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
module SportDB::Play
|
|
21
|
+
|
|
22
|
+
def self.banner
|
|
23
|
+
"sportdb-play #{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
## cut off folders lib(#1)/sportdb(#2) to get to root
|
|
27
|
+
def self.root
|
|
28
|
+
"#{File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.create
|
|
32
|
+
CreateDB.up
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end # module SportDB::Play
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
## say hello
|
|
39
|
+
puts SportDB::Play.banner
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
## NB: just use namespace SportDB::Models (not SportDB::Models::Play)
|
|
3
|
+
|
|
4
|
+
module SportDB::Models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BonusPoint < ActiveRecord::Base
|
|
8
|
+
|
|
9
|
+
belongs_to :user
|
|
10
|
+
belongs_to :pool
|
|
11
|
+
belongs_to :round, :class_name => 'BonusRound', :foreign_key => 'round_id'
|
|
12
|
+
|
|
13
|
+
end # class BonusPoint
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
end # module SportDB::Models
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
## NB: just use namespace SportDB::Models (not SportDB::Models::Play)
|
|
3
|
+
|
|
4
|
+
module SportDB::Models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BonusQuestion < ActiveRecord::Base
|
|
8
|
+
|
|
9
|
+
self.table_name = 'bonus_questions'
|
|
10
|
+
|
|
11
|
+
has_many :tips, :class_name => 'BonusTip', :foreign_key => 'question_id'
|
|
12
|
+
|
|
13
|
+
end # class BonusQuestion
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
end # module SportDB::Models
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
## NB: just use namespace SportDB::Models (not SportDB::Models::Play)
|
|
3
|
+
|
|
4
|
+
module SportDB::Models
|
|
5
|
+
|
|
6
|
+
class BonusRound < ActiveRecord::Base
|
|
7
|
+
|
|
8
|
+
self.table_name = 'bonus_rounds'
|
|
9
|
+
|
|
10
|
+
has_many :questions, :order => 'pos', :class_name => 'BonusQuestion', :foreign_key => 'round_id'
|
|
11
|
+
belongs_to :pool
|
|
12
|
+
|
|
13
|
+
end # class BonusRound
|
|
14
|
+
|
|
15
|
+
end # module SportDB::Models
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
## NB: just use namespace SportDB::Models (not SportDB::Models::Play)
|
|
3
|
+
|
|
4
|
+
module SportDB::Models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class BonusTip < ActiveRecord::Base
|
|
8
|
+
|
|
9
|
+
self.table_name = 'bonus_tips'
|
|
10
|
+
|
|
11
|
+
belongs_to :user
|
|
12
|
+
|
|
13
|
+
end # class BonusTip
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
end # module SportDB::Models
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
module SportDB::Models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
### NB: extend Game model from sport.db gem
|
|
8
|
+
|
|
9
|
+
class Game
|
|
10
|
+
|
|
11
|
+
has_many :tips
|
|
12
|
+
|
|
13
|
+
##############
|
|
14
|
+
## move to sport.db gem ? why? why not?
|
|
15
|
+
|
|
16
|
+
def job_running!
|
|
17
|
+
@job_running = true
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def job_done!
|
|
21
|
+
@job_running = false
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def job_running?
|
|
25
|
+
(@job_running ||= false) == true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# move end
|
|
29
|
+
##########
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
###
|
|
33
|
+
## keep style helpers here? why? why not?
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def tip_1_style_class
|
|
37
|
+
toto12x == '1' ? ' bingo ' : ' '
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def tip_2_style_class
|
|
41
|
+
toto12x == '2' ? ' bingo ' : ' '
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def tip_x_style_class
|
|
45
|
+
toto12x == 'X' ? ' bingo ' : ' '
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
############ some methods for stats
|
|
50
|
+
|
|
51
|
+
def complete_tips
|
|
52
|
+
tips.where( 'toto12x is not null' )
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def complete_tips_1
|
|
56
|
+
tips.where( 'toto12x is not null' ).where( :toto12x => '1' ).order( 'score1 desc,score2 desc')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def complete_tips_2
|
|
60
|
+
tips.where( 'toto12x is not null' ).where( :toto12x => '2' ).order( 'score2 desc,score1 desc')
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def complete_tips_x
|
|
64
|
+
tips.where( 'toto12x is not null' ).where( :toto12x => 'X' ).order( 'score1 desc,score2 desc')
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def incomplete_tips
|
|
69
|
+
tips.where( 'toto12x is null' )
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def tip_1_count
|
|
73
|
+
complete_tips.where( :toto12x => '1' ).count()
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def tip_2_count
|
|
77
|
+
complete_tips.where( :toto12x => '2' ).count()
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def tip_x_count
|
|
81
|
+
complete_tips.where( :toto12x => 'X' ).count()
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def tip_12x_count
|
|
85
|
+
complete_tips.count()
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
end # class Game
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
end # module SportDB::Models
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
|
|
2
|
+
## NB: just use namespace SportDB::Models (not SportDB::Models::Play)
|
|
3
|
+
|
|
4
|
+
module SportDB::Models
|
|
5
|
+
|
|
6
|
+
class Play < ActiveRecord::Base
|
|
7
|
+
|
|
8
|
+
belongs_to :user
|
|
9
|
+
belongs_to :pool
|
|
10
|
+
|
|
11
|
+
belongs_to :team1, :class_name => 'Team', :foreign_key => 'team1_id'
|
|
12
|
+
belongs_to :team2, :class_name => 'Team', :foreign_key => 'team2_id'
|
|
13
|
+
belongs_to :team3, :class_name => 'Team', :foreign_key => 'team3_id'
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def job_running!
|
|
17
|
+
@job_running = true
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def job_done!
|
|
21
|
+
@job_running = false
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def job_running?
|
|
25
|
+
(@job_running ||= false) == true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def public?
|
|
29
|
+
return true if pool.public?
|
|
30
|
+
|
|
31
|
+
# team1, team2 public after kickoff of event
|
|
32
|
+
## use past?
|
|
33
|
+
Time.now.utc > pool.event.start_at.utc
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
## todo/fix: can it be done w/ a has_many macro and a condition?
|
|
38
|
+
def tips
|
|
39
|
+
recs = Tip.where( :pool_id => pool_id, :user_id => user_id ).all
|
|
40
|
+
recs
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
## todo/fix: can it be done w/ a has_many macro and a condition?
|
|
44
|
+
def complete_rankings # fix rename to points and remove points column from play table??
|
|
45
|
+
recs = Point.where( :pool_id => pool_id, :user_id => user_id ).joins( :round ).order('rounds.pos').all
|
|
46
|
+
recs
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def export?
|
|
50
|
+
# check if user entered some data
|
|
51
|
+
# - do NOT export nil records (all teams blank)
|
|
52
|
+
|
|
53
|
+
(team1_id.blank? && team2_id.blank? && team3_id.blank?)==false
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end # class Play
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
end # module SportDB::Models
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
## NB: just use namespace SportDB::Models (not SportDB::Models::Play)
|
|
4
|
+
|
|
5
|
+
module SportDB::Models
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Point < ActiveRecord::Base
|
|
9
|
+
|
|
10
|
+
belongs_to :user
|
|
11
|
+
belongs_to :pool
|
|
12
|
+
belongs_to :round
|
|
13
|
+
|
|
14
|
+
def round_pts_str
|
|
15
|
+
buf = ''
|
|
16
|
+
round_pts.times { buf << '♣' }
|
|
17
|
+
buf
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def total_pts_str
|
|
21
|
+
buf = ''
|
|
22
|
+
total_pts.times { buf << '♣' }
|
|
23
|
+
buf
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def diff_total_pos_style_class
|
|
28
|
+
if diff_total_pos > 0
|
|
29
|
+
' ranking-up '
|
|
30
|
+
elsif diff_total_pos < 0
|
|
31
|
+
' ranking-down '
|
|
32
|
+
else # == 0
|
|
33
|
+
' '
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def diff_total_pos_str
|
|
38
|
+
## todo: diff 2 use ⇑⇑
|
|
39
|
+
# diff 3 use ⇑⇑⇑
|
|
40
|
+
# diff 4 use ⇑⇑⇑⇑
|
|
41
|
+
# etc.
|
|
42
|
+
|
|
43
|
+
if diff_total_pos > 0
|
|
44
|
+
"⇑#{diff_total_pos}"
|
|
45
|
+
elsif diff_total_pos < 0
|
|
46
|
+
"⇓#{diff_total_pos.abs}"
|
|
47
|
+
else # == 0
|
|
48
|
+
""
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end # class Point
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
end # module SportDB::Models
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
## NB: just use namespace SportDB::Models (not SportDB::Models::Play)
|
|
4
|
+
|
|
5
|
+
module SportDB::Models
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Pool < ActiveRecord::Base
|
|
9
|
+
|
|
10
|
+
belongs_to :user # is owner/admin/manager
|
|
11
|
+
|
|
12
|
+
has_many :bonus_rounds
|
|
13
|
+
|
|
14
|
+
has_many :plays # pools_users join table
|
|
15
|
+
|
|
16
|
+
## rename to users from players??
|
|
17
|
+
has_many :players, :through => :plays, :source => :user
|
|
18
|
+
|
|
19
|
+
belongs_to :event
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def full_title
|
|
23
|
+
#### "#{title} #{event.title}#{fix? ? ' Fix' : ''}"
|
|
24
|
+
"#{title} #{event.title}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def team3? # tip for 3rd place?
|
|
29
|
+
event.team3 == true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end # class Pool
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
end # module SportDB::Models
|
|
36
|
+
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## NB: just use namespace SportDB::Models (not SportDB::Models::Play)
|
|
5
|
+
|
|
6
|
+
module SportDB::Models
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Tip < ActiveRecord::Base
|
|
10
|
+
|
|
11
|
+
belongs_to :user
|
|
12
|
+
belongs_to :pool
|
|
13
|
+
belongs_to :game
|
|
14
|
+
|
|
15
|
+
before_save :calc_toto12x
|
|
16
|
+
|
|
17
|
+
## todo: rename to find_by_play_and_game ????
|
|
18
|
+
def self.find_by_user_and_pool_and_game( user_arg, pool_arg, game_arg )
|
|
19
|
+
recs = self.where( :user_id => user_arg.id, :pool_id => pool_arg.id, :game_id => game_arg.id )
|
|
20
|
+
recs.first
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def export?
|
|
25
|
+
# check if user entered some data
|
|
26
|
+
# - do NOT export nil records (all scores blank)
|
|
27
|
+
|
|
28
|
+
(score1.blank? && score2.blank? && score3.blank? && score4.blank? && score5.blank? && score6.blank?)==false
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def calc_points_worker
|
|
33
|
+
pts = 0
|
|
34
|
+
|
|
35
|
+
if(((game.score1 == game.score2) && (score1 == score2)) ||
|
|
36
|
+
((game.score1 > game.score2) && (score1 > score2)) ||
|
|
37
|
+
((game.score1 < game.score2) && (score1 < score2)))
|
|
38
|
+
pts += 1
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# tordifferenz richtig? todo: auch fuer unentschieden???
|
|
42
|
+
if((game.score1-game.score2) == (score1-score2))
|
|
43
|
+
## nb: for now now points for tordifferenz
|
|
44
|
+
### pts +=1
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# ergebnis richtig?
|
|
48
|
+
if game.score1 == score1 && game.score2 == score2
|
|
49
|
+
pts += 2
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
## check n.V.
|
|
53
|
+
|
|
54
|
+
if (game.score3.present? && game.score4.present? && score3.present? && score4.present?)
|
|
55
|
+
|
|
56
|
+
if(((game.score3 == game.score4) && (score3 == score4)) ||
|
|
57
|
+
((game.score3 > game.score4) && (score3 > score4)) ||
|
|
58
|
+
((game.score3 < game.score4) && (score3 < score4)))
|
|
59
|
+
pts += 1
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
## check i.E.
|
|
64
|
+
|
|
65
|
+
if (game.score5.present? && game.score6.present? && score5.present? && score6.present?)
|
|
66
|
+
|
|
67
|
+
if(((game.score5 > game.score6) && (score5 > score6)) ||
|
|
68
|
+
((game.score5 < game.score6) && (score5 < score6)))
|
|
69
|
+
pts += 1
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
pts
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def calc_points
|
|
77
|
+
pts = 0
|
|
78
|
+
pts = calc_points_worker() if complete?
|
|
79
|
+
pts
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def calc_points_str
|
|
83
|
+
buf = ''
|
|
84
|
+
calc_points.times { buf << '♣' }
|
|
85
|
+
buf
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
## todo: use tip-fail, tip-bingo, etc.
|
|
90
|
+
|
|
91
|
+
def bingo_style_class
|
|
92
|
+
if incomplete?
|
|
93
|
+
# show missing label for upcoming games only
|
|
94
|
+
if game.over?
|
|
95
|
+
''
|
|
96
|
+
elsif score1.blank? || score2.blank?
|
|
97
|
+
'missing' # missing tip scores
|
|
98
|
+
else
|
|
99
|
+
'' # tip scores filled in; game scores not yet available
|
|
100
|
+
end
|
|
101
|
+
else
|
|
102
|
+
pts = calc_points()
|
|
103
|
+
if pts == 0
|
|
104
|
+
'fail'
|
|
105
|
+
elsif pts == 1
|
|
106
|
+
'bingo'
|
|
107
|
+
elsif pts == 2
|
|
108
|
+
'bingoo'
|
|
109
|
+
elsif pts == 3
|
|
110
|
+
'bingooo'
|
|
111
|
+
else
|
|
112
|
+
'' # unknown state; return empty (css) class
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# like bingo_style_class but only for pts>0 (that is not for fail)
|
|
118
|
+
def bingo_win_style_class
|
|
119
|
+
if incomplete?
|
|
120
|
+
# show missing label for upcoming games only
|
|
121
|
+
if game.over?
|
|
122
|
+
''
|
|
123
|
+
elsif score1.blank? || score2.blank?
|
|
124
|
+
'missing' # missing tip scores
|
|
125
|
+
else
|
|
126
|
+
'' # tip scores filled in; game scores not yet available
|
|
127
|
+
end
|
|
128
|
+
else
|
|
129
|
+
pts = calc_points()
|
|
130
|
+
if pts == 0
|
|
131
|
+
''
|
|
132
|
+
elsif pts == 1
|
|
133
|
+
'bingo'
|
|
134
|
+
elsif pts == 2
|
|
135
|
+
'bingoo'
|
|
136
|
+
elsif pts == 3
|
|
137
|
+
'bingooo'
|
|
138
|
+
else
|
|
139
|
+
'' # unknown state; return empty (css) class
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def bingo_text
|
|
145
|
+
if incomplete?
|
|
146
|
+
# show missing label for upcoming games only
|
|
147
|
+
if game.over?
|
|
148
|
+
''
|
|
149
|
+
elsif score1.blank? || score2.blank?
|
|
150
|
+
'?' # missing tip scores
|
|
151
|
+
else
|
|
152
|
+
'' # tip scores filled in; game scores not yet available
|
|
153
|
+
end
|
|
154
|
+
else
|
|
155
|
+
pts = calc_points()
|
|
156
|
+
if pts == 0
|
|
157
|
+
### FIX: - make extendable how?
|
|
158
|
+
### if game.calc? && (game.team1_id != calc_team1_id || game.team2_id != calc_team2_id )
|
|
159
|
+
## ## sorry, wrong teams - show team1 n team2 tags
|
|
160
|
+
## "× Leider, nein. Richtige Spielpaarung (#{game.team1.tag}) - (#{game.team2.tag})."
|
|
161
|
+
## else
|
|
162
|
+
"× Leider, nein. Richtiger Tipp #{game.toto12x}." # return 1,2,X from game
|
|
163
|
+
## end
|
|
164
|
+
elsif pts == 1
|
|
165
|
+
'♣ 1 Pkt - Ja!'
|
|
166
|
+
elsif pts == 2
|
|
167
|
+
'♣♣ 2 Pkte - Jaaa!'
|
|
168
|
+
elsif pts == 3
|
|
169
|
+
'♣♣♣ 3 Pkte - Jaaaaa!'
|
|
170
|
+
else
|
|
171
|
+
'' # unknown state; return empty (css) class
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def calc_toto12x
|
|
177
|
+
if score1.nil? || score2.nil?
|
|
178
|
+
self.toto12x = nil
|
|
179
|
+
elsif score1 == score2
|
|
180
|
+
self.toto12x = 'X'
|
|
181
|
+
elsif score1 > score2
|
|
182
|
+
self.toto12x = '1'
|
|
183
|
+
elsif score1 < score2
|
|
184
|
+
self.toto12x = '2'
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def complete?
|
|
190
|
+
game.score1.present? && game.score2.present? && score1.present? && score2.present?
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def incomplete?
|
|
194
|
+
complete? == false
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def locked?
|
|
198
|
+
### FIX: make extendable (pool.fix? only in addon??)
|
|
199
|
+
### return true if pool.fix? && pool.locked? # if fix pool is locked all games are (automatically) locked too
|
|
200
|
+
return true if pool.locked?
|
|
201
|
+
game.locked?
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def public?
|
|
205
|
+
return true if pool.public?
|
|
206
|
+
return true if locked? # if fix pool is locked or game (make tip public)
|
|
207
|
+
|
|
208
|
+
## todo: use builtin utc.past? method ???
|
|
209
|
+
Time.now.utc > game.play_at.utc
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def score_str
|
|
213
|
+
## fix: use new game.toto12x instead of game.over ??? (doesn't depend on time)
|
|
214
|
+
if score1.blank? && score2.blank? && game.over?
|
|
215
|
+
# return no data marker (e.g. middot) if not touched by user
|
|
216
|
+
'·'
|
|
217
|
+
else
|
|
218
|
+
str = ''
|
|
219
|
+
if score5.present? && score6.present? # im Elfmeterschiessen i.E.?
|
|
220
|
+
str = "#{score1_str} : #{score2_str} / #{score3} : #{score4} n.V. / #{score5} : #{score6} i.E."
|
|
221
|
+
elsif score3.present? && score4.present? # nach Verlaengerung n.V.?
|
|
222
|
+
str = "#{score1_str} : #{score2_str} / #{score3} : #{score4} n.V."
|
|
223
|
+
else
|
|
224
|
+
str = "#{score1_str} : #{score2_str}"
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
##### FIX: make extendable!!
|
|
228
|
+
# if calc
|
|
229
|
+
# str_calc_team1 = calc_team1_id.blank? ? '' : calc_team1.tag
|
|
230
|
+
# str_calc_team2 = calc_team2_id.blank? ? '' : calc_team2.tag
|
|
231
|
+
# str = "(#{str_calc_team1}) #{str} (#{str_calc_team2})"
|
|
232
|
+
# end
|
|
233
|
+
str
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def score1_str
|
|
238
|
+
if score1.blank? then '?' else score1.to_s end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def score2_str
|
|
242
|
+
if score2.blank? then '?' else score2.to_s end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
end # class Tip
|
|
246
|
+
|
|
247
|
+
end # module SportDB::Models
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## NB: just use namespace SportDB::Models (not SportDB::Models::Play)
|
|
5
|
+
|
|
6
|
+
module SportDB::Models
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class User < ActiveRecord::Base
|
|
10
|
+
|
|
11
|
+
has_many :pools
|
|
12
|
+
has_many :tips
|
|
13
|
+
has_many :plays
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
end # class User
|
|
17
|
+
|
|
18
|
+
end # module SportDB::Models
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
module SportDB::Play
|
|
2
|
+
|
|
3
|
+
class CreateDB
|
|
4
|
+
|
|
5
|
+
## make models available in sportdb module by default with namespace
|
|
6
|
+
# e.g. lets you use Team instead of Models::Team
|
|
7
|
+
include SportDB::Models
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def self.up
|
|
11
|
+
|
|
12
|
+
ActiveRecord::Schema.define do
|
|
13
|
+
|
|
14
|
+
change_table :games do |t|
|
|
15
|
+
t.boolean :locked, :null => false, :default => false
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
#####################################
|
|
19
|
+
## new tables / create tables
|
|
20
|
+
####################################
|
|
21
|
+
|
|
22
|
+
create_table :users do |t|
|
|
23
|
+
t.string :key, :null => false # import/export key
|
|
24
|
+
t.timestamps
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
add_index :users, :key, :unique => true
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
create_table :pools do |t|
|
|
31
|
+
t.references :event, :null => false
|
|
32
|
+
t.string :title, :null => false
|
|
33
|
+
t.references :user, :null => false # owner/manager/admin of pool
|
|
34
|
+
t.boolean :public, :null => false, :default => true # make all tips public (not private/secret)
|
|
35
|
+
t.boolean :locked, :null => false, :default => false
|
|
36
|
+
t.string :key # import/export key
|
|
37
|
+
t.timestamps
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
add_index :pools, :key, :unique => true
|
|
41
|
+
add_index :pools, :event_id
|
|
42
|
+
add_index :pools, :user_id
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
create_table :plays do |t|
|
|
46
|
+
t.references :user, :null => false
|
|
47
|
+
t.references :pool, :null => false
|
|
48
|
+
t.references :team1 # winner (1st)
|
|
49
|
+
t.references :team2 # runnerup (2nd)
|
|
50
|
+
t.references :team3 # 2n runnerup (3nd)
|
|
51
|
+
|
|
52
|
+
t.integer :total_pts, :null => false, :default => 0 # cached total player points
|
|
53
|
+
t.integer :total_pos, :null => false, :default => 0 # cached total ranking/position
|
|
54
|
+
|
|
55
|
+
t.timestamps
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
add_index :plays, [:user_id,:pool_id], :unique => true # enforce only one play per user and pool
|
|
59
|
+
add_index :plays, :user_id
|
|
60
|
+
add_index :plays, :pool_id
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
create_table :tips do |t|
|
|
64
|
+
t.references :user, :null => false
|
|
65
|
+
t.references :pool, :null => false
|
|
66
|
+
t.references :game, :null => false
|
|
67
|
+
t.integer :score1
|
|
68
|
+
t.integer :score2
|
|
69
|
+
t.integer :score3 # verlaengerung (opt)
|
|
70
|
+
t.integer :score4
|
|
71
|
+
t.integer :score5 # elfmeter (opt)
|
|
72
|
+
t.integer :score6
|
|
73
|
+
t.string :toto12x # 1,2,X,nil calculate on save
|
|
74
|
+
|
|
75
|
+
t.timestamps
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
add_index :tips, [:user_id,:pool_id,:game_id], :unique => true
|
|
79
|
+
add_index :tips, :user_id
|
|
80
|
+
add_index :tips, :pool_id
|
|
81
|
+
add_index :tips, :game_id
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
create_table :points do |t|
|
|
86
|
+
t.references :user, :null => false
|
|
87
|
+
t.references :pool, :null => false
|
|
88
|
+
t.references :round, :null => false
|
|
89
|
+
|
|
90
|
+
t.integer :round_pts, :null => false, :default => 0 # points for this round
|
|
91
|
+
t.integer :round_pos, :null => false, :default => 0 # ranking/position for this round
|
|
92
|
+
|
|
93
|
+
t.integer :total_pts, :null => false, :default => 0 # total points up to(*) this round (including) (* rounds sorted by pos)
|
|
94
|
+
t.integer :total_pos, :null => false, :default => 0 # ranking/position for points up to this round
|
|
95
|
+
|
|
96
|
+
t.integer :diff_total_pos, :null => false, :default => 0
|
|
97
|
+
|
|
98
|
+
t.timestamps
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
add_index :points, [:user_id,:pool_id,:round_id], :unique => true
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
create_table :bonus_rounds do |t|
|
|
106
|
+
t.references :pool, :null => false
|
|
107
|
+
t.string :title, :null => false
|
|
108
|
+
t.integer :pos, :null => false
|
|
109
|
+
t.timestamps
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
create_table :bonus_questions do |t|
|
|
113
|
+
t.references :round, :null => false
|
|
114
|
+
t.string :title, :null => false
|
|
115
|
+
t.integer :pos, :null => false
|
|
116
|
+
t.timestamps
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
create_table :bonus_answers do |t|
|
|
120
|
+
# to be done
|
|
121
|
+
t.timestamps
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
create_table :bonus_tips do |t|
|
|
125
|
+
t.references :user, :null => false
|
|
126
|
+
t.references :question, :null => false
|
|
127
|
+
t.integer :pts , :null => false, :default => 0
|
|
128
|
+
t.timestamps
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
create_table :bonus_points do |t|
|
|
132
|
+
t.references :user, :null => false
|
|
133
|
+
t.references :pool, :null => false ## todo: check if we keep reference to pool (because round_id depends itself on pool)
|
|
134
|
+
t.references :round, :null => false # nb: is bonus_round_id
|
|
135
|
+
|
|
136
|
+
t.integer :round_pts, :null => false, :default => 0 # points for this round
|
|
137
|
+
t.integer :round_pos, :null => false, :default => 0 # ranking/position for this round
|
|
138
|
+
|
|
139
|
+
t.integer :total_pts, :null => false, :default => 0 # total points up to(*) this round (including) (* rounds sorted by pos)
|
|
140
|
+
t.integer :total_pos, :null => false, :default => 0 # ranking/position for points up to this round
|
|
141
|
+
|
|
142
|
+
t.integer :diff_total_pos, :null => false, :default => 0
|
|
143
|
+
|
|
144
|
+
t.timestamps
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
add_index :bonus_points, [:user_id,:pool_id,:round_id], :unique => true
|
|
148
|
+
|
|
149
|
+
end # block Schema.define
|
|
150
|
+
|
|
151
|
+
Prop.create!( key: 'db.schema.sport.play.version', value: SportDB::Play::VERSION )
|
|
152
|
+
|
|
153
|
+
end # method self.up
|
|
154
|
+
|
|
155
|
+
end # class CreateDB
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
end # module SportDB::Play
|
metadata
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: sportdb-play
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
hash: 27
|
|
5
|
+
prerelease:
|
|
6
|
+
segments:
|
|
7
|
+
- 0
|
|
8
|
+
- 1
|
|
9
|
+
- 0
|
|
10
|
+
version: 0.1.0
|
|
11
|
+
platform: ruby
|
|
12
|
+
authors:
|
|
13
|
+
- Gerald Bauer
|
|
14
|
+
autorequire:
|
|
15
|
+
bindir: bin
|
|
16
|
+
cert_chain: []
|
|
17
|
+
|
|
18
|
+
date: 2012-12-03 00:00:00 Z
|
|
19
|
+
dependencies:
|
|
20
|
+
- !ruby/object:Gem::Dependency
|
|
21
|
+
name: rdoc
|
|
22
|
+
prerelease: false
|
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
24
|
+
none: false
|
|
25
|
+
requirements:
|
|
26
|
+
- - ~>
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
hash: 19
|
|
29
|
+
segments:
|
|
30
|
+
- 3
|
|
31
|
+
- 10
|
|
32
|
+
version: "3.10"
|
|
33
|
+
type: :development
|
|
34
|
+
version_requirements: *id001
|
|
35
|
+
- !ruby/object:Gem::Dependency
|
|
36
|
+
name: hoe
|
|
37
|
+
prerelease: false
|
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
39
|
+
none: false
|
|
40
|
+
requirements:
|
|
41
|
+
- - ~>
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
hash: 1
|
|
44
|
+
segments:
|
|
45
|
+
- 3
|
|
46
|
+
- 3
|
|
47
|
+
version: "3.3"
|
|
48
|
+
type: :development
|
|
49
|
+
version_requirements: *id002
|
|
50
|
+
description: sportdb plugin for plays (predictions, betting pool, etc.)
|
|
51
|
+
email: opensport@googlegroups.com
|
|
52
|
+
executables: []
|
|
53
|
+
|
|
54
|
+
extensions: []
|
|
55
|
+
|
|
56
|
+
extra_rdoc_files:
|
|
57
|
+
- Manifest.txt
|
|
58
|
+
files:
|
|
59
|
+
- History.md
|
|
60
|
+
- Manifest.txt
|
|
61
|
+
- README.md
|
|
62
|
+
- Rakefile
|
|
63
|
+
- lib/sportdb/play.rb
|
|
64
|
+
- lib/sportdb/play/models/bonus_point.rb
|
|
65
|
+
- lib/sportdb/play/models/bonus_question.rb
|
|
66
|
+
- lib/sportdb/play/models/bonus_round.rb
|
|
67
|
+
- lib/sportdb/play/models/bonus_tip.rb
|
|
68
|
+
- lib/sportdb/play/models/game.rb
|
|
69
|
+
- lib/sportdb/play/models/play.rb
|
|
70
|
+
- lib/sportdb/play/models/point.rb
|
|
71
|
+
- lib/sportdb/play/models/pool.rb
|
|
72
|
+
- lib/sportdb/play/models/tip.rb
|
|
73
|
+
- lib/sportdb/play/models/user.rb
|
|
74
|
+
- lib/sportdb/play/schema.rb
|
|
75
|
+
- lib/sportdb/play/version.rb
|
|
76
|
+
homepage: http://geraldb.github.com/sport.db
|
|
77
|
+
licenses:
|
|
78
|
+
- Public Domain
|
|
79
|
+
post_install_message:
|
|
80
|
+
rdoc_options:
|
|
81
|
+
- --main
|
|
82
|
+
- README.md
|
|
83
|
+
require_paths:
|
|
84
|
+
- lib
|
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
86
|
+
none: false
|
|
87
|
+
requirements:
|
|
88
|
+
- - ">="
|
|
89
|
+
- !ruby/object:Gem::Version
|
|
90
|
+
hash: 55
|
|
91
|
+
segments:
|
|
92
|
+
- 1
|
|
93
|
+
- 9
|
|
94
|
+
- 2
|
|
95
|
+
version: 1.9.2
|
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
97
|
+
none: false
|
|
98
|
+
requirements:
|
|
99
|
+
- - ">="
|
|
100
|
+
- !ruby/object:Gem::Version
|
|
101
|
+
hash: 3
|
|
102
|
+
segments:
|
|
103
|
+
- 0
|
|
104
|
+
version: "0"
|
|
105
|
+
requirements: []
|
|
106
|
+
|
|
107
|
+
rubyforge_project: sportdb-play
|
|
108
|
+
rubygems_version: 1.8.24
|
|
109
|
+
signing_key:
|
|
110
|
+
specification_version: 3
|
|
111
|
+
summary: sportdb plugin for plays (predictions, betting pool, etc.)
|
|
112
|
+
test_files: []
|
|
113
|
+
|