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.
- 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
|
+
|