sportdb-models 1.18.5 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Manifest.txt +27 -145
- data/Rakefile +4 -5
- data/lib/sportdb/models.rb +93 -160
- data/lib/sportdb/{deleter.rb → models/deleter.rb} +4 -10
- 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} +18 -61
- 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} +2 -1
- 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} +165 -100
- data/lib/sportdb/models/stats.rb +23 -0
- data/lib/sportdb/models/utils.rb +24 -24
- data/lib/sportdb/{version.rb → models/version.rb} +12 -5
- data/test/helper.rb +10 -114
- data/test/test_changes.rb +38 -38
- data/test/test_cursor.rb +15 -15
- data/test/test_winner.rb +75 -70
- metadata +29 -161
- data/lib/sportdb/calc.rb +0 -279
- data/lib/sportdb/indexers/team.rb +0 -87
- data/lib/sportdb/mapper_teams.rb +0 -24
- data/lib/sportdb/matcher.rb +0 -31
- 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/pretty_printer.rb +0 -175
- data/lib/sportdb/reader.rb +0 -132
- data/lib/sportdb/reader_file.rb +0 -131
- data/lib/sportdb/reader_zip.rb +0 -172
- data/lib/sportdb/readers/assoc.rb +0 -54
- data/lib/sportdb/readers/event.rb +0 -253
- data/lib/sportdb/readers/event_meta.rb +0 -133
- data/lib/sportdb/readers/event_table.rb +0 -196
- data/lib/sportdb/readers/game.rb +0 -912
- data/lib/sportdb/readers/ground.rb +0 -53
- data/lib/sportdb/readers/league.rb +0 -54
- data/lib/sportdb/readers/season.rb +0 -83
- data/lib/sportdb/readers/squad_club.rb +0 -201
- data/lib/sportdb/readers/squad_national_team.rb +0 -173
- data/lib/sportdb/readers/team.rb +0 -53
- data/lib/sportdb/rsssf_reader.rb +0 -367
- data/lib/sportdb/standings.rb +0 -178
- data/lib/sportdb/stats.rb +0 -27
- data/lib/sportdb/utils.rb +0 -89
- data/lib/sportdb/utils_date.rb +0 -26
- data/lib/sportdb/utils_goals.rb +0 -20
- data/lib/sportdb/utils_group.rb +0 -63
- data/lib/sportdb/utils_map.rb +0 -44
- data/lib/sportdb/utils_round.rb +0 -165
- data/lib/sportdb/utils_scores.rb +0 -17
- data/lib/sportdb/utils_teams.rb +0 -48
- data/test/data/at-austria/2013_14/bl.txt +0 -227
- data/test/data/at-austria/2013_14/bl.yml +0 -30
- data/test/data/at-austria/2013_14/bl_ii.txt +0 -154
- data/test/data/at-austria/2013_14/el.txt +0 -4
- data/test/data/at-austria/2013_14/el.yml +0 -25
- data/test/data/at-austria/2013_14/squads/austria.txt +0 -40
- data/test/data/at-austria/2013_14/squads/salzburg.txt +0 -35
- data/test/data/at-austria/2014_15/1-bundesliga-ii.txt +0 -158
- data/test/data/at-austria/2014_15/1-bundesliga.yml +0 -18
- data/test/data/at-austria/2015_16/1-bundesliga-v2.conf.txt +0 -20
- data/test/data/at-austria/2015_16/1-bundesliga-v2.yml +0 -20
- data/test/data/at-austria/2015_16/1-bundesliga.conf.txt +0 -20
- data/test/data/at-austria/2015_16/1-bundesliga.yml +0 -24
- data/test/data/at-austria/2015_16/cup.yml +0 -77
- data/test/data/at-austria/leagues.txt +0 -11
- data/test/data/at-austria/teams.txt +0 -68
- data/test/data/at-austria/teams_2.txt +0 -21
- data/test/data/csv/de-2013-14--1-bundesliga.txt +0 -307
- data/test/data/de-deutschland/2013-14/1-bundesliga.yml +0 -26
- data/test/data/de-deutschland/leagues.txt +0 -4
- data/test/data/de-deutschland/teams.txt +0 -53
- data/test/data/eng-england/2015-16/1-premierleague-v2.yml +0 -2
- data/test/data/eng-england/2015-16/1-premierleague.yml +0 -5
- data/test/data/national-teams/assocs.txt +0 -231
- data/test/data/national-teams/europe/assocs.txt +0 -13
- data/test/data/national-teams/europe/teams.txt +0 -13
- data/test/data/national-teams/north-america/assocs.txt +0 -10
- data/test/data/national-teams/north-america/teams.txt +0 -7
- data/test/data/national-teams/teams.txt +0 -19
- data/test/data/players/europe/at-austria/players.txt +0 -45
- data/test/data/players/europe/de-deutschland/players.txt +0 -41
- data/test/data/players/south-america/br-brazil/players.txt +0 -51
- data/test/data/rsssf/at-2014-15--1-bundesliga.txt +0 -339
- data/test/data/rsssf/at-2015-16--1-bundesliga.txt +0 -18
- data/test/data/world-cup/1930/cup.txt +0 -71
- data/test/data/world-cup/1930/cup.yml +0 -23
- data/test/data/world-cup/1930/cup_goals.txt +0 -47
- data/test/data/world-cup/1930/cup_goals.yml +0 -23
- data/test/data/world-cup/1954/cup.txt +0 -90
- data/test/data/world-cup/1954/cup.yml +0 -30
- data/test/data/world-cup/1962/cup.txt +0 -86
- data/test/data/world-cup/1962/cup.yml +0 -32
- data/test/data/world-cup/1974/cup.yml +0 -35
- data/test/data/world-cup/1974/cup_finals.txt +0 -14
- data/test/data/world-cup/1974/cup_i.txt +0 -55
- data/test/data/world-cup/1974/cup_ii.txt +0 -34
- data/test/data/world-cup/2014/cup.txt +0 -5
- data/test/data/world-cup/2014/cup.yml +0 -54
- data/test/data/world-cup/2014/squads/br-brazil.txt +0 -46
- data/test/data/world-cup/2014/squads/de-deutschland.txt +0 -8
- data/test/data/world-cup/2014/squads/jp-japan.txt +0 -30
- data/test/data/world-cup/2014/squads/uy-uruguay.txt +0 -32
- data/test/data/world-cup/leagues.txt +0 -5
- data/test/data/world-cup/seasons_1930.txt +0 -4
- data/test/data/world-cup/seasons_1954.txt +0 -4
- data/test/data/world-cup/seasons_1962.txt +0 -4
- data/test/data/world-cup/seasons_1974.txt +0 -5
- data/test/data/world-cup/teams_1930.txt +0 -26
- data/test/data/world-cup/teams_1954.txt +0 -30
- data/test/data/world-cup/teams_1962.txt +0 -29
- data/test/data/world-cup/teams_1974.txt +0 -29
- data/test/test_assoc_reader.rb +0 -199
- data/test/test_event_meta_reader.rb +0 -47
- data/test/test_event_reader.rb +0 -64
- data/test/test_event_table_reader.rb +0 -57
- data/test/test_goals.rb +0 -107
- data/test/test_indexer_team.rb +0 -34
- data/test/test_load.rb +0 -61
- data/test/test_pp.rb +0 -35
- data/test/test_reader.rb +0 -88
- data/test/test_reader_from_string.rb +0 -63
- data/test/test_round_auto.rb +0 -370
- data/test/test_round_def.rb +0 -109
- data/test/test_round_header.rb +0 -183
- data/test/test_rsssf_reader.rb +0 -76
- data/test/test_squad_club_reader.rb +0 -76
- data/test/test_squad_national_team_reader.rb +0 -116
- data/test/test_standings.rb +0 -279
- data/test/test_standings_ii.rb +0 -46
- data/test/test_utils.rb +0 -124
data/lib/sportdb/readers/team.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
module SportDb
|
4
|
-
|
5
|
-
|
6
|
-
class TeamReader
|
7
|
-
|
8
|
-
include LogUtils::Logging
|
9
|
-
|
10
|
-
## make models available by default with namespace
|
11
|
-
# e.g. lets you use Usage instead of Model::Usage
|
12
|
-
include Models
|
13
|
-
|
14
|
-
def self.from_zip( zip_file, entry_path, more_attribs={} )
|
15
|
-
## get text content from zip
|
16
|
-
entry = zip_file.find_entry( entry_path )
|
17
|
-
|
18
|
-
text = entry.get_input_stream().read()
|
19
|
-
text = text.force_encoding( Encoding::UTF_8 )
|
20
|
-
|
21
|
-
self.from_string( text, more_attribs )
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.from_file( path, more_attribs={} )
|
25
|
-
## note: assume/enfore utf-8 encoding (with or without BOM - byte order mark)
|
26
|
-
## - see textutils/utils.rb
|
27
|
-
text = File.read_utf8( path )
|
28
|
-
self.from_string( text, more_attribs )
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.from_string( text, more_attribs={} )
|
32
|
-
TeamReader.new( text, more_attribs )
|
33
|
-
end
|
34
|
-
|
35
|
-
def initialize( text, more_attribs={} )
|
36
|
-
## todo/fix: how to add opts={} ???
|
37
|
-
@text = text
|
38
|
-
@more_attribs = more_attribs
|
39
|
-
end
|
40
|
-
|
41
|
-
|
42
|
-
def read
|
43
|
-
reader = ValuesReader.from_string( @text, @more_attribs )
|
44
|
-
|
45
|
-
reader.each_line do |new_attributes, values|
|
46
|
-
Team.create_or_update_from_values( new_attributes, values )
|
47
|
-
end # each lines
|
48
|
-
end
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end # class TeamReader
|
53
|
-
end # module SportDb
|
data/lib/sportdb/rsssf_reader.rb
DELETED
@@ -1,367 +0,0 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
|
3
|
-
##
|
4
|
-
## note: for now lets only support leagues with rounds (no cups/knockout rounds n groups)
|
5
|
-
## (re)add later when needed (e.g. for playoffs etc.)
|
6
|
-
|
7
|
-
|
8
|
-
module SportDb
|
9
|
-
|
10
|
-
|
11
|
-
class RsssfGameReader ### todo: rename to RsssfLeagueMatchReader ( or use league/cup option?) - why? why not??
|
12
|
-
|
13
|
-
include LogUtils::Logging
|
14
|
-
|
15
|
-
## make models available by default with namespace
|
16
|
-
# e.g. lets you use Usage instead of Model::Usage
|
17
|
-
include Models
|
18
|
-
|
19
|
-
##
|
20
|
-
## todo: add from_file and from_zip too
|
21
|
-
|
22
|
-
def self.from_string( event_or_event_key, text )
|
23
|
-
self.new( event_or_event_key, text )
|
24
|
-
end
|
25
|
-
|
26
|
-
def initialize( event_or_event_key, text )
|
27
|
-
## todo/fix: how to add opts={} ???
|
28
|
-
@event_or_event_key = event_or_event_key
|
29
|
-
@text = text
|
30
|
-
end
|
31
|
-
|
32
|
-
|
33
|
-
def read
|
34
|
-
## note: assume active activerecord connection
|
35
|
-
|
36
|
-
if @event_or_event_key.kind_of?( Event )
|
37
|
-
@event= @event_or_event_key
|
38
|
-
else ## assume string
|
39
|
-
@event = Event.find_by!( key: @event_or_event_key )
|
40
|
-
end
|
41
|
-
|
42
|
-
logger.debug "Event #{@event.key} >#{@event.title}<"
|
43
|
-
|
44
|
-
@mapper_teams = TeamMapper.new( @event.teams )
|
45
|
-
|
46
|
-
## reset cached values
|
47
|
-
@patch_round_ids = []
|
48
|
-
|
49
|
-
@last_round = nil
|
50
|
-
@last_date = nil
|
51
|
-
|
52
|
-
reader = LineReader.from_string( @text )
|
53
|
-
parse_fixtures( reader )
|
54
|
-
end # method load_fixtures
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
RSSSF_FT_REGEX = /\b
|
59
|
-
(?<score1>\d{1,2})
|
60
|
-
-
|
61
|
-
(?<score2>\d{1,2})
|
62
|
-
\b/x
|
63
|
-
|
64
|
-
def find_rsssf_scores!( line )
|
65
|
-
# e.g. 1-1 or 0-2 or 3-3
|
66
|
-
|
67
|
-
m = RSSSF_FT_REGEX.match( line )
|
68
|
-
if m
|
69
|
-
score1 = m[:score1].to_i
|
70
|
-
score2 = m[:score2].to_i
|
71
|
-
|
72
|
-
logger.debug " score: >#{score1}-#{score2}<"
|
73
|
-
|
74
|
-
line.sub!( m[0], '[SCORE]' )
|
75
|
-
else
|
76
|
-
score1 = nil
|
77
|
-
score2 = nil
|
78
|
-
end
|
79
|
-
|
80
|
-
scores = [score1, score2]
|
81
|
-
scores
|
82
|
-
end # method find_rsssf_scores!
|
83
|
-
|
84
|
-
|
85
|
-
def find_rsssf_date!( line, opts={} )
|
86
|
-
finder = RsssfDateFinder.new
|
87
|
-
finder.find!( line, opts )
|
88
|
-
end
|
89
|
-
|
90
|
-
|
91
|
-
RSSSF_ROUND_REGEX = /\b
|
92
|
-
(?<round>Round)
|
93
|
-
\s
|
94
|
-
(?<pos>\d{1,3})
|
95
|
-
\b/x
|
96
|
-
|
97
|
-
def is_rsssf_round?( line )
|
98
|
-
RSSSF_ROUND_REGEX.match( line ).nil? == false ## match found if not nil
|
99
|
-
end
|
100
|
-
|
101
|
-
def find_rsssf_round!( line )
|
102
|
-
## todo: check if \b works for run on [Apr 13] too ??
|
103
|
-
## todo: allow multiple spaces after round ??
|
104
|
-
|
105
|
-
m = RSSSF_ROUND_REGEX.match( line )
|
106
|
-
if m
|
107
|
-
title = m[0] ## note: title is complete match e.g. Round 1, Round 2, etc.
|
108
|
-
pos = m[:pos].to_i
|
109
|
-
|
110
|
-
logger.debug " title: >#{title}<, pos: >#{pos}<"
|
111
|
-
|
112
|
-
line.sub!( m[0], '[ROUND]' )
|
113
|
-
else
|
114
|
-
## fix: add logger.warn no round pos found in line
|
115
|
-
title = nil
|
116
|
-
pos = nil
|
117
|
-
end
|
118
|
-
|
119
|
-
[title,pos] ## return array; note: [nil,nil] if nothing found
|
120
|
-
end # method find_rsssf_round!
|
121
|
-
|
122
|
-
|
123
|
-
def parse_round_header( line )
|
124
|
-
|
125
|
-
## todo/fix:
|
126
|
-
## simplify - for now round number always required
|
127
|
-
# e.g. no auto-calculation supported here
|
128
|
-
# fail if round found w/o number/pos !!!
|
129
|
-
#
|
130
|
-
# also remove knockout flag for now (set to always false for now)
|
131
|
-
|
132
|
-
logger.debug "parsing round header line: >#{line}<"
|
133
|
-
|
134
|
-
## check for date in header first e.g. Round 36 [Jul 20] !!
|
135
|
-
## avoid "conflict" with getting "wrong" round number from date etc.
|
136
|
-
date = find_rsssf_date!( line, start_at: @event.start_at )
|
137
|
-
if date
|
138
|
-
@last_date = date
|
139
|
-
end
|
140
|
-
|
141
|
-
title, pos = find_rsssf_round!( line )
|
142
|
-
|
143
|
-
## check if pos available; if not auto-number/calculate
|
144
|
-
if pos.nil?
|
145
|
-
logger.error( " no round pos found in line >#{line}<; round pos required in rsssf; sorry" )
|
146
|
-
fail( "round pos required in rsssf; sorry")
|
147
|
-
end
|
148
|
-
|
149
|
-
logger.debug " line: >#{line}<"
|
150
|
-
|
151
|
-
## Note: dummy/placeholder start_at, end_at date
|
152
|
-
## replace/patch after adding all games for round
|
153
|
-
|
154
|
-
round_attribs = {
|
155
|
-
title: title,
|
156
|
-
title2: nil,
|
157
|
-
knockout: false
|
158
|
-
}
|
159
|
-
|
160
|
-
round = Round.find_by( event_id: @event.id,
|
161
|
-
pos: pos )
|
162
|
-
|
163
|
-
if round.present?
|
164
|
-
logger.debug "update round #{round.id}:"
|
165
|
-
else
|
166
|
-
logger.debug "create round:"
|
167
|
-
round = Round.new
|
168
|
-
|
169
|
-
round_attribs = round_attribs.merge( {
|
170
|
-
event_id: @event.id,
|
171
|
-
pos: pos,
|
172
|
-
## todo: add num e.g. num == pos for round 1, round 2, etc. - why? why not??
|
173
|
-
start_at: Date.parse('1911-11-11'),
|
174
|
-
end_at: Date.parse('1911-11-11')
|
175
|
-
})
|
176
|
-
end
|
177
|
-
|
178
|
-
logger.debug round_attribs.to_json
|
179
|
-
|
180
|
-
round.update_attributes!( round_attribs )
|
181
|
-
|
182
|
-
### store list of round ids for patching start_at/end_at at the end
|
183
|
-
@patch_round_ids << round.id
|
184
|
-
@last_round = round ## keep track of last seen round for matches that follow etc.
|
185
|
-
end
|
186
|
-
|
187
|
-
|
188
|
-
def try_parse_game( line )
|
189
|
-
# note: clone line; for possible test do NOT modify in place for now
|
190
|
-
# note: returns true if parsed, false if no match
|
191
|
-
parse_game( line.dup )
|
192
|
-
end
|
193
|
-
|
194
|
-
def parse_game( line )
|
195
|
-
logger.debug "parsing game (fixture) line: >#{line}<"
|
196
|
-
|
197
|
-
@mapper_teams.map_teams!( line )
|
198
|
-
team_keys = @mapper_teams.find_teams!( line )
|
199
|
-
team1_key = team_keys[0]
|
200
|
-
team2_key = team_keys[1]
|
201
|
-
|
202
|
-
## note: if we do NOT find two teams; return false - no match found
|
203
|
-
if team1_key.nil? || team2_key.nil?
|
204
|
-
logger.debug " no game match (two teams required) found for line: >#{line}<"
|
205
|
-
return false
|
206
|
-
end
|
207
|
-
|
208
|
-
date = find_rsssf_date!( line, start_at: @event.start_at )
|
209
|
-
|
210
|
-
###
|
211
|
-
# check if date found?
|
212
|
-
# note: ruby falsey is nil & false only (not 0 or empty array etc.)
|
213
|
-
if date
|
214
|
-
@last_date = date # keep a reference for later use
|
215
|
-
else
|
216
|
-
date = @last_date # no date found; (re)use last seen date
|
217
|
-
end
|
218
|
-
|
219
|
-
scores = find_rsssf_scores!( line )
|
220
|
-
|
221
|
-
logger.debug " line: >#{line}<"
|
222
|
-
|
223
|
-
|
224
|
-
### todo: cache team lookups in hash?
|
225
|
-
team1 = Team.find_by!( key: team1_key )
|
226
|
-
team2 = Team.find_by!( key: team2_key )
|
227
|
-
|
228
|
-
round = @last_round
|
229
|
-
|
230
|
-
### check if games exists
|
231
|
-
## with this teams in this round if yes only update
|
232
|
-
##
|
233
|
-
## todo: add replay flag (true/false) !!!!!!!!
|
234
|
-
## allows same match fixture in round !!!!!!!!
|
235
|
-
game = Game.find_by( round_id: round.id,
|
236
|
-
team1_id: team1.id,
|
237
|
-
team2_id: team2.id )
|
238
|
-
|
239
|
-
game_attribs = {
|
240
|
-
score1: scores[0],
|
241
|
-
score2: scores[1],
|
242
|
-
score1et: scores[2],
|
243
|
-
score2et: scores[3],
|
244
|
-
score1p: scores[4],
|
245
|
-
score2p: scores[5],
|
246
|
-
play_at: date,
|
247
|
-
play_at_v2: nil,
|
248
|
-
postponed: false,
|
249
|
-
knockout: false, ## round.knockout, ## note: for now always use knockout flag from round - why? why not??
|
250
|
-
ground_id: nil,
|
251
|
-
group_id: nil
|
252
|
-
}
|
253
|
-
|
254
|
-
if game.present?
|
255
|
-
logger.debug "update game #{game.id}:"
|
256
|
-
else
|
257
|
-
logger.debug "create game:"
|
258
|
-
game = Game.new
|
259
|
-
|
260
|
-
## Note: use round.games.count for pos
|
261
|
-
## lets us add games out of order if later needed
|
262
|
-
more_game_attribs = {
|
263
|
-
round_id: round.id,
|
264
|
-
team1_id: team1.id,
|
265
|
-
team2_id: team2.id,
|
266
|
-
pos: round.games.count+1
|
267
|
-
}
|
268
|
-
game_attribs = game_attribs.merge( more_game_attribs )
|
269
|
-
end
|
270
|
-
|
271
|
-
logger.debug game_attribs.to_json
|
272
|
-
game.update_attributes!( game_attribs )
|
273
|
-
|
274
|
-
return true # game match found
|
275
|
-
end # method parse_game
|
276
|
-
|
277
|
-
|
278
|
-
def try_parse_date_header( line )
|
279
|
-
# note: clone line; for possible test do NOT modify in place for now
|
280
|
-
# note: returns true if parsed, false if no match
|
281
|
-
parse_date_header( line.dup )
|
282
|
-
end
|
283
|
-
|
284
|
-
def parse_date_header( line )
|
285
|
-
# note: returns true if parsed, false if no match
|
286
|
-
|
287
|
-
# line with NO teams plus include date e.g.
|
288
|
-
# [Jun 17] etc.
|
289
|
-
|
290
|
-
@mapper_teams.map_teams!( line )
|
291
|
-
team_keys= @mapper_teams.find_teams!( line )
|
292
|
-
team1_key = team_keys[0]
|
293
|
-
team2_key = team_keys[1]
|
294
|
-
|
295
|
-
date = find_rsssf_date!( line, start_at: @event.start_at )
|
296
|
-
|
297
|
-
if date && team1_key.nil? && team2_key.nil?
|
298
|
-
logger.debug( "date header line found: >#{line}<")
|
299
|
-
logger.debug( " date: #{date}")
|
300
|
-
|
301
|
-
@last_date = date # keep a reference for later use
|
302
|
-
return true
|
303
|
-
else
|
304
|
-
return false
|
305
|
-
end
|
306
|
-
end
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
def parse_fixtures( reader )
|
311
|
-
|
312
|
-
reader.each_line do |line|
|
313
|
-
|
314
|
-
if is_rsssf_round?( line )
|
315
|
-
parse_round_header( line )
|
316
|
-
elsif try_parse_game( line )
|
317
|
-
# do nothing here
|
318
|
-
elsif try_parse_date_header( line )
|
319
|
-
# do nothing here
|
320
|
-
else
|
321
|
-
logger.info "skipping line (no match found): >#{line}<"
|
322
|
-
end
|
323
|
-
end # lines.each
|
324
|
-
|
325
|
-
###########################
|
326
|
-
# backtrack and patch round dates (start_at/end_at)
|
327
|
-
|
328
|
-
unless @patch_round_ids.empty?
|
329
|
-
###
|
330
|
-
# note: use uniq - to allow multiple round headers (possible?)
|
331
|
-
|
332
|
-
Round.find( @patch_round_ids.uniq ).each do |r|
|
333
|
-
logger.debug "patch round start_at/end_at date for #{r.title}:"
|
334
|
-
|
335
|
-
## note:
|
336
|
-
## will add "scope" pos first e.g
|
337
|
-
#
|
338
|
-
## SELECT "games".* FROM "games" WHERE "games"."round_id" = ?
|
339
|
-
# ORDER BY pos, play_at asc [["round_id", 7]]
|
340
|
-
# thus will NOT order by play_at but by pos first!!!
|
341
|
-
# =>
|
342
|
-
# need to unscope pos!!! or use unordered_games - games_by_play_at_date etc.??
|
343
|
-
# thus use reorder()!!! - not just order('play_at asc')
|
344
|
-
|
345
|
-
games = r.games.reorder( 'play_at asc' ).all
|
346
|
-
|
347
|
-
## skip rounds w/ no games
|
348
|
-
|
349
|
-
## todo/check/fix: what's the best way for checking assoc w/ 0 recs?
|
350
|
-
next if games.size == 0
|
351
|
-
|
352
|
-
# note: make sure start_at/end_at is date only (e.g. use play_at.to_date)
|
353
|
-
# sqlite3 saves datetime in date field as datetime, for example (will break date compares later!)
|
354
|
-
|
355
|
-
round_attribs = {
|
356
|
-
start_at: games[0].play_at.to_date, # use games.first ?
|
357
|
-
end_at: games[-1].play_at.to_date # use games.last ? why? why not?
|
358
|
-
}
|
359
|
-
|
360
|
-
logger.debug round_attribs.to_json
|
361
|
-
r.update_attributes!( round_attribs )
|
362
|
-
end
|
363
|
-
end
|
364
|
-
end # method parse_fixtures
|
365
|
-
|
366
|
-
end # class RsssfGameReader
|
367
|
-
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
|