sportdb-formats 1.1.2 → 1.1.3
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 +6 -13
- data/Rakefile +1 -1
- data/lib/sportdb/formats.rb +5 -0
- data/lib/sportdb/formats/country/country_index.rb +2 -2
- data/lib/sportdb/formats/event/event_index.rb +9 -11
- data/lib/sportdb/formats/league/league_index.rb +22 -18
- data/lib/sportdb/formats/league/league_outline_reader.rb +4 -1
- data/lib/sportdb/formats/league/league_reader.rb +7 -1
- data/lib/sportdb/formats/match/match_parser.rb +27 -15
- data/lib/sportdb/formats/match/match_parser_csv.rb +148 -21
- data/lib/sportdb/formats/match/match_status_parser.rb +86 -0
- data/lib/sportdb/formats/name_helper.rb +4 -1
- data/lib/sportdb/formats/package.rb +30 -8
- data/lib/sportdb/formats/score/score_formats.rb +19 -0
- data/lib/sportdb/formats/score/score_parser.rb +4 -2
- data/lib/sportdb/formats/structs/match.rb +2 -0
- data/lib/sportdb/formats/structs/team.rb +7 -0
- data/lib/sportdb/formats/team/club_index.rb +13 -11
- data/lib/sportdb/formats/team/club_index_history.rb +138 -0
- data/lib/sportdb/formats/team/club_reader_history.rb +203 -0
- data/lib/sportdb/formats/team/club_reader_props.rb +2 -3
- data/lib/sportdb/formats/version.rb +1 -1
- data/test/helper.rb +47 -81
- data/test/test_club_index_history.rb +107 -0
- data/test/test_club_reader_history.rb +212 -0
- data/test/test_datafile_package.rb +1 -1
- data/test/test_match_status_parser.rb +49 -0
- data/test/test_scores.rb +2 -0
- metadata +10 -17
- data/test/test_conf.rb +0 -65
- data/test/test_csv_match_parser.rb +0 -114
- data/test/test_csv_match_parser_utils.rb +0 -20
- data/test/test_match_auto.rb +0 -72
- data/test/test_match_auto_champs.rb +0 -45
- data/test/test_match_auto_euro.rb +0 -37
- data/test/test_match_auto_relegation.rb +0 -41
- data/test/test_match_auto_worldcup.rb +0 -61
- data/test/test_match_champs.rb +0 -27
- data/test/test_match_eng.rb +0 -26
- data/test/test_match_euro.rb +0 -27
- data/test/test_match_start_date.rb +0 -44
- data/test/test_match_worldcup.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 666fc1f16808dddbc988aa073c0d3b47c08a5934
|
4
|
+
data.tar.gz: 97437435e1f37341c9f2cc15c8b4e67adf0efe61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9498c5e378feab9fa1e80a8287f33ab608e606ecde6ae914997483850faffbbbc7695ef07d2cea1e04a529e724b01612e8231fe8625c19d0af34f3fabffd0a14
|
7
|
+
data.tar.gz: 28146d5c35a061f6c128a001c190681eb76de5471cde8124435e77d93ccca090bf0a84a7a6a09ccb67372f8edef0198e8f09390126629d14072901ff5fcb7743
|
data/Manifest.txt
CHANGED
@@ -20,6 +20,7 @@ lib/sportdb/formats/match/mapper_teams.rb
|
|
20
20
|
lib/sportdb/formats/match/match_parser.rb
|
21
21
|
lib/sportdb/formats/match/match_parser_auto_conf.rb
|
22
22
|
lib/sportdb/formats/match/match_parser_csv.rb
|
23
|
+
lib/sportdb/formats/match/match_status_parser.rb
|
23
24
|
lib/sportdb/formats/name_helper.rb
|
24
25
|
lib/sportdb/formats/outline_reader.rb
|
25
26
|
lib/sportdb/formats/package.rb
|
@@ -38,7 +39,9 @@ lib/sportdb/formats/structs/standings.rb
|
|
38
39
|
lib/sportdb/formats/structs/team.rb
|
39
40
|
lib/sportdb/formats/structs/team_usage.rb
|
40
41
|
lib/sportdb/formats/team/club_index.rb
|
42
|
+
lib/sportdb/formats/team/club_index_history.rb
|
41
43
|
lib/sportdb/formats/team/club_reader.rb
|
44
|
+
lib/sportdb/formats/team/club_reader_history.rb
|
42
45
|
lib/sportdb/formats/team/club_reader_props.rb
|
43
46
|
lib/sportdb/formats/team/national_team_index.rb
|
44
47
|
lib/sportdb/formats/team/team_index.rb
|
@@ -46,14 +49,13 @@ lib/sportdb/formats/team/wiki_reader.rb
|
|
46
49
|
lib/sportdb/formats/version.rb
|
47
50
|
test/helper.rb
|
48
51
|
test/test_club_index.rb
|
52
|
+
test/test_club_index_history.rb
|
49
53
|
test/test_club_reader.rb
|
54
|
+
test/test_club_reader_history.rb
|
50
55
|
test/test_club_reader_props.rb
|
51
56
|
test/test_clubs.rb
|
52
|
-
test/test_conf.rb
|
53
57
|
test/test_country_index.rb
|
54
58
|
test/test_country_reader.rb
|
55
|
-
test/test_csv_match_parser.rb
|
56
|
-
test/test_csv_match_parser_utils.rb
|
57
59
|
test/test_csv_reader.rb
|
58
60
|
test/test_datafile.rb
|
59
61
|
test/test_datafile_package.rb
|
@@ -62,16 +64,7 @@ test/test_league_index.rb
|
|
62
64
|
test/test_league_outline_reader.rb
|
63
65
|
test/test_league_reader.rb
|
64
66
|
test/test_match.rb
|
65
|
-
test/
|
66
|
-
test/test_match_auto_champs.rb
|
67
|
-
test/test_match_auto_euro.rb
|
68
|
-
test/test_match_auto_relegation.rb
|
69
|
-
test/test_match_auto_worldcup.rb
|
70
|
-
test/test_match_champs.rb
|
71
|
-
test/test_match_eng.rb
|
72
|
-
test/test_match_euro.rb
|
73
|
-
test/test_match_start_date.rb
|
74
|
-
test/test_match_worldcup.rb
|
67
|
+
test/test_match_status_parser.rb
|
75
68
|
test/test_name_helper.rb
|
76
69
|
test/test_outline_reader.rb
|
77
70
|
test/test_package.rb
|
data/Rakefile
CHANGED
data/lib/sportdb/formats.rb
CHANGED
@@ -75,10 +75,12 @@ require 'sportdb/formats/goals'
|
|
75
75
|
|
76
76
|
require 'sportdb/formats/match/mapper'
|
77
77
|
require 'sportdb/formats/match/mapper_teams'
|
78
|
+
require 'sportdb/formats/match/match_status_parser'
|
78
79
|
require 'sportdb/formats/match/match_parser'
|
79
80
|
require 'sportdb/formats/match/match_parser_auto_conf'
|
80
81
|
require 'sportdb/formats/match/conf_parser'
|
81
82
|
|
83
|
+
|
82
84
|
require 'sportdb/formats/match/match_parser_csv'
|
83
85
|
|
84
86
|
require 'sportdb/formats/country/country_reader'
|
@@ -119,6 +121,9 @@ require 'sportdb/formats/team/wiki_reader'
|
|
119
121
|
require 'sportdb/formats/team/national_team_index'
|
120
122
|
require 'sportdb/formats/team/team_index'
|
121
123
|
|
124
|
+
require 'sportdb/formats/team/club_reader_history'
|
125
|
+
require 'sportdb/formats/team/club_index_history'
|
126
|
+
|
122
127
|
|
123
128
|
###
|
124
129
|
# add convenience helpers / shortcuts
|
@@ -109,12 +109,12 @@ class CountryIndex
|
|
109
109
|
@countries_by_name[ name ]
|
110
110
|
end
|
111
111
|
|
112
|
-
def
|
112
|
+
def find( key )
|
113
113
|
country = find_by_code( key )
|
114
114
|
country = find_by_name( key ) if country.nil? ## try lookup / find by (normalized) name
|
115
115
|
country
|
116
116
|
end
|
117
|
-
alias_method :
|
117
|
+
alias_method :[], :find
|
118
118
|
|
119
119
|
|
120
120
|
###
|
@@ -2,27 +2,25 @@ module SportDb
|
|
2
2
|
module Import
|
3
3
|
|
4
4
|
|
5
|
+
|
5
6
|
class EventIndex
|
6
7
|
|
7
8
|
def self.build( path )
|
8
|
-
|
9
|
-
|
10
|
-
puts
|
11
|
-
puts "#{datafiles.size} seasons datafile(s):"
|
12
|
-
pp datafiles
|
13
|
-
|
14
|
-
index = new
|
15
|
-
datafiles.each do |datafile|
|
16
|
-
recs = EventInfoReader.read( datafile )
|
17
|
-
# pp recs
|
9
|
+
pack = Package.new( path ) ## lets us use direcotry or zip archive
|
18
10
|
|
19
|
-
|
11
|
+
recs = []
|
12
|
+
pack.each_seasons do |entry|
|
13
|
+
recs += EventInfoReader.parse( entry.read )
|
20
14
|
end
|
15
|
+
recs
|
21
16
|
|
17
|
+
index = new
|
18
|
+
index.add( recs )
|
22
19
|
index
|
23
20
|
end
|
24
21
|
|
25
22
|
|
23
|
+
|
26
24
|
attr_reader :events
|
27
25
|
def initialize
|
28
26
|
@events = []
|
@@ -95,36 +95,40 @@ class LeagueIndex
|
|
95
95
|
end # method add
|
96
96
|
|
97
97
|
|
98
|
+
## helper to always convert (possible) country key to existing country record
|
99
|
+
## todo: make private - why? why not?
|
100
|
+
def country( country )
|
101
|
+
if country.is_a?( String ) || country.is_a?( Symbol )
|
102
|
+
## note: use own "global" countries index setting for ClubIndex - why? why not?
|
103
|
+
rec = catalog.countries.find( country.to_s )
|
104
|
+
if rec.nil?
|
105
|
+
puts "** !!! ERROR !!! - unknown country >#{country}< - no match found, sorry - add to world/countries.txt in config"
|
106
|
+
exit 1
|
107
|
+
end
|
108
|
+
rec
|
109
|
+
else
|
110
|
+
country ## (re)use country struct - no need to run lookup again
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
|
98
115
|
def match( name )
|
99
|
-
##
|
116
|
+
## note: returns empty array if no match and NOT nil
|
100
117
|
name = normalize( name )
|
101
|
-
@leagues_by_name[ name ]
|
118
|
+
@leagues_by_name[ name ] || []
|
102
119
|
end
|
103
120
|
|
104
|
-
|
105
121
|
def match_by( name:, country: )
|
106
122
|
## note: match must for now always include name
|
107
123
|
m = match( name )
|
108
|
-
if
|
124
|
+
if country ## filter by country
|
109
125
|
## note: country assumes / allows the country key or fifa code for now
|
110
|
-
|
111
126
|
## note: allow passing in of country struct too
|
112
|
-
country_rec =
|
113
|
-
country ## (re)use country struct - no need to run lookup again
|
114
|
-
else
|
115
|
-
## note: use own "global" countries index setting for ClubIndex - why? why not?
|
116
|
-
rec = catalog.countries.find( country )
|
117
|
-
if rec.nil?
|
118
|
-
puts "** !!! ERROR !!! - unknown country >#{country}< - no match found, sorry - add to world/countries.txt in config"
|
119
|
-
exit 1
|
120
|
-
end
|
121
|
-
rec
|
122
|
-
end
|
127
|
+
country_rec = country( country )
|
123
128
|
|
124
129
|
## note: also skip international leagues & cups (e.g. champions league etc.) for now - why? why not?
|
125
130
|
m = m.select { |league| league.country &&
|
126
131
|
league.country.key == country_rec.key }
|
127
|
-
m = nil if m.empty? ## note: reset to nil if no more matches
|
128
132
|
end
|
129
133
|
m
|
130
134
|
end
|
@@ -144,7 +148,7 @@ class LeagueIndex
|
|
144
148
|
m = match( name )
|
145
149
|
# pp m
|
146
150
|
|
147
|
-
if m.
|
151
|
+
if m.empty?
|
148
152
|
## fall through/do nothing
|
149
153
|
elsif m.size > 1
|
150
154
|
puts "** !!! ERROR - ambigious league name; too many leagues (#{m.size}) found:"
|
@@ -127,7 +127,7 @@ class LeagueOutlineReader ## todo/check - rename to LeaguePageReader / LeagueP
|
|
127
127
|
'Regular Season',
|
128
128
|
'Regular Stage',
|
129
129
|
'Championship Round',
|
130
|
-
'Championship Playoff',
|
130
|
+
'Championship Playoff', # or Championship play-off
|
131
131
|
'Relegation Round',
|
132
132
|
'Relegation Playoff',
|
133
133
|
'Play-offs',
|
@@ -140,6 +140,9 @@ class LeagueOutlineReader ## todo/check - rename to LeaguePageReader / LeagueP
|
|
140
140
|
'EL Play-off',
|
141
141
|
'Europa League Play-off',
|
142
142
|
'Europa-League-Play-offs',
|
143
|
+
'Playoffs - Championship',
|
144
|
+
'Playoffs - Relegation',
|
145
|
+
'Finals',
|
143
146
|
].map {|name| name.downcase.gsub( /[^a-z]/, '' ) }
|
144
147
|
|
145
148
|
|
@@ -118,12 +118,18 @@ def parse
|
|
118
118
|
alt_names_auto << "#{country.code}" if league_key == '1' ## add shortcut for top level 1 (just country key)
|
119
119
|
end
|
120
120
|
alt_names_auto << "#{country.name} #{league_key}" if league_key =~ /^[0-9]+$/ ## if all numeric e.g. add Austria 1 etc.
|
121
|
+
|
122
|
+
## auto-add with country prepended
|
123
|
+
## e.g. England Premier League, Austria Bundesliga etc.
|
124
|
+
## todo/check: also add variants with country alt name if present!!!
|
125
|
+
## todo/check: exclude cups or such from country + league name auto-add - why? why not?
|
126
|
+
alt_names_auto << "#{country.name} #{league_name}"
|
121
127
|
else ## assume int'l (no country) e.g. champions league, etc.
|
122
128
|
## only auto-add key (e.g. CL, EL, etc.)
|
123
129
|
alt_names_auto << league_key.upcase.gsub('.', ' ') ## note: no country code (prefix/leading) used
|
124
130
|
end
|
125
131
|
|
126
|
-
pp alt_names_auto
|
132
|
+
## pp alt_names_auto
|
127
133
|
|
128
134
|
## prepend country key/code if country present
|
129
135
|
## todo/fix: only auto-prepend country if key/code start with a number (level) or incl. cup
|
@@ -302,6 +302,11 @@ class MatchParser ## simple match parser for team match schedules
|
|
302
302
|
ScoreFormats.find!( line )
|
303
303
|
end
|
304
304
|
|
305
|
+
def find_status!( line )
|
306
|
+
StatusParser.find!( line )
|
307
|
+
end
|
308
|
+
|
309
|
+
|
305
310
|
def try_parse_game( line )
|
306
311
|
# note: clone line; for possible test do NOT modify in place for now
|
307
312
|
# note: returns true if parsed, false if no match
|
@@ -329,6 +334,10 @@ class MatchParser ## simple match parser for team match schedules
|
|
329
334
|
return false
|
330
335
|
end
|
331
336
|
|
337
|
+
## find (optional) match status e.g. [abandoned] or [replay] or [awarded]
|
338
|
+
## or [cancelled] or [postponed] etc.
|
339
|
+
status = find_status!( line ) ## todo/check: allow match status also in geo part (e.g. after @) - why? why not?
|
340
|
+
|
332
341
|
## pos = find_game_pos!( line )
|
333
342
|
|
334
343
|
date = find_date!( line, start: @start )
|
@@ -353,20 +362,23 @@ class MatchParser ## simple match parser for team match schedules
|
|
353
362
|
if @last_round
|
354
363
|
round = @last_round
|
355
364
|
else
|
356
|
-
## find (first) matching round by date
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
365
|
+
## find (first) matching round by date if rounds / matchdays defined
|
366
|
+
## if not rounds / matchdays defined - YES, allow matches WITHOUT rounds!!!
|
367
|
+
if @rounds.size > 0
|
368
|
+
@rounds.values.each do |round_rec|
|
369
|
+
## note: convert date to date only (no time) with to_date!!!
|
370
|
+
if (round_rec.start_date && round_rec.end_date) &&
|
371
|
+
(date.to_date >= round_rec.start_date &&
|
372
|
+
date.to_date <= round_rec.end_date)
|
373
|
+
round = round_rec
|
374
|
+
break
|
375
|
+
end
|
376
|
+
end
|
377
|
+
if round.nil?
|
378
|
+
puts "!! ERROR - no matching round found for match date:"
|
379
|
+
pp date
|
380
|
+
exit 1
|
364
381
|
end
|
365
|
-
end
|
366
|
-
if round.nil?
|
367
|
-
puts "!! ERROR - no matching round found for match date:"
|
368
|
-
pp date
|
369
|
-
exit 1
|
370
382
|
end
|
371
383
|
end
|
372
384
|
|
@@ -380,8 +392,8 @@ class MatchParser ## simple match parser for team match schedules
|
|
380
392
|
team2: team2, ## note: for now always use mapping value e.g. rec (NOT string e.g. team2.name)
|
381
393
|
score: score,
|
382
394
|
round: round ? round.name : nil, ## note: for now always use string (assume unique canonical name for event)
|
383
|
-
group: @last_group ? @last_group.name : nil
|
384
|
-
|
395
|
+
group: @last_group ? @last_group.name : nil, ## note: for now always use string (assume unique canonical name for event)
|
396
|
+
status: status )
|
385
397
|
### todo: cache team lookups in hash?
|
386
398
|
|
387
399
|
=begin
|
@@ -101,9 +101,23 @@ module SportDb
|
|
101
101
|
header_stage = find_header( headers, ['Stage'] )
|
102
102
|
headers_mapping[:stage] = header_stage if header_stage
|
103
103
|
|
104
|
+
header_group = find_header( headers, ['Group'] )
|
105
|
+
headers_mapping[:group] = header_group if header_group
|
106
|
+
|
107
|
+
|
108
|
+
header_et = find_header( headers, ['ET', 'AET'] ) ## (after) extra time
|
109
|
+
headers_mapping[:score_et] = header_et if header_et
|
110
|
+
|
111
|
+
header_p = find_header( headers, ['P', 'PEN'] ) ## penalties
|
112
|
+
headers_mapping[:score_p] = header_p if header_p
|
113
|
+
|
114
|
+
header_notes = find_header( headers, ['Notes', 'Comments'] )
|
115
|
+
headers_mapping[:notes] = header_notes if header_notes
|
116
|
+
|
117
|
+
|
104
118
|
header_league = find_header( headers, ['League'] )
|
105
119
|
headers_mapping[:league] = header_league if header_league
|
106
|
-
|
120
|
+
else
|
107
121
|
## else try footballdata.uk and others
|
108
122
|
headers_mapping[:team1] = find_header( headers, ['HomeTeam', 'HT', 'Home'] )
|
109
123
|
headers_mapping[:team2] = find_header( headers, ['AwayTeam', 'AT', 'Away'] )
|
@@ -229,7 +243,15 @@ module SportDb
|
|
229
243
|
if headers_mapping[ :round ]
|
230
244
|
col = row[ headers_mapping[ :round ]]
|
231
245
|
## todo: issue warning if not ? or - (and just empty string) why? why not
|
232
|
-
round = col.to_i if col =~ /^\d{1,2}$/ # check format - e.g. ignore ? or - or such non-numbers for now
|
246
|
+
## (old attic) was: round = col.to_i if col =~ /^\d{1,2}$/ # check format - e.g. ignore ? or - or such non-numbers for now
|
247
|
+
|
248
|
+
## note: make round always a string for now!!!! e.g. "1", "2" too!!
|
249
|
+
round = if col.nil? || col.empty? || col == '-' || col == 'n/a'
|
250
|
+
## note: allow missing round for match / defaults to nil
|
251
|
+
nil
|
252
|
+
else
|
253
|
+
col
|
254
|
+
end
|
233
255
|
end
|
234
256
|
|
235
257
|
|
@@ -258,25 +280,65 @@ module SportDb
|
|
258
280
|
score2i = ht[1].to_i if ht[1] =~ /^\d{1,2}$/
|
259
281
|
end
|
260
282
|
|
283
|
+
|
261
284
|
## check for all-in-one full time scores?
|
262
285
|
if headers_mapping[ :score ]
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
score1 =
|
267
|
-
score2 =
|
286
|
+
col = row[ headers_mapping[ :score ]]
|
287
|
+
score = parse_score( col )
|
288
|
+
if score
|
289
|
+
score1 = score[0]
|
290
|
+
score2 = score[1]
|
291
|
+
else
|
292
|
+
puts "!! ERROR - invalid score (ft) format >#{col}<:"
|
293
|
+
pp row
|
294
|
+
exit 1
|
268
295
|
end
|
269
|
-
## todo/fix: issue warning if non-empty!!! and not matching format!!!!
|
270
296
|
end
|
271
297
|
|
272
298
|
if headers_mapping[ :scorei ]
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
score1i =
|
277
|
-
score2i =
|
299
|
+
col = row[ headers_mapping[ :scorei ]]
|
300
|
+
score = parse_score( col )
|
301
|
+
if score
|
302
|
+
score1i = score[0]
|
303
|
+
score2i = score[1]
|
304
|
+
else
|
305
|
+
puts "!! ERROR - invalid score (ht) format >#{col}<:"
|
306
|
+
pp row
|
307
|
+
exit 1
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
####
|
312
|
+
## try optional score - extra time (et) and penalities (p/pen)
|
313
|
+
score1et = nil
|
314
|
+
score2et = nil
|
315
|
+
score1p = nil
|
316
|
+
score2p = nil
|
317
|
+
|
318
|
+
if headers_mapping[ :score_et ]
|
319
|
+
col = row[ headers_mapping[ :score_et ]]
|
320
|
+
score = parse_score( col )
|
321
|
+
if score
|
322
|
+
score1et = score[0]
|
323
|
+
score2et = score[1]
|
324
|
+
else
|
325
|
+
puts "!! ERROR - invalid score (et) format >#{col}<:"
|
326
|
+
pp row
|
327
|
+
exit 1
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
if headers_mapping[ :score_p ]
|
332
|
+
col = row[ headers_mapping[ :score_p ]]
|
333
|
+
score = parse_score( col )
|
334
|
+
if score
|
335
|
+
score1p = score[0]
|
336
|
+
score2p = score[1]
|
337
|
+
else
|
338
|
+
puts "!! ERROR - invalid score (p) format >#{col}<:"
|
339
|
+
pp row
|
340
|
+
exit 1
|
278
341
|
end
|
279
|
-
## todo/fix: issue warning if non-empty!!! and not matching format!!!!
|
280
342
|
end
|
281
343
|
|
282
344
|
|
@@ -296,17 +358,51 @@ module SportDb
|
|
296
358
|
end
|
297
359
|
end
|
298
360
|
|
361
|
+
group = nil
|
362
|
+
if headers_mapping[ :group ]
|
363
|
+
col = row[ headers_mapping[ :group ]]
|
364
|
+
## todo/fix: check can col be nil e.g. col.nil? possible?
|
365
|
+
group = if col.nil? || col.empty? || col == '-' || col == 'n/a'
|
366
|
+
## note: allow missing stage for match / defaults to "regular"
|
367
|
+
nil
|
368
|
+
else
|
369
|
+
col
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
status = nil ## e.g. AWARDED, CANCELLED, POSTPONED, etc.
|
374
|
+
if headers_mapping[ :notes ]
|
375
|
+
col = row[ headers_mapping[ :notes ]]
|
376
|
+
## check for optional (match) status in notes / comments
|
377
|
+
status = if col.nil? || col.empty? || col == '-' || col == 'n/a'
|
378
|
+
nil
|
379
|
+
else
|
380
|
+
StatusParser.parse( col ) # note: returns nil if no (match) status found
|
381
|
+
end
|
382
|
+
end
|
383
|
+
|
384
|
+
|
299
385
|
league = nil
|
300
386
|
league = row[ headers_mapping[ :league ]] if headers_mapping[ :league ]
|
301
387
|
|
302
388
|
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
389
|
+
## puts 'match attributes:'
|
390
|
+
attributes = {
|
391
|
+
date: date,
|
392
|
+
team1: team1, team2: team2,
|
393
|
+
score1: score1, score2: score2,
|
394
|
+
score1i: score1i, score2i: score2i,
|
395
|
+
score1et: score1et, score2et: score2et,
|
396
|
+
score1p: score1p, score2p: score2p,
|
397
|
+
round: round,
|
398
|
+
stage: stage,
|
399
|
+
group: group,
|
400
|
+
status: status,
|
401
|
+
league: league
|
402
|
+
}
|
403
|
+
## pp attributes
|
404
|
+
|
405
|
+
match = Import::Match.new( **attributes )
|
310
406
|
matches << match
|
311
407
|
end
|
312
408
|
|
@@ -326,6 +422,37 @@ module SportDb
|
|
326
422
|
nil ## no matching header found!!!
|
327
423
|
end
|
328
424
|
|
425
|
+
########
|
426
|
+
# more helpers
|
427
|
+
#
|
428
|
+
|
429
|
+
def parse_score( str )
|
430
|
+
if str.nil? ## todo/check: remove nil case - possible? - why? why not?
|
431
|
+
[nil,nil]
|
432
|
+
else
|
433
|
+
## remove (optional single) note/footnote/endnote markers
|
434
|
+
## e.g. (*) or (a), (b),
|
435
|
+
## or [*], [A], [1], etc.
|
436
|
+
## - allow (1) or maybe (*1) in the future - why? why not?
|
437
|
+
str = str.sub( /\( [a-z*] \)
|
438
|
+
|
|
439
|
+
\[ [1-9a-z*] \]
|
440
|
+
/ix, '' ).strip
|
441
|
+
|
442
|
+
if str.empty? || str == '?' || str == '-' || str == 'n/a'
|
443
|
+
[nil,nil]
|
444
|
+
### todo/check: use regex with named capture groups here - why? why not?
|
445
|
+
elsif str =~ /^\d{1,2}[:-]\d{1,2}$/ ## sanity check scores format
|
446
|
+
score = str.split( /[:-]/ )
|
447
|
+
[score[0].to_i, score[1].to_i]
|
448
|
+
else
|
449
|
+
nil ## note: returns nil if invalid / unparseable format!!!
|
450
|
+
end
|
451
|
+
end
|
452
|
+
end # method parse_score
|
453
|
+
|
454
|
+
|
455
|
+
|
329
456
|
end # class CsvMatchParser
|
330
457
|
end # module SportDb
|
331
458
|
|