football-sources 0.1.0 → 0.2.0
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 +5 -5
- data/CHANGELOG.md +6 -4
- data/Manifest.txt +2 -20
- data/README.md +30 -169
- data/Rakefile +36 -31
- data/bin/fbgen +131 -0
- data/lib/football/sources.rb +6 -6
- data/lib/football-sources/process.rb +68 -0
- data/lib/football-sources/version.rb +19 -19
- data/lib/football-sources.rb +21 -57
- metadata +51 -40
- data/lib/football-sources/apis/config.rb +0 -17
- data/lib/football-sources/apis/convert.rb +0 -239
- data/lib/football-sources/apis/convert_cl.rb +0 -267
- data/lib/football-sources/apis/mods.rb +0 -20
- data/lib/football-sources/apis/stat.rb +0 -59
- data/lib/football-sources/apis.rb +0 -10
- data/lib/football-sources/fbref/build.rb +0 -96
- data/lib/football-sources/fbref/config.rb +0 -16
- data/lib/football-sources/fbref/convert.rb +0 -95
- data/lib/football-sources/fbref.rb +0 -4
- data/lib/football-sources/worldfootball/build.rb +0 -245
- data/lib/football-sources/worldfootball/config.rb +0 -16
- data/lib/football-sources/worldfootball/convert.rb +0 -100
- data/lib/football-sources/worldfootball/convert_reports.rb +0 -107
- data/lib/football-sources/worldfootball/jobs.rb +0 -76
- data/lib/football-sources/worldfootball/mods.rb +0 -72
- data/lib/football-sources/worldfootball/vacuum.rb +0 -66
- data/lib/football-sources/worldfootball.rb +0 -19
- data/test/helper.rb +0 -8
- data/test/test_version.rb +0 -16
metadata
CHANGED
@@ -1,43 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: football-sources
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-07-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: sportdb-catalogs
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0
|
19
|
+
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name: sportdb-
|
28
|
+
name: sportdb-writers
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: footballdata-api
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: worldfootball
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
30
58
|
requirements:
|
31
59
|
- - ">="
|
32
60
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
61
|
+
version: '0'
|
34
62
|
type: :runtime
|
35
63
|
prerelease: false
|
36
64
|
version_requirements: !ruby/object:Gem::Requirement
|
37
65
|
requirements:
|
38
66
|
- - ">="
|
39
67
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
68
|
+
version: '0'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: rdoc
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -64,18 +92,19 @@ dependencies:
|
|
64
92
|
requirements:
|
65
93
|
- - "~>"
|
66
94
|
- !ruby/object:Gem::Version
|
67
|
-
version: '
|
95
|
+
version: '4.1'
|
68
96
|
type: :development
|
69
97
|
prerelease: false
|
70
98
|
version_requirements: !ruby/object:Gem::Requirement
|
71
99
|
requirements:
|
72
100
|
- - "~>"
|
73
101
|
- !ruby/object:Gem::Version
|
74
|
-
version: '
|
75
|
-
description: football-sources - get football data
|
76
|
-
calls
|
77
|
-
email:
|
78
|
-
executables:
|
102
|
+
version: '4.1'
|
103
|
+
description: football-sources - get football match data (leagues, cups & more) via
|
104
|
+
web pages or web api (json) calls
|
105
|
+
email: gerald.bauer@gmail.com
|
106
|
+
executables:
|
107
|
+
- fbgen
|
79
108
|
extensions: []
|
80
109
|
extra_rdoc_files:
|
81
110
|
- CHANGELOG.md
|
@@ -86,34 +115,16 @@ files:
|
|
86
115
|
- Manifest.txt
|
87
116
|
- README.md
|
88
117
|
- Rakefile
|
118
|
+
- bin/fbgen
|
89
119
|
- lib/football-sources.rb
|
90
|
-
- lib/football-sources/
|
91
|
-
- lib/football-sources/apis/config.rb
|
92
|
-
- lib/football-sources/apis/convert.rb
|
93
|
-
- lib/football-sources/apis/convert_cl.rb
|
94
|
-
- lib/football-sources/apis/mods.rb
|
95
|
-
- lib/football-sources/apis/stat.rb
|
96
|
-
- lib/football-sources/fbref.rb
|
97
|
-
- lib/football-sources/fbref/build.rb
|
98
|
-
- lib/football-sources/fbref/config.rb
|
99
|
-
- lib/football-sources/fbref/convert.rb
|
120
|
+
- lib/football-sources/process.rb
|
100
121
|
- lib/football-sources/version.rb
|
101
|
-
- lib/football-sources/worldfootball.rb
|
102
|
-
- lib/football-sources/worldfootball/build.rb
|
103
|
-
- lib/football-sources/worldfootball/config.rb
|
104
|
-
- lib/football-sources/worldfootball/convert.rb
|
105
|
-
- lib/football-sources/worldfootball/convert_reports.rb
|
106
|
-
- lib/football-sources/worldfootball/jobs.rb
|
107
|
-
- lib/football-sources/worldfootball/mods.rb
|
108
|
-
- lib/football-sources/worldfootball/vacuum.rb
|
109
122
|
- lib/football/sources.rb
|
110
|
-
- test/helper.rb
|
111
|
-
- test/test_version.rb
|
112
123
|
homepage: https://github.com/sportdb/sport.db
|
113
124
|
licenses:
|
114
125
|
- Public Domain
|
115
126
|
metadata: {}
|
116
|
-
post_install_message:
|
127
|
+
post_install_message:
|
117
128
|
rdoc_options:
|
118
129
|
- "--main"
|
119
130
|
- README.md
|
@@ -130,9 +141,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
130
141
|
- !ruby/object:Gem::Version
|
131
142
|
version: '0'
|
132
143
|
requirements: []
|
133
|
-
|
134
|
-
|
135
|
-
signing_key:
|
144
|
+
rubygems_version: 3.4.10
|
145
|
+
signing_key:
|
136
146
|
specification_version: 4
|
137
|
-
summary: football-sources - get football data
|
147
|
+
summary: football-sources - get football match data (leagues, cups & more) via web
|
148
|
+
pages or web api (json) calls
|
138
149
|
test_files: []
|
@@ -1,17 +0,0 @@
|
|
1
|
-
|
2
|
-
module Footballdata
|
3
|
-
|
4
|
-
### add some more config options / settings
|
5
|
-
class Configuration
|
6
|
-
#########
|
7
|
-
## nested configuration classes - use - why? why not?
|
8
|
-
class Convert
|
9
|
-
def out_dir() @out_dir || './o'; end
|
10
|
-
def out_dir=(value) @out_dir = value; end
|
11
|
-
end
|
12
|
-
|
13
|
-
def convert() @convert ||= Convert.new; end
|
14
|
-
end # class Configuration
|
15
|
-
|
16
|
-
|
17
|
-
end # module Footballdata
|
@@ -1,239 +0,0 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
module Footballdata
|
4
|
-
|
5
|
-
|
6
|
-
def self.convert( league:, season: )
|
7
|
-
|
8
|
-
### note/fix: cl (champions league for now is a "special" case)
|
9
|
-
if league.downcase == 'cl'
|
10
|
-
convert_cl( league: league,
|
11
|
-
season: season )
|
12
|
-
return
|
13
|
-
end
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
season = Season( season ) ## cast (ensure) season class (NOT string, integer, etc.)
|
18
|
-
|
19
|
-
data = Webcache.read_json( Metal.competition_matches_url( LEAGUES[league.downcase], season.start_year ))
|
20
|
-
data_teams = Webcache.read_json( Metal.competition_teams_url( LEAGUES[league.downcase], season.start_year ))
|
21
|
-
|
22
|
-
|
23
|
-
## build a (reverse) team lookup by name
|
24
|
-
puts "#{data_teams['teams'].size} teams"
|
25
|
-
|
26
|
-
teams_by_name = data_teams['teams'].reduce( {} ) do |h,rec|
|
27
|
-
h[ rec['name'] ] = rec
|
28
|
-
h
|
29
|
-
end
|
30
|
-
|
31
|
-
pp teams_by_name.keys
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
mods = MODS[ league.downcase ] || {}
|
36
|
-
|
37
|
-
|
38
|
-
recs = []
|
39
|
-
|
40
|
-
teams = Hash.new( 0 )
|
41
|
-
|
42
|
-
stat = Stat.new
|
43
|
-
|
44
|
-
matches = data[ 'matches']
|
45
|
-
matches.each do |m|
|
46
|
-
stat.update( m )
|
47
|
-
|
48
|
-
team1 = m['homeTeam']['name']
|
49
|
-
team2 = m['awayTeam']['name']
|
50
|
-
|
51
|
-
score = m['score']
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
if m['stage'] == 'REGULAR_SEASON'
|
56
|
-
teams[ team1 ] += 1
|
57
|
-
teams[ team2 ] += 1
|
58
|
-
|
59
|
-
### mods - rename club names
|
60
|
-
unless mods.nil? || mods.empty?
|
61
|
-
team1 = mods[ team1 ] if mods[ team1 ]
|
62
|
-
team2 = mods[ team2 ] if mods[ team2 ]
|
63
|
-
end
|
64
|
-
|
65
|
-
|
66
|
-
## e.g. "utcDate": "2020-05-09T00:00:00Z",
|
67
|
-
date_str = m['utcDate']
|
68
|
-
date = DateTime.strptime( date_str, '%Y-%m-%dT%H:%M:%SZ' )
|
69
|
-
|
70
|
-
|
71
|
-
comments = ''
|
72
|
-
ft = ''
|
73
|
-
ht = ''
|
74
|
-
|
75
|
-
case m['status']
|
76
|
-
when 'SCHEDULED', 'IN_PLAY'
|
77
|
-
ft = ''
|
78
|
-
ht = ''
|
79
|
-
when 'FINISHED'
|
80
|
-
## todo/fix: assert duration == "REGULAR"
|
81
|
-
ft = "#{score['fullTime']['homeTeam']}-#{score['fullTime']['awayTeam']}"
|
82
|
-
ht = "#{score['halfTime']['homeTeam']}-#{score['halfTime']['awayTeam']}"
|
83
|
-
when 'AWARDED'
|
84
|
-
## todo/fix: assert duration == "REGULAR"
|
85
|
-
ft = "#{score['fullTime']['homeTeam']}-#{score['fullTime']['awayTeam']}"
|
86
|
-
ft << ' (*)'
|
87
|
-
ht = ''
|
88
|
-
comments = 'awarded'
|
89
|
-
when 'CANCELLED'
|
90
|
-
ft = '(*)'
|
91
|
-
ht = ''
|
92
|
-
comments = 'canceled' ## us eng ? -> canceled, british eng. cancelled ?
|
93
|
-
when 'POSTPONED'
|
94
|
-
ft = '(*)'
|
95
|
-
ht = ''
|
96
|
-
comments = 'postponed'
|
97
|
-
else
|
98
|
-
puts "!! ERROR: unsupported match status >#{m['status']}< - sorry:"
|
99
|
-
pp m
|
100
|
-
exit 1
|
101
|
-
end
|
102
|
-
|
103
|
-
|
104
|
-
## todo/fix: assert matchday is a number e.g. 1,2,3, etc.!!!
|
105
|
-
recs << [m['matchday'],
|
106
|
-
date.to_date.strftime( '%Y-%m-%d' ),
|
107
|
-
team1,
|
108
|
-
ft,
|
109
|
-
ht,
|
110
|
-
team2,
|
111
|
-
comments
|
112
|
-
]
|
113
|
-
|
114
|
-
|
115
|
-
print '%2s' % m['matchday']
|
116
|
-
print ' - '
|
117
|
-
print '%-24s' % team1
|
118
|
-
print ' '
|
119
|
-
print ft
|
120
|
-
print ' '
|
121
|
-
print "(#{ht})" unless ht.empty?
|
122
|
-
print ' '
|
123
|
-
print '%-24s' % team2
|
124
|
-
print ' '
|
125
|
-
print comments
|
126
|
-
print ' | '
|
127
|
-
## print date.to_date ## strip time
|
128
|
-
print date.to_date.strftime( '%a %b %-d %Y' )
|
129
|
-
print ' -- '
|
130
|
-
print date
|
131
|
-
print "\n"
|
132
|
-
else
|
133
|
-
puts "-- skipping #{m['stage']}"
|
134
|
-
end
|
135
|
-
end # each match
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
## note: get season from first match
|
140
|
-
## assert - all other matches include the same season
|
141
|
-
## e.g.
|
142
|
-
# "season": {
|
143
|
-
# "id": 154,
|
144
|
-
# "startDate": "2018-08-03",
|
145
|
-
# "endDate": "2019-05-05",
|
146
|
-
# "currentMatchday": 46
|
147
|
-
# }
|
148
|
-
|
149
|
-
start_date = Date.strptime( matches[0]['season']['startDate'], '%Y-%m-%d' )
|
150
|
-
end_date = Date.strptime( matches[0]['season']['endDate'], '%Y-%m-%d' )
|
151
|
-
|
152
|
-
dates = "#{start_date.strftime('%b %-d')} - #{end_date.strftime('%b %-d')}"
|
153
|
-
|
154
|
-
buf = ''
|
155
|
-
buf << "#{season.key} (#{dates}) - "
|
156
|
-
buf << "#{teams.keys.size} clubs, "
|
157
|
-
buf << "#{stat[:regular_season][:matches]} matches, "
|
158
|
-
buf << "#{stat[:regular_season][:goals]} goals"
|
159
|
-
buf << "\n"
|
160
|
-
|
161
|
-
puts buf
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
## note: warn if stage is greater one and not regular season!!
|
166
|
-
File.open( './errors.txt' , 'a:utf-8' ) do |f|
|
167
|
-
if stat[:all][:stage].keys != ['REGULAR_SEASON']
|
168
|
-
f.write "!! WARN - league: #{league}, season: #{season.key} includes non-regular stage(s):\n"
|
169
|
-
f.write " #{stat[:all][:stage].keys.inspect}\n"
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
|
174
|
-
File.open( './logs.txt', 'a:utf-8' ) do |f|
|
175
|
-
f.write "\n================================\n"
|
176
|
-
f.write "==== #{league} =============\n"
|
177
|
-
f.write buf
|
178
|
-
f.write " match status: #{stat[:regular_season][:status].inspect}\n"
|
179
|
-
f.write " match duration: #{stat[:regular_season][:duration].inspect}\n"
|
180
|
-
|
181
|
-
f.write "#{teams.keys.size} teams:\n"
|
182
|
-
teams.each do |name, count|
|
183
|
-
rec = teams_by_name[ name ]
|
184
|
-
f.write " #{count}x #{name}"
|
185
|
-
if rec
|
186
|
-
f.write " | #{rec['shortName']} " if name != rec['shortName']
|
187
|
-
f.write " › #{rec['area']['name']}"
|
188
|
-
f.write " - #{rec['address']}"
|
189
|
-
else
|
190
|
-
puts "!! ERROR - no team record found in teams.json for >#{name}<"
|
191
|
-
exit 1
|
192
|
-
end
|
193
|
-
f.write "\n"
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
# recs = recs.sort { |l,r| l[1] <=> r[1] }
|
201
|
-
## reformat date / beautify e.g. Sat Aug 7 1993
|
202
|
-
recs.each { |rec| rec[1] = Date.strptime( rec[1], '%Y-%m-%d' ).strftime( '%a %b %-d %Y' ) }
|
203
|
-
|
204
|
-
headers = [
|
205
|
-
'Matchday',
|
206
|
-
'Date',
|
207
|
-
'Team 1',
|
208
|
-
'FT',
|
209
|
-
'HT',
|
210
|
-
'Team 2',
|
211
|
-
'Comments'
|
212
|
-
]
|
213
|
-
|
214
|
-
## note: change season_key from 2019/20 to 2019-20 (for path/directory!!!!)
|
215
|
-
Cache::CsvMatchWriter.write( "#{config.convert.out_dir}/#{season.to_path}/#{league.downcase}.csv",
|
216
|
-
recs,
|
217
|
-
headers: headers )
|
218
|
-
|
219
|
-
|
220
|
-
teams.each do |name, count|
|
221
|
-
rec = teams_by_name[ name ]
|
222
|
-
print " #{count}x "
|
223
|
-
print name
|
224
|
-
if rec
|
225
|
-
print " | #{rec['shortName']} " if name != rec['shortName']
|
226
|
-
print " › #{rec['area']['name']}"
|
227
|
-
print " - #{rec['address']}"
|
228
|
-
else
|
229
|
-
puts "!! ERROR - no team record found in teams.json for #{name}"
|
230
|
-
exit 1
|
231
|
-
end
|
232
|
-
print "\n"
|
233
|
-
end
|
234
|
-
|
235
|
-
pp stat
|
236
|
-
end # method convert
|
237
|
-
end # module Footballdata
|
238
|
-
|
239
|
-
|
@@ -1,267 +0,0 @@
|
|
1
|
-
##########
|
2
|
-
## todo/fix:
|
3
|
-
## use a more generic name?
|
4
|
-
## might also works for euro or worldcup - check?
|
5
|
-
|
6
|
-
|
7
|
-
module Footballdata
|
8
|
-
|
9
|
-
|
10
|
-
STAGE_TO_STAGE = {
|
11
|
-
'PRELIMINARY_SEMI_FINALS' => 'Qualifying',
|
12
|
-
'PRELIMINARY_FINAL' => 'Qualifying',
|
13
|
-
'1ST_QUALIFYING_ROUND' => 'Qualifying',
|
14
|
-
'2ND_QUALIFYING_ROUND' => 'Qualifying',
|
15
|
-
'3RD_QUALIFYING_ROUND' => 'Qualifying',
|
16
|
-
'PLAY_OFF_ROUND' => 'Qualifying',
|
17
|
-
'ROUND_OF_16' => 'Knockout',
|
18
|
-
'QUARTER_FINALS' => 'Knockout',
|
19
|
-
'SEMI_FINALS' => 'Knockout',
|
20
|
-
'FINAL' => 'Knockout',
|
21
|
-
}
|
22
|
-
|
23
|
-
STAGE_TO_ROUND = {
|
24
|
-
'PRELIMINARY_SEMI_FINALS' => 'Preliminary Semifinals',
|
25
|
-
'PRELIMINARY_FINAL' => 'Preliminary Final',
|
26
|
-
'1ST_QUALIFYING_ROUND' => 'Qual. Round 1',
|
27
|
-
'2ND_QUALIFYING_ROUND' => 'Qual. Round 2',
|
28
|
-
'3RD_QUALIFYING_ROUND' => 'Qual. Round 3',
|
29
|
-
'PLAY_OFF_ROUND' => 'Playoff Round',
|
30
|
-
'ROUND_OF_16' => 'Round of 16',
|
31
|
-
'QUARTER_FINALS' => 'Quarterfinals',
|
32
|
-
'SEMI_FINALS' => 'Semifinals',
|
33
|
-
'FINAL' => 'Final',
|
34
|
-
}
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
def self.convert_cl( league:, season: )
|
40
|
-
season = Season( season ) ## cast (ensure) season class (NOT string, integer, etc.)
|
41
|
-
|
42
|
-
data = Webcache.read_json( Metal.competition_matches_url( LEAGUES[league.downcase], season.start_year ))
|
43
|
-
data_teams = Webcache.read_json( Metal.competition_teams_url( LEAGUES[league.downcase], season.start_year ))
|
44
|
-
|
45
|
-
|
46
|
-
## build a (reverse) team lookup by name
|
47
|
-
puts "#{data_teams['teams'].size} teams"
|
48
|
-
|
49
|
-
teams_by_name = data_teams['teams'].reduce( {} ) do |h,rec|
|
50
|
-
h[ rec['name'] ] = rec
|
51
|
-
h
|
52
|
-
end
|
53
|
-
|
54
|
-
pp teams_by_name.keys
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
mods = MODS[ league.downcase ] || {}
|
59
|
-
|
60
|
-
|
61
|
-
recs = []
|
62
|
-
|
63
|
-
teams = Hash.new( 0 )
|
64
|
-
stat = Stat.new
|
65
|
-
|
66
|
-
matches = data[ 'matches' ]
|
67
|
-
matches.each do |m|
|
68
|
-
stat.update( m )
|
69
|
-
|
70
|
-
team1 = m['homeTeam']['name']
|
71
|
-
team2 = m['awayTeam']['name']
|
72
|
-
|
73
|
-
|
74
|
-
score = m['score']
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
if m['stage'] == 'GROUP_STAGE'
|
79
|
-
stage = 'Group'
|
80
|
-
round = "Matchday #{m['matchday']}"
|
81
|
-
if m['group'] =~ /Group ([A-Z])/
|
82
|
-
group = $1
|
83
|
-
else
|
84
|
-
puts "!! ERROR - no group name found for group >#{m['group']}<"
|
85
|
-
exit 1
|
86
|
-
end
|
87
|
-
else
|
88
|
-
stage = STAGE_TO_STAGE[ m['stage'] ]
|
89
|
-
if stage.nil?
|
90
|
-
puts "!! ERROR - no stage mapping found for stage >#{m['stage']}<"
|
91
|
-
exit 1
|
92
|
-
end
|
93
|
-
round = STAGE_TO_ROUND[ m['stage'] ]
|
94
|
-
if round.nil?
|
95
|
-
puts "!! ERROR - no round mapping found for stage >#{m['stage']}<"
|
96
|
-
exit 1
|
97
|
-
end
|
98
|
-
group = ''
|
99
|
-
end
|
100
|
-
|
101
|
-
|
102
|
-
teams[ team1 ] += 1
|
103
|
-
teams[ team2 ] += 1
|
104
|
-
|
105
|
-
### mods - rename club names
|
106
|
-
unless mods.nil? || mods.empty?
|
107
|
-
team1 = mods[ team1 ] if mods[ team1 ]
|
108
|
-
team2 = mods[ team2 ] if mods[ team2 ]
|
109
|
-
end
|
110
|
-
|
111
|
-
|
112
|
-
## e.g. "utcDate": "2020-05-09T00:00:00Z",
|
113
|
-
date_str = m['utcDate']
|
114
|
-
date = DateTime.strptime( date_str, '%Y-%m-%dT%H:%M:%SZ' )
|
115
|
-
|
116
|
-
|
117
|
-
comments = ''
|
118
|
-
ft = ''
|
119
|
-
ht = ''
|
120
|
-
et = ''
|
121
|
-
pen = ''
|
122
|
-
|
123
|
-
case m['status']
|
124
|
-
when 'SCHEDULED', 'IN_PLAY'
|
125
|
-
ft = ''
|
126
|
-
ht = ''
|
127
|
-
et = ''
|
128
|
-
pen = ''
|
129
|
-
when 'AWARDED'
|
130
|
-
## todo/fix: assert duration == "REGULAR"
|
131
|
-
ft = "#{score['fullTime']['homeTeam']}-#{score['fullTime']['awayTeam']}"
|
132
|
-
ft << ' (*)'
|
133
|
-
ht = ''
|
134
|
-
comments = 'awarded'
|
135
|
-
when 'FINISHED'
|
136
|
-
## note: if extraTime present
|
137
|
-
## than fullTime is extraTime score!!
|
138
|
-
## AND fullTime - extraTime is fullTime score!!
|
139
|
-
## double check in other season too??
|
140
|
-
## - checked in cl 2018/19
|
141
|
-
|
142
|
-
if score['extraTime']['homeTeam'] && score['extraTime']['awayTeam']
|
143
|
-
et = "#{score['fullTime']['homeTeam']}-#{score['fullTime']['awayTeam']}"
|
144
|
-
ft = "#{score['fullTime']['homeTeam']-score['extraTime']['homeTeam']}-#{score['fullTime']['awayTeam']-score['extraTime']['awayTeam']}"
|
145
|
-
else
|
146
|
-
ft = "#{score['fullTime']['homeTeam']}-#{score['fullTime']['awayTeam']}"
|
147
|
-
end
|
148
|
-
|
149
|
-
ht = "#{score['halfTime']['homeTeam']}-#{score['halfTime']['awayTeam']}"
|
150
|
-
|
151
|
-
pen = if score['penalties']['homeTeam'] && score['penalties']['awayTeam']
|
152
|
-
"#{score['penalties']['homeTeam']}-#{score['penalties']['awayTeam']}"
|
153
|
-
else
|
154
|
-
''
|
155
|
-
end
|
156
|
-
else
|
157
|
-
puts "!! ERROR: unsupported match status >#{m['status']}< - sorry:"
|
158
|
-
pp m
|
159
|
-
exit 1
|
160
|
-
end
|
161
|
-
|
162
|
-
|
163
|
-
recs << [stage,
|
164
|
-
round,
|
165
|
-
group,
|
166
|
-
date.to_date.strftime( '%Y-%m-%d' ),
|
167
|
-
team1,
|
168
|
-
ft,
|
169
|
-
ht,
|
170
|
-
team2,
|
171
|
-
et,
|
172
|
-
pen,
|
173
|
-
comments
|
174
|
-
]
|
175
|
-
|
176
|
-
|
177
|
-
print '%2s' % m['matchday']
|
178
|
-
print ' - '
|
179
|
-
print '%-24s' % team1
|
180
|
-
print ' '
|
181
|
-
print ft
|
182
|
-
print ' '
|
183
|
-
print "(#{ht})" unless ht.empty?
|
184
|
-
print ' '
|
185
|
-
print '%-24s' % team2
|
186
|
-
print ' '
|
187
|
-
print comments
|
188
|
-
print ' | '
|
189
|
-
## print date.to_date ## strip time
|
190
|
-
print date.to_date.strftime( '%a %b %-d %Y' )
|
191
|
-
print ' -- '
|
192
|
-
print date
|
193
|
-
print "\n"
|
194
|
-
|
195
|
-
end # each match
|
196
|
-
|
197
|
-
|
198
|
-
## note: get season from first match
|
199
|
-
## assert - all other matches include the same season
|
200
|
-
## e.g.
|
201
|
-
# "season": {
|
202
|
-
# "id": 154,
|
203
|
-
# "startDate": "2018-08-03",
|
204
|
-
# "endDate": "2019-05-05",
|
205
|
-
# "currentMatchday": 46
|
206
|
-
# }
|
207
|
-
|
208
|
-
start_date = Date.strptime( matches[0]['season']['startDate'], '%Y-%m-%d' )
|
209
|
-
end_date = Date.strptime( matches[0]['season']['endDate'], '%Y-%m-%d' )
|
210
|
-
|
211
|
-
dates = "#{start_date.strftime('%b %-d')} - #{end_date.strftime('%b %-d')}"
|
212
|
-
|
213
|
-
buf = ''
|
214
|
-
buf << "#{season.key} (#{dates}) - "
|
215
|
-
buf << "#{teams.keys.size} clubs, "
|
216
|
-
buf << "#{stat[:all][:matches]} matches, "
|
217
|
-
buf << "#{stat[:all][:goals]} goals"
|
218
|
-
buf << "\n"
|
219
|
-
|
220
|
-
puts buf
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
# recs = recs.sort { |l,r| l[1] <=> r[1] }
|
225
|
-
## reformat date / beautify e.g. Sat Aug 7 1993
|
226
|
-
recs.each { |rec| rec[3] = Date.strptime( rec[3], '%Y-%m-%d' ).strftime( '%a %b %-d %Y' ) }
|
227
|
-
|
228
|
-
headers = [
|
229
|
-
'Stage',
|
230
|
-
'Round',
|
231
|
-
'Group',
|
232
|
-
'Date',
|
233
|
-
'Team 1',
|
234
|
-
'FT',
|
235
|
-
'HT',
|
236
|
-
'Team 2',
|
237
|
-
'ET',
|
238
|
-
'P',
|
239
|
-
'Comments'
|
240
|
-
]
|
241
|
-
|
242
|
-
## note: change season_key from 2019/20 to 2019-20 (for path/directory!!!!)
|
243
|
-
Cache::CsvMatchWriter.write( "#{config.convert.out_dir}/#{season.to_path}/#{league.downcase}.csv",
|
244
|
-
recs,
|
245
|
-
headers: headers )
|
246
|
-
|
247
|
-
|
248
|
-
teams.each do |name, count|
|
249
|
-
rec = teams_by_name[ name ]
|
250
|
-
print " #{count}x "
|
251
|
-
print name
|
252
|
-
if rec
|
253
|
-
print " | #{rec['shortName']} " if name != rec['shortName']
|
254
|
-
print " › #{rec['area']['name']}"
|
255
|
-
print " - #{rec['address']}"
|
256
|
-
else
|
257
|
-
print "!! ERROR - no team record found in teams.json for #{name}"
|
258
|
-
exit 1
|
259
|
-
end
|
260
|
-
print "\n"
|
261
|
-
end
|
262
|
-
|
263
|
-
pp stat
|
264
|
-
end # method convert_cl
|
265
|
-
end # module Footballdata
|
266
|
-
|
267
|
-
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module Footballdata
|
2
|
-
|
3
|
-
#########
|
4
|
-
## Mods
|
5
|
-
# e.g.
|
6
|
-
# Cardiff City FC | Cardiff › Wales - Cardiff City Stadium, Leckwith Road Cardiff CF11 8AZ
|
7
|
-
# AS Monaco FC | Monaco › Monaco - Avenue des Castellans Monaco 98000
|
8
|
-
|
9
|
-
|
10
|
-
MODS = {
|
11
|
-
'br.1' => {
|
12
|
-
'América FC' => 'América MG', # in year 2018
|
13
|
-
},
|
14
|
-
'pt.1' => {
|
15
|
-
'Vitória SC' => 'Vitória Guimarães', ## avoid easy confusion with Vitória SC <=> Vitória FC
|
16
|
-
'Vitória FC' => 'Vitória Setúbal',
|
17
|
-
},
|
18
|
-
}
|
19
|
-
|
20
|
-
end # module Footballdata
|