sportdb-formats 1.0.6 → 1.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/Manifest.txt +6 -33
  3. data/Rakefile +2 -5
  4. data/lib/sportdb/formats.rb +54 -70
  5. data/lib/sportdb/formats/country/country_index.rb +2 -2
  6. data/lib/sportdb/formats/event/event_index.rb +141 -0
  7. data/lib/sportdb/formats/event/event_reader.rb +183 -0
  8. data/lib/sportdb/formats/league/league_index.rb +22 -18
  9. data/lib/sportdb/formats/league/league_outline_reader.rb +45 -13
  10. data/lib/sportdb/formats/league/league_reader.rb +7 -1
  11. data/lib/sportdb/formats/match/match_parser.rb +101 -111
  12. data/lib/sportdb/formats/package.rb +59 -11
  13. data/lib/sportdb/formats/parser_helper.rb +11 -2
  14. data/lib/sportdb/formats/team/club_index.rb +13 -11
  15. data/lib/sportdb/formats/team/club_index_history.rb +134 -0
  16. data/lib/sportdb/formats/team/club_reader_history.rb +203 -0
  17. data/lib/sportdb/formats/team/club_reader_props.rb +20 -5
  18. data/lib/sportdb/formats/version.rb +2 -2
  19. data/test/helper.rb +51 -81
  20. data/test/test_club_index_history.rb +107 -0
  21. data/test/test_club_reader_history.rb +212 -0
  22. data/test/test_datafile_package.rb +1 -1
  23. data/test/test_regex.rb +25 -7
  24. metadata +9 -78
  25. data/lib/sportdb/formats/config.rb +0 -40
  26. data/lib/sportdb/formats/match/match_parser_csv.rb +0 -314
  27. data/lib/sportdb/formats/name_helper.rb +0 -84
  28. data/lib/sportdb/formats/score/score_formats.rb +0 -220
  29. data/lib/sportdb/formats/score/score_parser.rb +0 -202
  30. data/lib/sportdb/formats/season_utils.rb +0 -27
  31. data/lib/sportdb/formats/structs/country.rb +0 -31
  32. data/lib/sportdb/formats/structs/group.rb +0 -18
  33. data/lib/sportdb/formats/structs/league.rb +0 -37
  34. data/lib/sportdb/formats/structs/match.rb +0 -151
  35. data/lib/sportdb/formats/structs/matchlist.rb +0 -220
  36. data/lib/sportdb/formats/structs/round.rb +0 -25
  37. data/lib/sportdb/formats/structs/season.rb +0 -123
  38. data/lib/sportdb/formats/structs/standings.rb +0 -247
  39. data/lib/sportdb/formats/structs/team.rb +0 -150
  40. data/lib/sportdb/formats/structs/team_usage.rb +0 -88
  41. data/test/test_clubs.rb +0 -40
  42. data/test/test_conf.rb +0 -65
  43. data/test/test_csv_match_parser.rb +0 -114
  44. data/test/test_csv_match_parser_utils.rb +0 -20
  45. data/test/test_csv_reader.rb +0 -31
  46. data/test/test_match.rb +0 -30
  47. data/test/test_match_auto.rb +0 -72
  48. data/test/test_match_auto_champs.rb +0 -45
  49. data/test/test_match_auto_euro.rb +0 -37
  50. data/test/test_match_auto_worldcup.rb +0 -61
  51. data/test/test_match_champs.rb +0 -27
  52. data/test/test_match_eng.rb +0 -26
  53. data/test/test_match_euro.rb +0 -27
  54. data/test/test_match_worldcup.rb +0 -27
  55. data/test/test_name_helper.rb +0 -67
  56. data/test/test_scores.rb +0 -122
  57. data/test/test_season.rb +0 -62
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 35a7be066d82d59b2cf35c8dc5676c0d5118479b
4
- data.tar.gz: eeceea13624ae5c795bc2b2709e7bef6727dd184
3
+ metadata.gz: bcac09da9cbe9b0e7d703df7b6b5075025979655
4
+ data.tar.gz: 71b00a95c66920bd25c1d92d0b4a29a2ec4436e3
5
5
  SHA512:
6
- metadata.gz: 732d53cf84db4d87449c9fe86e4c0b1109a277b8442a7fd15cf61a5318555e6a53c61c08ab1b66187429fc770f89e4a72ef48b9bde616e2736a96bb8d1a47324
7
- data.tar.gz: 60b46bf871ffd180bec2a3a96403ecceebc5689dde1d0c6181ecf1b22fdaf9b8aaf49bd8e15a8ba886cf9751e62fc89658376b27d983e8871003f498d6498c0e
6
+ metadata.gz: 81b387f334f672dbe493884bde8661dfd83c892a834bec422c95efc5231141f556397d5aacdfd7665e935589f5cffcedcbeab1f0993a414e8678ae56c89e80ab
7
+ data.tar.gz: ba6546d68cafa1198c39dec94d91481ec6652d051f3e9887b1366a1319a9a6b35667313390fac1bbae3cc46056468aff0d3bc41a8e128d429f0f9a16d2c7f998
@@ -3,11 +3,12 @@ Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
5
  lib/sportdb/formats.rb
6
- lib/sportdb/formats/config.rb
7
6
  lib/sportdb/formats/country/country_index.rb
8
7
  lib/sportdb/formats/country/country_reader.rb
9
8
  lib/sportdb/formats/datafile.rb
10
9
  lib/sportdb/formats/datafile_package.rb
10
+ lib/sportdb/formats/event/event_index.rb
11
+ lib/sportdb/formats/event/event_reader.rb
11
12
  lib/sportdb/formats/goals.rb
12
13
  lib/sportdb/formats/league/league_index.rb
13
14
  lib/sportdb/formats/league/league_outline_reader.rb
@@ -17,26 +18,13 @@ lib/sportdb/formats/match/mapper.rb
17
18
  lib/sportdb/formats/match/mapper_teams.rb
18
19
  lib/sportdb/formats/match/match_parser.rb
19
20
  lib/sportdb/formats/match/match_parser_auto_conf.rb
20
- lib/sportdb/formats/match/match_parser_csv.rb
21
- lib/sportdb/formats/name_helper.rb
22
21
  lib/sportdb/formats/outline_reader.rb
23
22
  lib/sportdb/formats/package.rb
24
23
  lib/sportdb/formats/parser_helper.rb
25
- lib/sportdb/formats/score/score_formats.rb
26
- lib/sportdb/formats/score/score_parser.rb
27
- lib/sportdb/formats/season_utils.rb
28
- lib/sportdb/formats/structs/country.rb
29
- lib/sportdb/formats/structs/group.rb
30
- lib/sportdb/formats/structs/league.rb
31
- lib/sportdb/formats/structs/match.rb
32
- lib/sportdb/formats/structs/matchlist.rb
33
- lib/sportdb/formats/structs/round.rb
34
- lib/sportdb/formats/structs/season.rb
35
- lib/sportdb/formats/structs/standings.rb
36
- lib/sportdb/formats/structs/team.rb
37
- lib/sportdb/formats/structs/team_usage.rb
38
24
  lib/sportdb/formats/team/club_index.rb
25
+ lib/sportdb/formats/team/club_index_history.rb
39
26
  lib/sportdb/formats/team/club_reader.rb
27
+ lib/sportdb/formats/team/club_reader_history.rb
40
28
  lib/sportdb/formats/team/club_reader_props.rb
41
29
  lib/sportdb/formats/team/national_team_index.rb
42
30
  lib/sportdb/formats/team/team_index.rb
@@ -44,35 +32,20 @@ lib/sportdb/formats/team/wiki_reader.rb
44
32
  lib/sportdb/formats/version.rb
45
33
  test/helper.rb
46
34
  test/test_club_index.rb
35
+ test/test_club_index_history.rb
47
36
  test/test_club_reader.rb
37
+ test/test_club_reader_history.rb
48
38
  test/test_club_reader_props.rb
49
- test/test_clubs.rb
50
- test/test_conf.rb
51
39
  test/test_country_index.rb
52
40
  test/test_country_reader.rb
53
- test/test_csv_match_parser.rb
54
- test/test_csv_match_parser_utils.rb
55
- test/test_csv_reader.rb
56
41
  test/test_datafile.rb
57
42
  test/test_datafile_package.rb
58
43
  test/test_goals.rb
59
44
  test/test_league_index.rb
60
45
  test/test_league_outline_reader.rb
61
46
  test/test_league_reader.rb
62
- test/test_match.rb
63
- test/test_match_auto.rb
64
- test/test_match_auto_champs.rb
65
- test/test_match_auto_euro.rb
66
- test/test_match_auto_worldcup.rb
67
- test/test_match_champs.rb
68
- test/test_match_eng.rb
69
- test/test_match_euro.rb
70
- test/test_match_worldcup.rb
71
- test/test_name_helper.rb
72
47
  test/test_outline_reader.rb
73
48
  test/test_package.rb
74
49
  test/test_package_match.rb
75
50
  test/test_regex.rb
76
- test/test_scores.rb
77
- test/test_season.rb
78
51
  test/test_wiki_reader.rb
data/Rakefile CHANGED
@@ -20,12 +20,9 @@ Hoe.spec 'sportdb-formats' do
20
20
  self.licenses = ['Public Domain']
21
21
 
22
22
  self.extra_deps = [
23
- ['alphabets', '>= 1.0.0'],
24
- ['date-formats', '>= 1.0.1'],
25
- ['csvreader', '>= 1.2.4'],
26
- ['sportdb-langs', '>= 0.1.0'],
23
+ ['sportdb-structs', '>= 0.1.0'],
27
24
 
28
- ['rubyzip', '>= 1.2.4' ],
25
+ ['rubyzip', '>= 1.2.4' ],
29
26
  ]
30
27
 
31
28
  self.spec_extras = {
@@ -1,43 +1,9 @@
1
- # encoding: utf-8
2
-
3
-
4
1
  ## 3rd party gems
5
- require 'alphabets' # downcase_i18n, unaccent, variants, ...
6
- require 'date/formats' # DateFormats.parse, find!, ...
7
- require 'csvreader'
8
-
9
- require 'zip' ## todo/check: if zip is alreay included in a required module
10
-
11
-
12
-
13
- def read_csv( path, sep: nil,
14
- symbolize_names: nil )
15
- opts = {}
16
- opts[:sep] = sep if sep
17
- opts[:header_converters] = :symbol if symbolize_names
18
-
19
- CsvHash.read( path, **opts )
20
- end
21
-
22
- def parse_csv( txt, sep: nil,
23
- symbolize_names: nil )
24
- opts = {}
25
- opts[:sep] = sep if sep
26
- opts[:header_converters] = :symbol if symbolize_names
2
+ require 'sportdb/structs'
27
3
 
28
- CsvHash.parse( txt, **opts )
29
- end
30
-
31
-
32
-
33
- ## more sportdb libs/gems
34
- require 'sportdb/langs'
35
4
 
5
+ require 'zip' ## todo/check: if zip is alreay included in a required module
36
6
 
37
- ## todo/fix: move shortcut to sportdb/langs!!!
38
- module SportDb
39
- Logging = LogUtils::Logging ## logging machinery shortcut; use LogUtils for now
40
- end
41
7
 
42
8
 
43
9
 
@@ -45,41 +11,59 @@ end
45
11
  # our own code
46
12
  require 'sportdb/formats/version' # let version always go first
47
13
 
48
- require 'sportdb/formats/config' # let "global" config "framework" go next - why? why not?
49
-
50
14
  require 'sportdb/formats/outline_reader'
51
15
  require 'sportdb/formats/datafile'
52
16
  require 'sportdb/formats/datafile_package'
53
17
  require 'sportdb/formats/package'
54
- require 'sportdb/formats/season_utils'
55
18
 
56
- require 'sportdb/formats/name_helper'
19
+
57
20
  require 'sportdb/formats/parser_helper'
58
21
 
59
- require 'sportdb/formats/structs/country'
60
- require 'sportdb/formats/structs/season'
61
- require 'sportdb/formats/structs/league'
62
- require 'sportdb/formats/structs/team'
63
- require 'sportdb/formats/structs/round'
64
- require 'sportdb/formats/structs/group'
65
- require 'sportdb/formats/structs/match'
66
- require 'sportdb/formats/structs/matchlist'
67
- require 'sportdb/formats/structs/standings'
68
- require 'sportdb/formats/structs/team_usage'
22
+
23
+ module SportDb
24
+ module Import
25
+ Season = ::Season ## add a convenience alias for top-level Season class
26
+
27
+ ## add "old" convenience aliases for structs - why? why not?
28
+ ## todo/check: just use include Sports !!!!
29
+ Country = ::Sports::Country
30
+ League = ::Sports::League
31
+ Group = ::Sports::Group
32
+ Round = ::Sports::Round
33
+ Match = ::Sports::Match
34
+ Matchlist = ::Sports::Matchlist
35
+ Goal = ::Sports::Goal
36
+ Team = ::Sports::Team
37
+ NationalTeam = ::Sports::NationalTeam
38
+ Club = ::Sports::Club
39
+ Standings = ::Sports::Standings
40
+ TeamUsage = ::Sports::TeamUsage
41
+
42
+
43
+ class Team
44
+ ## add convenience lookup helper / method for name by season for now
45
+ ## use clubs history - for now kept separate from struct - why? why not?
46
+ def name_by_season( season )
47
+ ## note: returns / fallback to "regular" name if no records found in history
48
+ SportDb::Import.catalog.clubs_history.find_name_by( name: name, season: season ) || name
49
+ end
50
+ end # class Team
51
+
52
+ end # module Import
53
+ end # module SportDb
69
54
 
70
55
 
71
- require 'sportdb/formats/score/score_formats'
72
- require 'sportdb/formats/score/score_parser'
73
56
  require 'sportdb/formats/goals'
74
57
 
75
58
 
59
+
76
60
  require 'sportdb/formats/match/mapper'
77
61
  require 'sportdb/formats/match/mapper_teams'
78
62
  require 'sportdb/formats/match/match_parser'
79
63
  require 'sportdb/formats/match/match_parser_auto_conf'
80
64
  require 'sportdb/formats/match/conf_parser'
81
65
 
82
- require 'sportdb/formats/match/match_parser_csv'
66
+
83
67
 
84
68
  require 'sportdb/formats/country/country_reader'
85
69
  require 'sportdb/formats/country/country_index'
@@ -119,11 +103,15 @@ require 'sportdb/formats/team/wiki_reader'
119
103
  require 'sportdb/formats/team/national_team_index'
120
104
  require 'sportdb/formats/team/team_index'
121
105
 
106
+ require 'sportdb/formats/team/club_reader_history'
107
+ require 'sportdb/formats/team/club_index_history'
108
+
122
109
 
123
110
  ###
124
111
  # add convenience helpers / shortcuts
125
112
  module SportDb
126
- module Import
113
+ module Import
114
+
127
115
  class Club
128
116
  def self.read( path ) ClubReader.read( path ); end
129
117
  def self.parse( txt ) ClubReader.parse( txt ); end
@@ -132,31 +120,27 @@ class Club
132
120
  def self.parse_props( txt ) ClubPropsReader.parse( txt ); end
133
121
  ## todo/check: use ClubProps.read and ClubProps.parse convenience alternate shortcuts - why? why not?
134
122
  end # class Club
123
+
135
124
  end # module Import
136
125
  end # module SportDb
137
126
 
138
127
 
128
+ require 'sportdb/formats/event/event_reader'
129
+ require 'sportdb/formats/event/event_index'
139
130
 
140
-
141
-
142
-
143
-
144
-
145
-
146
-
147
- ## let's put test configuration in its own namespace / module
131
+ ## add convenience helper
148
132
  module SportDb
149
- class Test ## todo/check: works with module too? use a module - why? why not?
150
-
151
- ####
152
- # todo/fix: find a better way to configure shared test datasets - why? why not?
153
- # note: use one-up (..) directory for now as default - why? why not?
154
- def self.data_dir() @data_dir ||= '../test'; end
155
- def self.data_dir=( path ) @data_dir = path; end
156
- end
133
+ module Import
134
+ class EventInfo
135
+ def self.read( path ) EventInfoReader.read( path ); end
136
+ def self.parse( txt ) EventInfoReader.parse( txt ); end
137
+ end # class EventInfo
138
+ end # module Import
157
139
  end # module SportDb
158
140
 
159
141
 
160
142
 
161
143
 
144
+
145
+
162
146
  puts SportDb::Module::Formats.banner # say hello
@@ -109,12 +109,12 @@ class CountryIndex
109
109
  @countries_by_name[ name ]
110
110
  end
111
111
 
112
- def []( key )
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 :find, :[]
117
+ alias_method :[], :find
118
118
 
119
119
 
120
120
  ###
@@ -0,0 +1,141 @@
1
+ module SportDb
2
+ module Import
3
+
4
+
5
+
6
+ class EventIndex
7
+
8
+ def self.build( path )
9
+ pack = Package.new( path ) ## lets us use direcotry or zip archive
10
+
11
+ recs = []
12
+ pack.each_seasons do |entry|
13
+ recs += EventInfoReader.parse( entry.read )
14
+ end
15
+ recs
16
+
17
+ index = new
18
+ index.add( recs )
19
+ index
20
+ end
21
+
22
+
23
+
24
+ attr_reader :events
25
+ def initialize
26
+ @events = []
27
+ @leagues = {}
28
+ end
29
+
30
+ def add( recs )
31
+ @events += recs ## add to "linear" records
32
+
33
+ recs.each do |rec|
34
+ league = rec.league
35
+ season = rec.season
36
+
37
+ seasons = @leagues[ league.key ] ||= {}
38
+ seasons[season.key] = rec
39
+ end
40
+ ## build search index by leagues (and season)
41
+ end
42
+
43
+ def find_by( league:, season: )
44
+ league_key = league.is_a?( String ) ? league : league.key
45
+ season_key = season.is_a?( String ) ? season : season.key
46
+
47
+ seasons = @leagues[ league_key ]
48
+ if seasons
49
+ seasons[ season_key ]
50
+ else
51
+ nil
52
+ end
53
+ end # method find_by
54
+ end ## class EventIndex
55
+
56
+
57
+
58
+ class SeasonIndex
59
+ def initialize( *args )
60
+ @leagues = {} ## use a league hash by years for now; change later
61
+
62
+ if args.size == 1 && args[0].is_a?( EventIndex )
63
+ ## convenience setup/hookup
64
+ ## (auto-)add all events from event index
65
+ add( args[0].events )
66
+ else
67
+ pp args
68
+ raise ArgumentError.new( 'unsupported arguments' )
69
+ end
70
+ end
71
+
72
+ def add( recs )
73
+ ## use a lookup index by year for now
74
+ ## todo - find something better/more generic for searching/matching date periods!!!
75
+ recs.each do |rec|
76
+ league = rec.league
77
+ season = rec.season
78
+
79
+ years = @leagues[ league.key ] ||= {}
80
+ if season.year?
81
+ years[season.start_year] ||= []
82
+ years[season.start_year] << rec
83
+ else
84
+ years[season.start_year] ||= []
85
+ years[season.end_year] ||= []
86
+ years[season.start_year] << rec
87
+ years[season.end_year] << rec
88
+ end
89
+ end
90
+ end # method add
91
+
92
+ def find_by( date:, league: )
93
+ date = Date.strptime( date, '%Y-%m-%d' ) if date.is_a?( String )
94
+ league_key = league.is_a?( String ) ? league : league.key
95
+
96
+ years = @leagues[ league_key ]
97
+ if years
98
+ year = years[ date.year ]
99
+ if year
100
+ season_key = nil
101
+ year.each do |event|
102
+ ## todo/check: rename/use between? instead of include? - why? why not?
103
+ if event.include?( date )
104
+ season_key = event.season.key
105
+ break
106
+ end
107
+ end
108
+ if season_key.nil?
109
+ puts "!! WARN: date >#{date}< out-of-seasons for year #{date.year} in league #{league_key}:"
110
+ year.each do |event|
111
+ puts " #{event.season.key} | #{event.start_date} - #{event.end_date}"
112
+ end
113
+ ## retry again and pick season with "overflow" at the end (date is great end_date)
114
+ year.each do |event|
115
+ if date > event.end_date
116
+ diff_in_days = date.to_date.jd - event.end_date.to_date.jd
117
+ puts " +#{diff_in_days} days - adding overflow to #{event.season.key} ending on #{event.end_date} ++ #{date}"
118
+ season_key = event.season.key
119
+ break
120
+ end
121
+ end
122
+ ## exit now for sure - if still empty!!!!
123
+ if season_key.nil?
124
+ puts "!! ERROR: CANNOT auto-fix / (auto-)append date at the end of an event; check season setup - sorry"
125
+ exit 1
126
+ end
127
+ end
128
+ season_key
129
+ else
130
+ nil ## no year defined / found for league
131
+ end
132
+ else
133
+ nil ## no league defined / found
134
+ end
135
+ end # method find
136
+
137
+ end # class SeasonIndex
138
+
139
+
140
+ end # module Import
141
+ end # module SportDb
@@ -0,0 +1,183 @@
1
+
2
+ module SportDb
3
+ module Import
4
+
5
+
6
+ class EventInfo
7
+ ## "high level" info (summary) about event (like a "wikipedia infobox")
8
+ ## use for checking dataset imports; lets you check e.g.
9
+ ## - dates within range
10
+ ## - number of teams e.g. 20
11
+ ## - matches played e.g. 380
12
+ ## - goals scored e.g. 937
13
+ ## etc.
14
+
15
+ attr_reader :league,
16
+ :season,
17
+ :teams,
18
+ :matches,
19
+ :goals,
20
+ :start_date,
21
+ :end_date
22
+
23
+ def initialize( league:, season:,
24
+ start_date: nil, end_date: nil,
25
+ teams: nil,
26
+ matches: nil,
27
+ goals: nil )
28
+
29
+ @league = league
30
+ @season = season
31
+
32
+ @start_date = start_date
33
+ @end_date = end_date
34
+
35
+ @teams = teams ## todo/check: rename/use teams_count ??
36
+ @matches = matches ## todo/check: rename/use match_count ??
37
+ @goals = goals
38
+ end
39
+
40
+ def include?( date )
41
+ ## todo/fix: add options e.g.
42
+ ## - add delta/off_by_one or such?
43
+ ## - add strict (for) only return true if date range (really) defined (no generic auto-rules)
44
+
45
+ ### note: for now allow off by one error (via timezone/local time errors)
46
+ ## todo/fix: issue warning if off by one!!!!
47
+ if @start_date && @end_date
48
+ date >= (@start_date-1) &&
49
+ date <= (@end_date+1)
50
+ else
51
+ if @season.year?
52
+ # assume generic rule
53
+ ## same year e.g. Jan 1 - Dec 31; always true for now
54
+ date.year == @season.start_year
55
+ else
56
+ # assume generic rule
57
+ ## July 1 - June 30 (Y+1)
58
+ ## - todo/check -start for some countries/leagues in June 1 or August 1 ????
59
+ date >= Date.new( @season.start_year, 7, 1 ) &&
60
+ date <= Date.new( @season.end_year, 6, 30 )
61
+ end
62
+ end
63
+ end # method include?
64
+ alias_method :between?, :include?
65
+ end # class EventInfo
66
+
67
+
68
+ class EventInfoReader
69
+ def catalog() Import.catalog; end
70
+
71
+
72
+ def self.read( path )
73
+ txt = File.open( path, 'r:utf-8') {|f| f.read }
74
+ new( txt ).parse
75
+ end
76
+
77
+ def self.parse( txt )
78
+ new( txt ).parse
79
+ end
80
+
81
+ def initialize( txt )
82
+ @txt = txt
83
+ end
84
+
85
+ def parse
86
+ recs = []
87
+
88
+ parse_csv( @txt ).each do |row|
89
+ league_col = row['League']
90
+ season_col = row['Season'] || row['Year']
91
+ dates_col = row['Dates']
92
+
93
+ season = Import::Season.parse( season_col )
94
+ league = catalog.leagues.find!( league_col )
95
+
96
+
97
+ dates = []
98
+ if dates_col.nil? || dates_col.empty?
99
+ ## do nothing; no dates - keep dates array empty
100
+ else
101
+ ## squish spaces
102
+ dates_col = dates_col.gsub( /[ ]{2,}/, ' ' ) ## squish/fold spaces
103
+
104
+ puts "#{league.name} (#{league.key}) | #{season.key} | #{dates_col}"
105
+
106
+ ### todo/check: check what parts "Aug 15" return ???
107
+ ### short form for "Aug 15 -" - works?
108
+
109
+ ## todo/fix!!! - check EventInfo.include?
110
+ ## now allow dates with only start_date too!! (WITHOUT end_date)
111
+ parts = dates_col.split( /[ ]*[–-][ ]*/ )
112
+ if parts.size == 1
113
+ pp parts
114
+ dates << DateFormats.parse( parts[0], start: Date.new( season.start_year, 1, 1 ), lang: 'en' )
115
+ pp dates
116
+ elsif parts.size == 2
117
+ pp parts
118
+ dates << DateFormats.parse( parts[0], start: Date.new( season.start_year, 1, 1 ), lang: 'en' )
119
+ dates << DateFormats.parse( parts[1], start: Date.new( season.end_year ? season.end_year : season.start_year, 1, 1 ), lang: 'en' )
120
+ pp dates
121
+
122
+ ## assert/check if period is less than 365 days for now
123
+ diff = dates[1].to_date.jd - dates[0].to_date.jd
124
+ puts "#{diff}d"
125
+ if diff > 365
126
+ puts "!! ERROR - date range / period assertion failed; expected diff < 365 days"
127
+ exit 1
128
+ end
129
+ else
130
+ puts "!! ERRROR - expected data range / period - one or two dates; got #{parts.size}:"
131
+ pp dates_col
132
+ pp parts
133
+ exit 1
134
+ end
135
+ end
136
+
137
+
138
+ teams_col = row['Clubs'] || row['Teams']
139
+ goals_col = row['Goals']
140
+
141
+ ## note: remove (and allow) all non-digits e.g. 370 goals, 20 clubs, etc.
142
+ teams_col = teams_col.gsub( /[^0-9]/, '' ) if teams_col
143
+ goals_col = goals_col.gsub( /[^0-9]/, '' ) if goals_col
144
+
145
+ teams = (teams_col.nil? || teams_col.empty?) ? nil : teams_col.to_i
146
+ goals = (goals_col.nil? || goals_col.empty?) ? nil : goals_col.to_i
147
+
148
+ matches_col = row['Matches']
149
+ ## note: support additions in matches (played) e.g.
150
+ # 132 + 63 Play-off-Spiele
151
+ matches_col = matches_col.gsub( /[^0-9+]/, '' ) if matches_col
152
+
153
+ matches = if matches_col.nil? || matches_col.empty?
154
+ nil
155
+ else
156
+ if matches_col.index( '+' ) ### check for calculations
157
+ ## note: for now only supports additions
158
+ matches_col.split( '+' ).reduce( 0 ) do |sum,str|
159
+ sum + str.to_i
160
+ end
161
+ else ## assume single (integer) number
162
+ matches_col.to_i
163
+ end
164
+ end
165
+
166
+ rec = EventInfo.new( league: league,
167
+ season: season,
168
+ start_date: dates[0],
169
+ end_date: dates[1],
170
+ teams: teams,
171
+ matches: matches,
172
+ goals: goals
173
+ )
174
+ recs << rec
175
+ end # each row
176
+ recs
177
+ end # method parse
178
+ end # class EventInfoReader
179
+
180
+
181
+ end ## module Import
182
+ end ## module SportDb
183
+