sportdb-models 1.19.1 → 2.0.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.
- checksums.yaml +4 -4
- data/Manifest.txt +27 -38
- data/Rakefile +1 -1
- data/lib/sportdb/models.rb +55 -49
- data/lib/sportdb/{deleter.rb → models/deleter.rb} +3 -9
- data/lib/sportdb/models/formats.rb +23 -0
- data/lib/sportdb/models/models/assoc.rb +38 -0
- data/lib/sportdb/models/{badge.rb → models/badge.rb} +1 -1
- data/lib/sportdb/models/models/event.rb +55 -0
- data/lib/sportdb/models/{forward.rb → models/forward.rb} +3 -3
- data/lib/sportdb/models/{goal.rb → models/goal.rb} +1 -1
- data/lib/sportdb/models/models/ground.rb +16 -0
- data/lib/sportdb/models/{group.rb → models/group.rb} +10 -7
- data/lib/sportdb/models/models/league.rb +20 -0
- data/lib/sportdb/models/{roster.rb → models/lineup.rb} +3 -4
- data/lib/sportdb/models/{game.rb → models/match.rb} +16 -60
- data/lib/sportdb/models/{person.rb → models/person.rb} +0 -0
- data/lib/sportdb/models/{round.rb → models/round.rb} +1 -6
- data/lib/sportdb/models/{season.rb → models/season.rb} +0 -0
- data/lib/sportdb/models/{stage.rb → models/stage.rb} +9 -5
- data/lib/sportdb/models/{stats/alltime_standing_entry.rb → models/stats/alltime_standing.rb} +9 -1
- data/lib/sportdb/models/{stats/event_standing_entry.rb → models/stats/event_standing.rb} +11 -1
- data/lib/sportdb/models/{stats/group_standing_entry.rb → models/stats/group_standing.rb} +10 -1
- data/lib/sportdb/models/models/team.rb +56 -0
- data/lib/sportdb/models/{world → models/world}/city.rb +2 -2
- data/lib/sportdb/models/{world → models/world}/continent.rb +0 -0
- data/lib/sportdb/models/{world → models/world}/country.rb +0 -0
- data/lib/sportdb/models/{world → models/world}/state.rb +0 -0
- data/lib/sportdb/{schema.rb → models/schema.rb} +98 -74
- data/lib/sportdb/{stats.rb → models/stats.rb} +4 -4
- data/lib/sportdb/models/utils.rb +24 -24
- data/lib/sportdb/{version.rb → models/version.rb} +4 -4
- data/test/helper.rb +10 -6
- data/test/test_changes.rb +38 -38
- data/test/test_cursor.rb +15 -15
- data/test/test_winner.rb +75 -70
- metadata +29 -40
- data/lib/sportdb/calc.rb +0 -279
- data/lib/sportdb/models/assoc.rb +0 -106
- data/lib/sportdb/models/assoc_assoc.rb +0 -15
- data/lib/sportdb/models/event.rb +0 -66
- data/lib/sportdb/models/event_ground.rb +0 -15
- data/lib/sportdb/models/event_team.rb +0 -16
- data/lib/sportdb/models/ground.rb +0 -100
- data/lib/sportdb/models/group_team.rb +0 -14
- data/lib/sportdb/models/league.rb +0 -83
- data/lib/sportdb/models/stage_team.rb +0 -14
- data/lib/sportdb/models/stats/alltime_standing.rb +0 -44
- data/lib/sportdb/models/stats/event_standing.rb +0 -55
- data/lib/sportdb/models/stats/group_standing.rb +0 -50
- data/lib/sportdb/models/team.rb +0 -119
- data/lib/sportdb/models/team_compat.rb +0 -64
- data/lib/sportdb/patterns.rb +0 -37
- data/lib/sportdb/standings.rb +0 -178
data/lib/sportdb/models/team.rb
DELETED
@@ -1,119 +0,0 @@
|
|
1
|
-
|
2
|
-
module SportDb
|
3
|
-
module Model
|
4
|
-
|
5
|
-
##################
|
6
|
-
# FIX: add ?
|
7
|
-
#
|
8
|
-
# use single table inheritance STI ????
|
9
|
-
# - to mark two dervided classes e.g.
|
10
|
-
# - Club ??? - why? why not?
|
11
|
-
# - NationalTeam ??? - why? why not?
|
12
|
-
|
13
|
-
|
14
|
-
class Team < ActiveRecord::Base
|
15
|
-
|
16
|
-
has_many :home_games, class_name: 'Game', foreign_key: 'team1_id'
|
17
|
-
has_many :away_games, class_name: 'Game', foreign_key: 'team2_id'
|
18
|
-
|
19
|
-
## todo/fix: must be 3 or more letters (plus allow digits e.g. salzburgii, muenchen1980, etc.) - why? why not??
|
20
|
-
validates :key, format: { with: /#{TEAM_KEY_PATTERN}/, message: TEAM_KEY_PATTERN_MESSAGE }
|
21
|
-
validates :code, format: { with: /#{TEAM_CODE_PATTERN}/, message: TEAM_CODE_PATTERN_MESSAGE }, allow_nil: true
|
22
|
-
|
23
|
-
has_many :event_teams, class_name: 'EventTeam' # join table (events+teams)
|
24
|
-
has_many :events, :through => :event_teams
|
25
|
-
|
26
|
-
# note: team belongs_to a single (optinal) assoc for now (national assoc may have many assocs)
|
27
|
-
belongs_to :assoc
|
28
|
-
|
29
|
-
### fix!!! - how to do it with has_many macro? use finder_sql?
|
30
|
-
## finder_sql is depreciated in Rails 4!!!
|
31
|
-
# use -> { where() } etc. -- try it if it works
|
32
|
-
## keep as is! best solution ??
|
33
|
-
## a discussion here -> https://github.com/rails/rails/issues/9726
|
34
|
-
## a discussion here (not really helpful) -> http://stackoverflow.com/questions/2125440/activerecord-has-many-where-two-columns-in-table-a-are-primary-keys-in-table-b
|
35
|
-
|
36
|
-
def games
|
37
|
-
Game.where( 'team1_id = ? or team2_id = ?', id, id ).order( 'play_at' )
|
38
|
-
end
|
39
|
-
|
40
|
-
def upcoming_games
|
41
|
-
Game.where( 'team1_id = ? or team2_id = ?', id, id ).where( 'play_at > ?', Time.now ).order( 'play_at' )
|
42
|
-
end
|
43
|
-
|
44
|
-
def past_games
|
45
|
-
Game.where( 'team1_id = ? or team2_id = ?', id, id ).where( 'play_at < ?', Time.now ).order( 'play_at desc' )
|
46
|
-
end
|
47
|
-
|
48
|
-
|
49
|
-
has_many :badges # Winner, 2nd, Cupsieger, Aufsteiger, Absteiger, etc.
|
50
|
-
|
51
|
-
belongs_to :country, class_name: 'WorldDb::Model::Country', foreign_key: 'country_id'
|
52
|
-
belongs_to :city, class_name: 'WorldDb::Model::City', foreign_key: 'city_id'
|
53
|
-
|
54
|
-
|
55
|
-
## fix/todo: change title to name; title2 to name2 etc.
|
56
|
-
def name() title; end
|
57
|
-
|
58
|
-
|
59
|
-
def self.create_or_update_from_values( new_attributes, values )
|
60
|
-
|
61
|
-
## fix: add/configure logger for ActiveRecord!!!
|
62
|
-
logger = LogUtils::Logger.root
|
63
|
-
|
64
|
-
|
65
|
-
## check optional values
|
66
|
-
values.each_with_index do |value, index|
|
67
|
-
if value =~ /^city:/ ## city:
|
68
|
-
value_city_key = value[5..-1] ## cut off city: prefix
|
69
|
-
value_city = City.find_by_key( value_city_key )
|
70
|
-
if value_city.present?
|
71
|
-
new_attributes[ :city_id ] = value_city.id
|
72
|
-
else
|
73
|
-
## todo/fix: add strict mode flag - fail w/ exit 1 in strict mode
|
74
|
-
logger.warn "city with key #{value_city_key} missing"
|
75
|
-
## todo: log errors to db log???
|
76
|
-
end
|
77
|
-
elsif value =~ /^(18|19|20)[0-9]{2}$/ ## assume founding year -- allow 18|19|20
|
78
|
-
## logger.info " founding/opening year #{value}"
|
79
|
-
new_attributes[ :since ] = value.to_i
|
80
|
-
elsif value =~ /\/{2}/ # assume it's an address line e.g. xx // xx
|
81
|
-
## logger.info " found address line #{value}"
|
82
|
-
new_attributes[ :address ] = value
|
83
|
-
elsif value =~ /^(?:[a-z]{2}\.)?wikipedia:/ # assume it's wikipedia e.g. [es.]wikipedia:
|
84
|
-
logger.info " found wikipedia line #{value}; skipping for now"
|
85
|
-
elsif value =~ /(^www\.)|(\.com$)/ # FIX: !!!! use a better matcher not just www. and .com
|
86
|
-
new_attributes[ :web ] = value
|
87
|
-
elsif value =~ /^[A-Z][A-Z0-9][A-Z0-9_]?$/ ## assume two or three-letter code e.g. FCB, RBS, etc.
|
88
|
-
new_attributes[ :code ] = value
|
89
|
-
elsif value =~ /^[a-z]{2,3}$/ ## assume two or three-letter country key e.g. at,de,mx, or eng,sco,wal,nir etc.
|
90
|
-
## fix: if country does NOT match / NOT found - just continue w/ next match!!!!
|
91
|
-
# - just issue an error/warn do NOT crash
|
92
|
-
value_country = Country.find_by_key!( value )
|
93
|
-
new_attributes[ :country_id ] = value_country.id
|
94
|
-
else
|
95
|
-
## todo: assume title2 ??
|
96
|
-
# issue warning: unknown type for value
|
97
|
-
logger.warn "unknown type for value >#{value}< - key #{new_attributes[:key]}"
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
rec = Team.find_by_key( new_attributes[ :key ] )
|
102
|
-
if rec.present?
|
103
|
-
logger.debug "update Team #{rec.id}-#{rec.key}:"
|
104
|
-
else
|
105
|
-
logger.debug "create Team:"
|
106
|
-
rec = Team.new
|
107
|
-
end
|
108
|
-
|
109
|
-
logger.debug new_attributes.to_json
|
110
|
-
|
111
|
-
rec.update_attributes!( new_attributes )
|
112
|
-
|
113
|
-
end # create_or_update_from_values
|
114
|
-
|
115
|
-
end # class Team
|
116
|
-
|
117
|
-
|
118
|
-
end # module Model
|
119
|
-
end # module SportDb
|
@@ -1,64 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module SportDb
|
4
|
-
module Model
|
5
|
-
|
6
|
-
#############################################################
|
7
|
-
# collect depreciated or methods for future removal here
|
8
|
-
# - keep for now for compatibility (for old code)
|
9
|
-
|
10
|
-
class Team
|
11
|
-
|
12
|
-
|
13
|
-
def self.create_from_ary!( teams, more_values={} )
|
14
|
-
teams.each do |values|
|
15
|
-
|
16
|
-
## key & title required
|
17
|
-
attr = {
|
18
|
-
key: values[0]
|
19
|
-
}
|
20
|
-
|
21
|
-
## title (split of optional synonyms)
|
22
|
-
# e.g. FC Bayern Muenchen|Bayern Muenchen|Bayern
|
23
|
-
titles = values[1].split('|')
|
24
|
-
|
25
|
-
attr[ :title ] = titles[0]
|
26
|
-
## add optional synonyms
|
27
|
-
attr[ :synonyms ] = titles[1..-1].join('|') if titles.size > 1
|
28
|
-
|
29
|
-
|
30
|
-
attr = attr.merge( more_values )
|
31
|
-
|
32
|
-
## check for optional values
|
33
|
-
values[2..-1].each do |value|
|
34
|
-
if value.is_a? Country
|
35
|
-
attr[ :country_id ] = value.id
|
36
|
-
elsif value.is_a? City
|
37
|
-
attr[ :city_id ] = value.id
|
38
|
-
elsif value =~ /#{TEAM_CODE_PATTERN}/ ## assume its three letter code (e.g. ITA or S04 etc.)
|
39
|
-
attr[ :code ] = value
|
40
|
-
elsif value =~ /^city:/ ## city:
|
41
|
-
value_city_key = value[5..-1] ## cut off city: prefix
|
42
|
-
value_city = City.find_by_key!( value_city_key )
|
43
|
-
attr[ :city_id ] = value_city.id
|
44
|
-
else
|
45
|
-
attr[ :title2 ] = value
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
## check if exists
|
50
|
-
team = Team.find_by_key( values[0] )
|
51
|
-
if team.present?
|
52
|
-
puts "*** warning team with key '#{values[0]}' exists; skipping create"
|
53
|
-
else
|
54
|
-
Team.create!( attr )
|
55
|
-
end
|
56
|
-
end # each team
|
57
|
-
end
|
58
|
-
|
59
|
-
end # class Team
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end # module Model
|
64
|
-
end # module SportDb
|
data/lib/sportdb/patterns.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
module SportDb
|
4
|
-
|
5
|
-
# collection of regex patterns for reuse (SportDb specific)
|
6
|
-
|
7
|
-
### todo: add a patterns.md page to github ??
|
8
|
-
## - add regexper pics??
|
9
|
-
|
10
|
-
############
|
11
|
-
# about ruby regexps
|
12
|
-
#
|
13
|
-
# try the rubular - Ruby regular expression editor and tester
|
14
|
-
# -> http://rubular.com
|
15
|
-
# code -> ?? by ??
|
16
|
-
#
|
17
|
-
#
|
18
|
-
# Jeff Avallone's Regexper - Shows State-Automata Diagrams
|
19
|
-
# try -> http://regexper.com
|
20
|
-
# code -> https://github.com/javallone/regexper
|
21
|
-
#
|
22
|
-
#
|
23
|
-
# Regular Expressions | The Bastards Book of Ruby by Dan Nguyen
|
24
|
-
# http://ruby.bastardsbook.com/chapters/regexes/
|
25
|
-
#
|
26
|
-
# move to notes regex|patterns on geraldb.github.io ??
|
27
|
-
#
|
28
|
-
|
29
|
-
TEAM_KEY_PATTERN = '\A[a-z]{3,}\z'
|
30
|
-
TEAM_KEY_PATTERN_MESSAGE = "expected three or more lowercase letters a-z /#{TEAM_KEY_PATTERN}/"
|
31
|
-
|
32
|
-
# must start w/ letter A-Z (2nd,3rd,4th or 5th can be number or underscore _)
|
33
|
-
TEAM_CODE_PATTERN = '\A[A-Z_][A-Z0-9_]{1,4}\z'
|
34
|
-
TEAM_CODE_PATTERN_MESSAGE = "expected two or three or four or five uppercase letters A-Z (and 0-9_; must start with A-Z) /#{TEAM_CODE_PATTERN}/"
|
35
|
-
|
36
|
-
|
37
|
-
end # module SportDb
|
data/lib/sportdb/standings.rb
DELETED
@@ -1,178 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
|
4
|
-
##############
|
5
|
-
##
|
6
|
-
## fix/todo:
|
7
|
-
## - reuse in footballcsv/build e.g. require sportdb and remove "old" code!!!!
|
8
|
-
|
9
|
-
module SportDb
|
10
|
-
|
11
|
-
|
12
|
-
class StandingsLine
|
13
|
-
attr_accessor :rank, :team_name,
|
14
|
-
:played, :won, :lost, :drawn, ## -- total
|
15
|
-
:goals_for, :goals_against, :pts,
|
16
|
-
:home_played, :home_won, :home_lost, :home_drawn, ## -- home
|
17
|
-
:home_goals_for, :home_goals_against, :home_pts,
|
18
|
-
:away_played, :away_won, :away_lost, :away_drawn, ## -- away
|
19
|
-
:away_goals_for, :away_goals_against, :away_pts
|
20
|
-
|
21
|
-
def initialize( team_name )
|
22
|
-
@rank = nil # use 0? why? why not?
|
23
|
-
@team_name = team_name
|
24
|
-
@played = @home_played = @away_played = 0
|
25
|
-
@won = @home_won = @away_won = 0
|
26
|
-
@lost = @home_lost = @away_lost = 0
|
27
|
-
@drawn = @home_drawn = @away_drawn = 0
|
28
|
-
@goals_for = @home_goals_for = @away_goals_for = 0
|
29
|
-
@goals_against = @home_goals_against = @away_goals_against = 0
|
30
|
-
@pts = @home_pts = @away_pts = 0
|
31
|
-
|
32
|
-
### fix: add @recs too - to count number of records (e.g. appearances/seasons etc.)
|
33
|
-
end
|
34
|
-
end # class StandingsLine
|
35
|
-
|
36
|
-
|
37
|
-
class Standings
|
38
|
-
|
39
|
-
def initialize( opts={} )
|
40
|
-
## fix:
|
41
|
-
# passing in e.g. pts for win (3? 2? etc.)
|
42
|
-
# default to 3 for now
|
43
|
-
|
44
|
-
## lets you pass in 2 as an alterantive, for example
|
45
|
-
@pts_won = opts[:pts_won] || 3
|
46
|
-
|
47
|
-
@lines = {} # StandingsLines cached by team name/key
|
48
|
-
end
|
49
|
-
|
50
|
-
|
51
|
-
def update( match_or_matches )
|
52
|
-
puts " [debug] update match_or_matches.class.name: #{match_or_matches.class.name}"
|
53
|
-
|
54
|
-
## convenience - update all matches at once
|
55
|
-
if match_or_matches.is_a?( Array ) ||
|
56
|
-
match_or_matches.is_a?( ActiveRecord::Associations::CollectionProxy )
|
57
|
-
matches = match_or_matches
|
58
|
-
matches.each_with_index do |match,i| # note: index(i) starts w/ zero (0)
|
59
|
-
update_match( match )
|
60
|
-
end
|
61
|
-
else
|
62
|
-
match = match_or_matches
|
63
|
-
update_match( match )
|
64
|
-
end
|
65
|
-
self # note: return self to allow chaining
|
66
|
-
end
|
67
|
-
|
68
|
-
def to_a
|
69
|
-
## return lines; sort and add rank
|
70
|
-
## note: will update rank!!!! (side effect)
|
71
|
-
|
72
|
-
#############################
|
73
|
-
### calc ranking position (rank)
|
74
|
-
## fix/allow same rank e.g. all 1 or more than one team 3rd etc.
|
75
|
-
|
76
|
-
# build array from hash
|
77
|
-
ary = []
|
78
|
-
@lines.each do |k,v|
|
79
|
-
ary << v
|
80
|
-
end
|
81
|
-
|
82
|
-
ary.sort! do |l,r|
|
83
|
-
## note: reverse order (thus, change l,r to r,l)
|
84
|
-
value = r.pts <=> l.pts
|
85
|
-
if value == 0 # same pts try goal diff
|
86
|
-
value = (r.goals_for-r.goals_against) <=> (l.goals_for-l.goals_against)
|
87
|
-
if value == 0 # same goal diff too; try assume more goals better for now
|
88
|
-
value = r.goals_for <=> l.goals_for
|
89
|
-
end
|
90
|
-
end
|
91
|
-
value
|
92
|
-
end
|
93
|
-
|
94
|
-
## update rank using ordered array
|
95
|
-
ary.each_with_index do |line,i|
|
96
|
-
line.rank = i+1 ## add ranking (e.g. 1,2,3 etc.) - note: i starts w/ zero (0)
|
97
|
-
end
|
98
|
-
|
99
|
-
ary
|
100
|
-
end # to_a
|
101
|
-
|
102
|
-
|
103
|
-
private
|
104
|
-
def update_match( m ) ## add a match
|
105
|
-
|
106
|
-
## puts " #{m.team1} - #{m.team2} #{m.score_str}"
|
107
|
-
unless m.over?
|
108
|
-
puts " !!!! skipping match - not yet over (play_at date in the future)"
|
109
|
-
return
|
110
|
-
end
|
111
|
-
|
112
|
-
unless m.complete?
|
113
|
-
puts "!!! [calc_standings] skipping match #{m.team1_name} - #{m.team2_name} - scores incomplete #{m.score_str}"
|
114
|
-
return
|
115
|
-
end
|
116
|
-
|
117
|
-
### fix/todo: use team1_name n team2_name ???
|
118
|
-
### fix/todo: - add extra time and penalty shootout !!!!
|
119
|
-
|
120
|
-
line1 = @lines[ m.team1_name ] || StandingsLine.new( m.team1_name )
|
121
|
-
line2 = @lines[ m.team2_name ] || StandingsLine.new( m.team2_name )
|
122
|
-
|
123
|
-
line1.played += 1
|
124
|
-
line1.home_played += 1
|
125
|
-
|
126
|
-
line2.played += 1
|
127
|
-
line2.away_played += 1
|
128
|
-
|
129
|
-
if m.winner == 1
|
130
|
-
line1.won += 1
|
131
|
-
line1.home_won += 1
|
132
|
-
|
133
|
-
line2.lost += 1
|
134
|
-
line2.away_lost += 1
|
135
|
-
|
136
|
-
line1.pts += @pts_won
|
137
|
-
line1.home_pts += @pts_won
|
138
|
-
elsif m.winner == 2
|
139
|
-
line1.lost += 1
|
140
|
-
line1.home_lost += 1
|
141
|
-
|
142
|
-
line2.won += 1
|
143
|
-
line2.away_won += 1
|
144
|
-
|
145
|
-
line2.pts += @pts_won
|
146
|
-
line2.away_pts += @pts_won
|
147
|
-
else ## assume drawn/tie (that is, 0)
|
148
|
-
line1.drawn += 1
|
149
|
-
line1.home_drawn += 1
|
150
|
-
|
151
|
-
line2.drawn += 1
|
152
|
-
line2.away_drawn += 1
|
153
|
-
|
154
|
-
line1.pts += 1
|
155
|
-
line1.home_pts += 1
|
156
|
-
line2.pts += 1
|
157
|
-
line2.away_pts += 1
|
158
|
-
end
|
159
|
-
|
160
|
-
line1.goals_for += m.score1
|
161
|
-
line1.home_goals_for += m.score1
|
162
|
-
line1.goals_against += m.score2
|
163
|
-
line1.home_goals_against += m.score2
|
164
|
-
|
165
|
-
line2.goals_for += m.score2
|
166
|
-
line2.away_goals_for += m.score2
|
167
|
-
line2.goals_against += m.score1
|
168
|
-
line2.away_goals_against += m.score1
|
169
|
-
|
170
|
-
@lines[ m.team1_name ] = line1
|
171
|
-
@lines[ m.team2_name ] = line2
|
172
|
-
end # method update_match
|
173
|
-
|
174
|
-
end # class Standings
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
end # module SportDb
|