sportdb-formats 1.0.6 → 1.1.4
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 -33
- data/Rakefile +2 -5
- data/lib/sportdb/formats.rb +54 -70
- data/lib/sportdb/formats/country/country_index.rb +2 -2
- data/lib/sportdb/formats/event/event_index.rb +141 -0
- data/lib/sportdb/formats/event/event_reader.rb +183 -0
- data/lib/sportdb/formats/league/league_index.rb +22 -18
- data/lib/sportdb/formats/league/league_outline_reader.rb +45 -13
- data/lib/sportdb/formats/league/league_reader.rb +7 -1
- data/lib/sportdb/formats/match/match_parser.rb +101 -111
- data/lib/sportdb/formats/package.rb +59 -11
- data/lib/sportdb/formats/parser_helper.rb +11 -2
- data/lib/sportdb/formats/team/club_index.rb +13 -11
- data/lib/sportdb/formats/team/club_index_history.rb +134 -0
- data/lib/sportdb/formats/team/club_reader_history.rb +203 -0
- data/lib/sportdb/formats/team/club_reader_props.rb +20 -5
- data/lib/sportdb/formats/version.rb +2 -2
- data/test/helper.rb +51 -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_regex.rb +25 -7
- metadata +9 -78
- data/lib/sportdb/formats/config.rb +0 -40
- data/lib/sportdb/formats/match/match_parser_csv.rb +0 -314
- data/lib/sportdb/formats/name_helper.rb +0 -84
- data/lib/sportdb/formats/score/score_formats.rb +0 -220
- data/lib/sportdb/formats/score/score_parser.rb +0 -202
- data/lib/sportdb/formats/season_utils.rb +0 -27
- data/lib/sportdb/formats/structs/country.rb +0 -31
- data/lib/sportdb/formats/structs/group.rb +0 -18
- data/lib/sportdb/formats/structs/league.rb +0 -37
- data/lib/sportdb/formats/structs/match.rb +0 -151
- data/lib/sportdb/formats/structs/matchlist.rb +0 -220
- data/lib/sportdb/formats/structs/round.rb +0 -25
- data/lib/sportdb/formats/structs/season.rb +0 -123
- data/lib/sportdb/formats/structs/standings.rb +0 -247
- data/lib/sportdb/formats/structs/team.rb +0 -150
- data/lib/sportdb/formats/structs/team_usage.rb +0 -88
- data/test/test_clubs.rb +0 -40
- 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_csv_reader.rb +0 -31
- data/test/test_match.rb +0 -30
- 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_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_worldcup.rb +0 -27
- data/test/test_name_helper.rb +0 -67
- data/test/test_scores.rb +0 -122
- data/test/test_season.rb +0 -62
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bcac09da9cbe9b0e7d703df7b6b5075025979655
|
4
|
+
data.tar.gz: 71b00a95c66920bd25c1d92d0b4a29a2ec4436e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81b387f334f672dbe493884bde8661dfd83c892a834bec422c95efc5231141f556397d5aacdfd7665e935589f5cffcedcbeab1f0993a414e8678ae56c89e80ab
|
7
|
+
data.tar.gz: ba6546d68cafa1198c39dec94d91481ec6652d051f3e9887b1366a1319a9a6b35667313390fac1bbae3cc46056468aff0d3bc41a8e128d429f0f9a16d2c7f998
|
data/Manifest.txt
CHANGED
@@ -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
|
-
['
|
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',
|
25
|
+
['rubyzip', '>= 1.2.4' ],
|
29
26
|
]
|
30
27
|
|
31
28
|
self.spec_extras = {
|
data/lib/sportdb/formats.rb
CHANGED
@@ -1,43 +1,9 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
|
4
1
|
## 3rd party gems
|
5
|
-
require '
|
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
|
-
|
19
|
+
|
57
20
|
require 'sportdb/formats/parser_helper'
|
58
21
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
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
|
-
|
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
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
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
|
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
|
###
|
@@ -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
|
+
|