footballdata-api 2026.7.11 → 2026.7.12
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/CHANGELOG.md +1 -1
- data/Manifest.txt +2 -2
- data/README.md +2 -2
- data/bin/fbdat +14 -2
- data/lib/footballdata/{convert_json-teams.rb → convert-teams.rb} +38 -7
- data/lib/footballdata/convert_csv.rb +120 -171
- data/lib/footballdata/convert_json.rb +1 -27
- data/lib/footballdata/version.rb +1 -1
- data/lib/footballdata.rb +2 -2
- metadata +4 -4
- /data/lib/footballdata/{convert_json-stages.rb → convert-stages.rb} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 301b4ba1575a7275090ed592dce4a7da171d739d3fbd7599a4b19794d589df0d
|
|
4
|
+
data.tar.gz: 467180eeb2bdd379d40fe46021748ddfca3ed72dab132aacdf397c762b155b5e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0c103f1473a73a21a494b86e435182d6bfe22744b098b7f2a661b7ac2f66e4b6a81965f5d18ec0b726b950746496ce8ed44b96266a66256a625784d2f5b0ba86
|
|
7
|
+
data.tar.gz: 4d538238d329037c41ffbbe1cdfdb1f0c21309c50250c1e403855ed7599b02c459a5430d305b82e7929245c0c101d5781c3df41354b20fe233d2b496297a70f8
|
data/CHANGELOG.md
CHANGED
data/Manifest.txt
CHANGED
|
@@ -6,9 +6,9 @@ bin/fbdat
|
|
|
6
6
|
config/leagues_tier1.csv
|
|
7
7
|
lib/footballdata.rb
|
|
8
8
|
lib/footballdata/convert-score.rb
|
|
9
|
+
lib/footballdata/convert-stages.rb
|
|
10
|
+
lib/footballdata/convert-teams.rb
|
|
9
11
|
lib/footballdata/convert_csv.rb
|
|
10
|
-
lib/footballdata/convert_json-stages.rb
|
|
11
|
-
lib/footballdata/convert_json-teams.rb
|
|
12
12
|
lib/footballdata/convert_json.rb
|
|
13
13
|
lib/footballdata/download.rb
|
|
14
14
|
lib/footballdata/leagues.rb
|
data/README.md
CHANGED
|
@@ -84,10 +84,10 @@ require 'footballdata'
|
|
|
84
84
|
'pt.1',
|
|
85
85
|
'uefa.cl',
|
|
86
86
|
].each do |league|
|
|
87
|
-
Footballdata.
|
|
87
|
+
Footballdata.convert_csv( league: league, season: '2020/21' )
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
-
Footballdata.
|
|
90
|
+
Footballdata.convert_csv( league: 'br.1', season: '2020' )
|
|
91
91
|
```
|
|
92
92
|
|
|
93
93
|
Note: By default all datasets get written into the `./o`
|
data/bin/fbdat
CHANGED
|
@@ -36,8 +36,10 @@ opts = {
|
|
|
36
36
|
cached: false,
|
|
37
37
|
convert: true,
|
|
38
38
|
file: nil,
|
|
39
|
+
json: nil,
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
|
|
41
43
|
parser = OptionParser.new do |parser|
|
|
42
44
|
parser.banner = "Usage: #{$PROGRAM_NAME} [options] [args]"
|
|
43
45
|
|
|
@@ -51,6 +53,11 @@ parser = OptionParser.new do |parser|
|
|
|
51
53
|
opts[:convert] = convert
|
|
52
54
|
end
|
|
53
55
|
|
|
56
|
+
parser.on( "--json",
|
|
57
|
+
"turn on conversion to .json in #{Footballdata.config.convert.out_dir}" ) do |json|
|
|
58
|
+
opts[:json] = json
|
|
59
|
+
end
|
|
60
|
+
|
|
54
61
|
parser.on( "--print", "--pp",
|
|
55
62
|
"pretty print cached data in #{Webcache.root}; no download & conversion") do |print|
|
|
56
63
|
opts[:cached] = true
|
|
@@ -248,8 +255,13 @@ if opts[:convert]
|
|
|
248
255
|
puts "==> converting to .csv"
|
|
249
256
|
datasets.each do |league_key, seasons|
|
|
250
257
|
seasons.each do |season|
|
|
251
|
-
|
|
252
|
-
|
|
258
|
+
### quick hack - for json only conversion
|
|
259
|
+
if opts[:json]
|
|
260
|
+
convert_json( league: league_key, season: season )
|
|
261
|
+
else
|
|
262
|
+
convert_csv( league: league_key, season: season )
|
|
263
|
+
convert_json( league: league_key, season: season )
|
|
264
|
+
end
|
|
253
265
|
end
|
|
254
266
|
end
|
|
255
267
|
end
|
|
@@ -43,9 +43,21 @@ note - for address "null null null",
|
|
|
43
43
|
=end
|
|
44
44
|
|
|
45
45
|
|
|
46
|
-
|
|
47
46
|
def build_team( h )
|
|
48
47
|
|
|
48
|
+
##
|
|
49
|
+
## note: convert country code to "standard" fifa code
|
|
50
|
+
## use official fifa country code
|
|
51
|
+
country_name = h['area']['name']
|
|
52
|
+
|
|
53
|
+
country = Fifa.world.find_by_name( country_name )
|
|
54
|
+
if country.nil?
|
|
55
|
+
raise ArgumentError, "[fifa world] no country record found for #{country_name} for: #{h.inspect}"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
country_code = country.code
|
|
59
|
+
|
|
60
|
+
|
|
49
61
|
rec = { id: h['id'],
|
|
50
62
|
name: h['name'],
|
|
51
63
|
short_name: h['shortName'],
|
|
@@ -57,8 +69,9 @@ def build_team( h )
|
|
|
57
69
|
##
|
|
58
70
|
## or use country { code:, name }
|
|
59
71
|
## change to cc (country code) - why? why not?
|
|
60
|
-
country: {
|
|
61
|
-
|
|
72
|
+
country: { name: country_name,
|
|
73
|
+
code: country_code,
|
|
74
|
+
code_bak: h['area']['code'] },
|
|
62
75
|
|
|
63
76
|
count: 0, ## track - match counts
|
|
64
77
|
}
|
|
@@ -68,6 +81,7 @@ end
|
|
|
68
81
|
|
|
69
82
|
|
|
70
83
|
class Teams
|
|
84
|
+
|
|
71
85
|
def initialize
|
|
72
86
|
@recs = []
|
|
73
87
|
@by_name = {}
|
|
@@ -79,9 +93,20 @@ class Teams
|
|
|
79
93
|
rec = build_team( h )
|
|
80
94
|
@recs << rec
|
|
81
95
|
|
|
82
|
-
##
|
|
83
|
-
@by_name
|
|
84
|
-
|
|
96
|
+
## note - assert/make sure team name is uniq
|
|
97
|
+
if @by_name.has_key?(rec[:name])
|
|
98
|
+
raise ArgumentError, "duplicate team name - #{h.inspect}"
|
|
99
|
+
else
|
|
100
|
+
@by_name[rec[:name]] = rec
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
if rec[:name] != rec[:short_name]
|
|
104
|
+
if @by_name.has_key?(rec[:short_name])
|
|
105
|
+
raise ArgumentError, "duplicate team (short) name - #{h.inspect}"
|
|
106
|
+
else
|
|
107
|
+
@by_name[rec[:short_name]] = rec
|
|
108
|
+
end
|
|
109
|
+
end
|
|
85
110
|
end
|
|
86
111
|
end
|
|
87
112
|
|
|
@@ -89,7 +114,10 @@ class Teams
|
|
|
89
114
|
|
|
90
115
|
def find_by!( name: )
|
|
91
116
|
rec = @by_name[ name ]
|
|
92
|
-
|
|
117
|
+
if rec.nil?
|
|
118
|
+
raise ArgumentError, "team >#{name}< not found; sorry"
|
|
119
|
+
end
|
|
120
|
+
|
|
93
121
|
rec
|
|
94
122
|
end
|
|
95
123
|
|
|
@@ -110,6 +138,9 @@ class Teams
|
|
|
110
138
|
end
|
|
111
139
|
end
|
|
112
140
|
|
|
141
|
+
def each( &blk) @recs.each( &blk); end
|
|
142
|
+
|
|
143
|
+
|
|
113
144
|
|
|
114
145
|
def as_json( id: false )
|
|
115
146
|
if id
|
|
@@ -1,75 +1,50 @@
|
|
|
1
1
|
|
|
2
2
|
module Footballdata
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
##
|
|
7
|
-
## or * (all)
|
|
4
|
+
|
|
5
|
+
####
|
|
6
|
+
## beautify stages constant names
|
|
8
7
|
STAGES = {
|
|
9
|
-
'REGULAR_SEASON' =>
|
|
10
|
-
|
|
11
|
-
'QUALIFICATION' =>
|
|
12
|
-
'PRELIMINARY_ROUND' =>
|
|
13
|
-
'PRELIMINARY_SEMI_FINALS' =>
|
|
14
|
-
'PRELIMINARY_FINAL' =>
|
|
15
|
-
'1ST_QUALIFYING_ROUND' =>
|
|
16
|
-
'2ND_QUALIFYING_ROUND' =>
|
|
17
|
-
'3RD_QUALIFYING_ROUND' =>
|
|
18
|
-
'QUALIFICATION_ROUND_1' =>
|
|
19
|
-
'QUALIFICATION_ROUND_2' =>
|
|
20
|
-
'QUALIFICATION_ROUND_3' =>
|
|
21
|
-
'ROUND_1' =>
|
|
22
|
-
'ROUND_2' =>
|
|
23
|
-
'ROUND_3' =>
|
|
24
|
-
'PLAY_OFF_ROUND' =>
|
|
25
|
-
'PLAYOFF_ROUND_1' =>
|
|
26
|
-
|
|
27
|
-
'LEAGUE_STAGE' =>
|
|
28
|
-
'GROUP_STAGE' =>
|
|
29
|
-
'PLAYOFFS' =>
|
|
30
|
-
'PLAY_OFFS' =>
|
|
31
|
-
|
|
32
|
-
'LAST_32' =>
|
|
33
|
-
'ROUND_OF_16' =>
|
|
34
|
-
'LAST_16' =>
|
|
35
|
-
'QUARTER_FINALS' =>
|
|
36
|
-
'SEMI_FINALS' =>
|
|
37
|
-
'THIRD_PLACE' =>
|
|
38
|
-
'FINAL' =>
|
|
8
|
+
'REGULAR_SEASON' => 'Regular Season',
|
|
9
|
+
|
|
10
|
+
'QUALIFICATION' => 'Qualification',
|
|
11
|
+
'PRELIMINARY_ROUND' => 'Preliminary Round',
|
|
12
|
+
'PRELIMINARY_SEMI_FINALS' => 'Preliminary Semifinals',
|
|
13
|
+
'PRELIMINARY_FINAL' => 'Preliminary Final',
|
|
14
|
+
'1ST_QUALIFYING_ROUND' => '1st Qualifying Round',
|
|
15
|
+
'2ND_QUALIFYING_ROUND' => '2nd Qualifying Round',
|
|
16
|
+
'3RD_QUALIFYING_ROUND' => '3rd Qualifying Round',
|
|
17
|
+
'QUALIFICATION_ROUND_1' => 'Qualification Round 1',
|
|
18
|
+
'QUALIFICATION_ROUND_2' => 'Qualification Round 2',
|
|
19
|
+
'QUALIFICATION_ROUND_3' => 'Qualification Round 3',
|
|
20
|
+
'ROUND_1' => 'Round 1',
|
|
21
|
+
'ROUND_2' => 'Round 2',
|
|
22
|
+
'ROUND_3' => 'Round 3',
|
|
23
|
+
'PLAY_OFF_ROUND' => 'Playoff Round',
|
|
24
|
+
'PLAYOFF_ROUND_1' => 'Playoff Round 1',
|
|
25
|
+
|
|
26
|
+
'LEAGUE_STAGE' => 'League', ## add Stage - why? why not?
|
|
27
|
+
'GROUP_STAGE' => 'Group',
|
|
28
|
+
'PLAYOFFS' => 'Playoffs', ## -- used in champs
|
|
29
|
+
'PLAY_OFFS' => 'Playoffs', ## -- used in copa liber.
|
|
30
|
+
|
|
31
|
+
'LAST_32' => 'Round of 32',
|
|
32
|
+
'ROUND_OF_16' => 'Round of 16',
|
|
33
|
+
'LAST_16' => 'Round of 16', ## use Last 16 - why? why not?
|
|
34
|
+
'QUARTER_FINALS' => 'Quarterfinals',
|
|
35
|
+
'SEMI_FINALS' => 'Semifinals',
|
|
36
|
+
'THIRD_PLACE' => 'Third place',
|
|
37
|
+
'FINAL' => 'Final',
|
|
39
38
|
}
|
|
40
39
|
|
|
41
40
|
|
|
42
41
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def self.find_team_country_code( name, teams: )
|
|
46
|
-
## add (fifa) country code e.g.
|
|
47
|
-
## Liverpool FC => Liverpool FC (ENG)
|
|
48
|
-
## or Liverpool FC => Liverpool FC (URU)
|
|
49
|
-
rec = teams[ name ]
|
|
50
|
-
if rec.nil?
|
|
51
|
-
puts "!! ERROR - no team record found in teams.json for #{name}"
|
|
52
|
-
pp teams.keys
|
|
53
|
-
exit 1
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
country_name = rec['area']['name']
|
|
57
|
-
country = Fifa.world.find_by_name( country_name )
|
|
58
|
-
if country.nil?
|
|
59
|
-
puts "!! ERROR - no country record found for #{country_name}"
|
|
60
|
-
exit 1
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
country.code
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def self.convert( league:, season: )
|
|
42
|
+
def self.convert_csv( league:, season: )
|
|
69
43
|
|
|
70
44
|
season = Season( season ) ## cast (ensure) season class (NOT string, integer, etc.)
|
|
71
45
|
|
|
72
46
|
### note - find_league returns the metal_league_code
|
|
47
|
+
## e.g. eng.1 => PL
|
|
73
48
|
league_code = find_league!( league )
|
|
74
49
|
|
|
75
50
|
matches_url = Metal.competition_matches_url( league_code, season.start_year )
|
|
@@ -79,6 +54,17 @@ def self.convert( league:, season: )
|
|
|
79
54
|
data_teams = Webcache.read_json( teams_url )
|
|
80
55
|
|
|
81
56
|
|
|
57
|
+
## build a team lookup by name (& short_name)
|
|
58
|
+
|
|
59
|
+
teams = Teams.new
|
|
60
|
+
teams.add( data_teams['teams'] )
|
|
61
|
+
puts "#{teams.size} team(s)"
|
|
62
|
+
|
|
63
|
+
## add/update match counts
|
|
64
|
+
teams.add_matches( data['matches'] )
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
82
68
|
###
|
|
83
69
|
## todo/fix - use find_by! - add upstream!!!
|
|
84
70
|
league_info = LeagueCodes.find_by( code: league, season: season )
|
|
@@ -95,131 +81,102 @@ def self.convert( league:, season: )
|
|
|
95
81
|
'copa.l'].include?(league.downcase) ? true : false
|
|
96
82
|
|
|
97
83
|
|
|
84
|
+
mods = MODS[ league.downcase ] || {}
|
|
98
85
|
|
|
99
|
-
## build a (reverse) team lookup by name
|
|
100
|
-
puts "#{data_teams['teams'].size} teams"
|
|
101
|
-
|
|
102
|
-
teams_by_name = data_teams['teams'].reduce( {} ) do |h,rec|
|
|
103
|
-
h[ rec['name'] ] = rec
|
|
104
|
-
h
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
## pp teams_by_name.keys
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
mods = MODS[ league.downcase ] || {}
|
|
112
86
|
|
|
113
87
|
|
|
114
|
-
recs = []
|
|
115
|
-
|
|
116
|
-
teams = Hash.new( 0 )
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
# stat = Stat.new
|
|
88
|
+
recs = []
|
|
120
89
|
|
|
90
|
+
# stat = Stat.new
|
|
121
91
|
## track stage, match status et
|
|
122
92
|
stats = { 'status' => Hash.new(0),
|
|
123
93
|
'stage' => Hash.new(0),
|
|
124
94
|
}
|
|
125
95
|
|
|
126
96
|
|
|
127
|
-
|
|
128
|
-
|
|
129
97
|
matches = data[ 'matches']
|
|
130
98
|
matches.each do |m|
|
|
131
99
|
# stat.update( m )
|
|
132
100
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
101
|
+
# use ? or N.N. or ? for nil - why? why not?
|
|
102
|
+
team1_name = m['homeTeam']['name']
|
|
103
|
+
team2_name = m['awayTeam']['name']
|
|
136
104
|
|
|
105
|
+
team1 = team1_name ? teams.find_by!(name: team1_name ) : { name: 'N.N.' }
|
|
106
|
+
team2 = team2_name ? teams.find_by!(name: team2_name ) : { name: 'N.N.' }
|
|
137
107
|
|
|
138
108
|
|
|
109
|
+
## use "normed" team names
|
|
110
|
+
team1_name = team1[:name]
|
|
111
|
+
team2_name = team2[:name]
|
|
139
112
|
|
|
140
|
-
|
|
113
|
+
### mods - rename club names
|
|
114
|
+
unless mods.nil? || mods.empty?
|
|
115
|
+
team1_name = mods[ team1_name ] if mods[ team1_name ]
|
|
116
|
+
team2_name = mods[ team2_name ] if mods[ team2_name ]
|
|
117
|
+
end
|
|
141
118
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
puts "!! WARN - group defined with NON GROUP!? >#{group}< reset to empty"
|
|
152
|
-
puts " and matchday to >#{m['matchday']}<"
|
|
153
|
-
## reset group to empty
|
|
154
|
-
group = ''
|
|
155
|
-
end
|
|
119
|
+
####
|
|
120
|
+
# auto-add (fifa) country code if int'l club tournament
|
|
121
|
+
if clubs_intl
|
|
122
|
+
if team1_name != 'N.N.' ## note - ignore no team/placeholder (e.g. N.N)
|
|
123
|
+
team1_name = "#{team1_name} (#{team1[:country][:code]})"
|
|
124
|
+
end
|
|
125
|
+
if team2_name != 'N.N.' ## note - ignore no team/placeholder (e.g. N.N)
|
|
126
|
+
team2_name = "#{team2_name} (#{team2[:country][:code]})"
|
|
127
|
+
end
|
|
156
128
|
end
|
|
157
129
|
|
|
158
130
|
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
group = m['group']
|
|
159
135
|
stage_key = m['stage']
|
|
160
136
|
stats['stage'][ stage_key ] += 1 ## track stage counts
|
|
137
|
+
## add group stats?
|
|
161
138
|
|
|
162
139
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
end
|
|
173
|
-
['Group', nil]
|
|
174
|
-
end
|
|
140
|
+
## GROUP_A
|
|
141
|
+
## shorten group to A|B|C etc.
|
|
142
|
+
if group
|
|
143
|
+
## assert group only used with GROUP_STAGE
|
|
144
|
+
if stage_key != 'GROUP_STAGE'
|
|
145
|
+
raise ArgumentError,
|
|
146
|
+
"group defined BUT stage set to >#{stage_key}< (expected GROUP_STAGE)" +
|
|
147
|
+
"and matchday to >#{m['matchday']}<"
|
|
148
|
+
end
|
|
175
149
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
150
|
+
if group =~ /^(GROUP_|Group )/
|
|
151
|
+
group = group.sub( /^(GROUP_|Group )/, '' )
|
|
152
|
+
else
|
|
153
|
+
raise ArgumentError,
|
|
154
|
+
"group defined with NON GROUP!? >#{group}< reset to empty"+
|
|
155
|
+
" and matchday to >#{m['matchday']}<"
|
|
156
|
+
end
|
|
157
|
+
else ## assume group.nil?
|
|
158
|
+
group = ''
|
|
179
159
|
end
|
|
180
160
|
|
|
181
|
-
matchday_num = m['matchday']
|
|
182
|
-
matchday_num = nil if matchday_num == 0 ## change 0 to nil (empty) too
|
|
183
161
|
|
|
184
162
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
matchday = matchday_num.to_s
|
|
189
|
-
else
|
|
190
|
-
## note - if matchday/round defined, use it
|
|
191
|
-
## note - ignore possible leg in matchday for now
|
|
192
|
-
matchday = stage_round
|
|
193
|
-
end
|
|
163
|
+
## map stage to stage + round
|
|
164
|
+
## note - if no mapping defined; use (fallback to) upcase version
|
|
165
|
+
stage = STAGES[ stage_key ]
|
|
194
166
|
|
|
167
|
+
if stage.nil?
|
|
168
|
+
puts "!! WARN - no stage mapping found for stage >#{stage_key}<"
|
|
169
|
+
stage = stage_key
|
|
170
|
+
end
|
|
195
171
|
|
|
196
|
-
teams[ team1 ] += 1
|
|
197
|
-
teams[ team2 ] += 1
|
|
198
172
|
|
|
199
173
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
team1 = mods[ team1 ] if mods[ team1 ]
|
|
203
|
-
team2 = mods[ team2 ] if mods[ team2 ]
|
|
204
|
-
end
|
|
174
|
+
matchday = m['matchday']
|
|
175
|
+
matchday = nil if matchday == 0 ## change 0 to nil (empty) too
|
|
205
176
|
|
|
206
177
|
|
|
207
|
-
####
|
|
208
|
-
# auto-add (fifa) country code if int'l club tournament
|
|
209
|
-
if clubs_intl
|
|
210
|
-
## note - use "original" name (not moded) for lookup
|
|
211
|
-
team1_org = m['homeTeam']['name']
|
|
212
|
-
team2_org = m['awayTeam']['name']
|
|
213
|
-
if team1_org ## note - ignore no team/placeholder (e.g. N.N)
|
|
214
|
-
country_code = find_team_country_code( team1_org, teams: teams_by_name )
|
|
215
|
-
team1 = "#{team1} (#{country_code})"
|
|
216
|
-
end
|
|
217
|
-
if team2_org ## note - ignore no team/placeholder (e.g. N.N)
|
|
218
|
-
country_code = find_team_country_code( team2_org, teams: teams_by_name )
|
|
219
|
-
team2 = "#{team2} (#{country_code})"
|
|
220
|
-
end
|
|
221
|
-
end
|
|
222
178
|
|
|
179
|
+
score = m['score']
|
|
223
180
|
|
|
224
181
|
|
|
225
182
|
comments = ''
|
|
@@ -254,9 +211,8 @@ matches.each do |m|
|
|
|
254
211
|
ht = ''
|
|
255
212
|
comments = 'postponed'
|
|
256
213
|
else
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
exit 1
|
|
214
|
+
raise ArgumentError,
|
|
215
|
+
"unsupported match status >#{m['status']}< - sorry:"
|
|
260
216
|
end
|
|
261
217
|
|
|
262
218
|
|
|
@@ -295,14 +251,14 @@ matches.each do |m|
|
|
|
295
251
|
|
|
296
252
|
recs << [stage,
|
|
297
253
|
group,
|
|
298
|
-
matchday,
|
|
254
|
+
matchday.to_s, ## not convert nil or Integer to str e.g. "", "1"
|
|
299
255
|
date,
|
|
300
256
|
time,
|
|
301
257
|
timezone,
|
|
302
|
-
|
|
258
|
+
team1_name,
|
|
303
259
|
ft,
|
|
304
260
|
ht,
|
|
305
|
-
|
|
261
|
+
team2_name,
|
|
306
262
|
et,
|
|
307
263
|
pen,
|
|
308
264
|
comments,
|
|
@@ -331,7 +287,7 @@ dates = "#{start_date.strftime('%b %-d')} - #{end_date.strftime('%b %-d')}"
|
|
|
331
287
|
|
|
332
288
|
buf = ''
|
|
333
289
|
buf << "#{season.key} (#{dates}) - "
|
|
334
|
-
buf << "#{teams.
|
|
290
|
+
buf << "#{teams.size} teams, "
|
|
335
291
|
buf << "#{recs.size} matches"
|
|
336
292
|
# buf << "#{stat[:regular_season][:goals]} goals"
|
|
337
293
|
buf << "\n"
|
|
@@ -418,27 +374,17 @@ recs, headers = vacuum( recs )
|
|
|
418
374
|
headers: headers )
|
|
419
375
|
|
|
420
376
|
|
|
421
|
-
teams.each do |
|
|
422
|
-
rec
|
|
423
|
-
print
|
|
424
|
-
print name
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
print " › #{rec['area']['name']}"
|
|
428
|
-
print " - #{rec['address']}"
|
|
429
|
-
else
|
|
430
|
-
if name == 'N.N.'
|
|
431
|
-
## ignore missing record
|
|
432
|
-
else
|
|
433
|
-
puts "!! ERROR - no team record found in teams.json for #{name}"
|
|
434
|
-
exit 1
|
|
435
|
-
end
|
|
436
|
-
end
|
|
377
|
+
teams.each do |rec|
|
|
378
|
+
print " #{rec[:count]}x "
|
|
379
|
+
print rec[:name]
|
|
380
|
+
print " | #{rec[:short_name]} " if rec[:name] != rec[:short_name]
|
|
381
|
+
print " › #{rec[:country][:name]} (#{rec[:country][:code]})"
|
|
382
|
+
print " - #{rec[:address]}"
|
|
437
383
|
print "\n"
|
|
438
384
|
end
|
|
439
385
|
|
|
440
386
|
## pp stat
|
|
441
|
-
end # method
|
|
387
|
+
end # method convert_csv
|
|
442
388
|
|
|
443
389
|
|
|
444
390
|
|
|
@@ -469,6 +415,9 @@ MIN_HEADERS = [ ## always keep even if all empty
|
|
|
469
415
|
|
|
470
416
|
|
|
471
417
|
|
|
418
|
+
###
|
|
419
|
+
### move upstream to cocos!! (re)use vacuum_csv !!!!
|
|
420
|
+
|
|
472
421
|
def self.vacuum( rows, headers: MAX_HEADERS, fixed_headers: MIN_HEADERS )
|
|
473
422
|
## check for unused columns and strip/remove
|
|
474
423
|
counter = Array.new( MAX_HEADERS.size, 0 )
|
|
@@ -154,33 +154,7 @@ def self.convert_json( league:, season: )
|
|
|
154
154
|
## note: change season_key from 2019/20 to 2019-20 (for path/directory!!!!)
|
|
155
155
|
puts " writing to >#{path}<"
|
|
156
156
|
write_json( path, data )
|
|
157
|
-
end # method
|
|
157
|
+
end # method convert_json
|
|
158
158
|
|
|
159
159
|
|
|
160
160
|
end # module Footballdata
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
__END__
|
|
165
|
-
|
|
166
|
-
## note: get season from first match
|
|
167
|
-
## assert - all other matches include the same season
|
|
168
|
-
## e.g.
|
|
169
|
-
# "season": {
|
|
170
|
-
# "id": 154,
|
|
171
|
-
# "startDate": "2018-08-03",
|
|
172
|
-
# "endDate": "2019-05-05",
|
|
173
|
-
# "currentMatchday": 46
|
|
174
|
-
# }
|
|
175
|
-
|
|
176
|
-
start_date = Date.strptime( matches[0]['season']['startDate'], '%Y-%m-%d' )
|
|
177
|
-
end_date = Date.strptime( matches[0]['season']['endDate'], '%Y-%m-%d' )
|
|
178
|
-
|
|
179
|
-
dates = "#{start_date.strftime('%b %-d')} - #{end_date.strftime('%b %-d')}"
|
|
180
|
-
|
|
181
|
-
buf = ''
|
|
182
|
-
buf << "#{season.key} (#{dates}) - "
|
|
183
|
-
buf << "#{teams.keys.size} teams, "
|
|
184
|
-
buf << "#{recs.size} matches"
|
|
185
|
-
# buf << "#{stat[:regular_season][:goals]} goals"
|
|
186
|
-
buf << "\n"
|
data/lib/footballdata/version.rb
CHANGED
data/lib/footballdata.rb
CHANGED
|
@@ -38,8 +38,8 @@ require_relative 'footballdata/prettyprint'
|
|
|
38
38
|
require_relative 'footballdata/mods'
|
|
39
39
|
require_relative 'footballdata/convert_csv'
|
|
40
40
|
require_relative 'footballdata/convert_json'
|
|
41
|
-
require_relative 'footballdata/
|
|
42
|
-
require_relative 'footballdata/
|
|
41
|
+
require_relative 'footballdata/convert-stages'
|
|
42
|
+
require_relative 'footballdata/convert-teams'
|
|
43
43
|
require_relative 'footballdata/convert-score'
|
|
44
44
|
|
|
45
45
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: footballdata-api
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2026.7.
|
|
4
|
+
version: 2026.7.12
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gerald Bauer
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-07-
|
|
11
|
+
date: 2026-07-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: leagues
|
|
@@ -105,9 +105,9 @@ files:
|
|
|
105
105
|
- config/leagues_tier1.csv
|
|
106
106
|
- lib/footballdata.rb
|
|
107
107
|
- lib/footballdata/convert-score.rb
|
|
108
|
+
- lib/footballdata/convert-stages.rb
|
|
109
|
+
- lib/footballdata/convert-teams.rb
|
|
108
110
|
- lib/footballdata/convert_csv.rb
|
|
109
|
-
- lib/footballdata/convert_json-stages.rb
|
|
110
|
-
- lib/footballdata/convert_json-teams.rb
|
|
111
111
|
- lib/footballdata/convert_json.rb
|
|
112
112
|
- lib/footballdata/download.rb
|
|
113
113
|
- lib/footballdata/leagues.rb
|
|
File without changes
|