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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7dc56c0d0418eab7317862787fc928fe1102785d1768f75b242fb3ab52e140b6
4
- data.tar.gz: 83fcf18d6a491b1cc9cff38a38de13cbdfe184b9400ae78678aa479b5517ff92
3
+ metadata.gz: 301b4ba1575a7275090ed592dce4a7da171d739d3fbd7599a4b19794d589df0d
4
+ data.tar.gz: 467180eeb2bdd379d40fe46021748ddfca3ed72dab132aacdf397c762b155b5e
5
5
  SHA512:
6
- metadata.gz: c3c0a16979fc71e903180ddae103249350461d48dab182f90afc94c06b1230e0c1de624b8c1517c79f3a80bb3fadf84d3d7519a64358a96e52fc877b7df6f803
7
- data.tar.gz: 04ac3d92c132dcce5277300e8ffae5b46eaa16dcede2b780574dbf8a98c6b098fab1e9e2d27231e4fd0aab81a12b8dcc9205c3065f70f79aa48135b9f49894fd
6
+ metadata.gz: 0c103f1473a73a21a494b86e435182d6bfe22744b098b7f2a661b7ac2f66e4b6a81965f5d18ec0b726b950746496ce8ed44b96266a66256a625784d2f5b0ba86
7
+ data.tar.gz: 4d538238d329037c41ffbbe1cdfdb1f0c21309c50250c1e403855ed7599b02c459a5430d305b82e7929245c0c101d5781c3df41354b20fe233d2b496297a70f8
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ### 2026.7.11
1
+ ### 2026.7.12
2
2
  ### 0.0.1 / 2024-07-03
3
3
 
4
4
  * Everything is new. First release.
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.convert( league: league, season: '2020/21' )
87
+ Footballdata.convert_csv( league: league, season: '2020/21' )
88
88
  end
89
89
 
90
- Footballdata.convert( league: 'br.1', season: '2020' )
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
- convert( league: league_key, season: season )
252
- convert_json( league: league_key, season: season )
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: { code: h['area']['code'],
61
- name: h['area']['name'] },
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
- ## todo/fix - make sure team name is uniq!!!!
83
- @by_name[rec[:name]] = rec
84
- @by_name[rec[:short_name]] = rec
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
- raise ArgumentError, "team >#{name}< not found; sorry" if rec.nil?
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
- ## map round-like to higher-level stages
6
- ## fix - map by league codes
7
- ## or * (all)
4
+
5
+ ####
6
+ ## beautify stages constant names
8
7
  STAGES = {
9
- 'REGULAR_SEASON' => ['Regular'],
10
-
11
- 'QUALIFICATION' => ['Qualifying'],
12
- 'PRELIMINARY_ROUND' => ['Qualifying', 'Preliminary Round' ],
13
- 'PRELIMINARY_SEMI_FINALS' => ['Qualifying', 'Preliminary Semifinals' ],
14
- 'PRELIMINARY_FINAL' => ['Qualifying', 'Preliminary Final' ],
15
- '1ST_QUALIFYING_ROUND' => ['Qualifying', 'Round 1' ],
16
- '2ND_QUALIFYING_ROUND' => ['Qualifying', 'Round 2' ],
17
- '3RD_QUALIFYING_ROUND' => ['Qualifying', 'Round 3' ],
18
- 'QUALIFICATION_ROUND_1' => ['Qualifying', 'Round 1' ],
19
- 'QUALIFICATION_ROUND_2' => ['Qualifying', 'Round 2' ],
20
- 'QUALIFICATION_ROUND_3' => ['Qualifying', 'Round 3' ],
21
- 'ROUND_1' => ['Qualifying', 'Round 1'], ## use Qual. Round 1 - why? why not?
22
- 'ROUND_2' => ['Qualifying', 'Round 2'],
23
- 'ROUND_3' => ['Qualifying', 'Round 3'],
24
- 'PLAY_OFF_ROUND' => ['Qualifying', 'Playoff Round'],
25
- 'PLAYOFF_ROUND_1' => ['Qualifying', 'Playoff Round 1'],
26
-
27
- 'LEAGUE_STAGE' => ['League'],
28
- 'GROUP_STAGE' => ['Group'],
29
- 'PLAYOFFS' => ['Playoffs'], ## used in champs
30
- 'PLAY_OFFS' => ['Playoffs'], ## used in copa liber.
31
-
32
- 'LAST_32' => ['Finals', 'Round of 32'],
33
- 'ROUND_OF_16' => ['Finals', 'Round of 16'],
34
- 'LAST_16' => ['Finals', 'Round of 16'], ## use Last 16 - why? why not?
35
- 'QUARTER_FINALS' => ['Finals', 'Quarterfinals'],
36
- 'SEMI_FINALS' => ['Finals', 'Semifinals'],
37
- 'THIRD_PLACE' => ['Finals', 'Third place play-off'],
38
- 'FINAL' => ['Finals', '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
- ## use ? or N.N. or ? for nil - why? why not?
134
- team1 = m['homeTeam']['name'] || 'N.N.'
135
- team2 = m['awayTeam']['name'] || 'N.N.'
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
- score = m['score']
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
- group = m['group']
143
- ## GROUP_A
144
- ## shorten group to A|B|C etc.
145
- if group && group =~ /^(GROUP_|Group )/
146
- group = group.sub( /^(GROUP_|Group )/, '' )
147
- else
148
- if group.nil?
149
- group = ''
150
- else
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
- stage, stage_round = if group.empty?
164
- ## map stage to stage + round
165
- STAGES[ stage_key ]
166
- else
167
- ## if group defined ignore stage
168
- ## hard-core always to group for now
169
- if stage_key != 'GROUP_STAGE'
170
- puts "!! WARN - group defined BUT stage set to >#{stage_key}<"
171
- puts " and matchday to >#{m['matchday']}<"
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
- if stage.nil?
177
- puts "!! ERROR - no stage mapping found for stage >#{stage_key}<"
178
- exit 1
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
- if stage_round.nil? ## e.g. Regular, League, Group, Playoffs
186
- ## keep/assume matchday number is matchday .e.g
187
- ## matchday 1, 2 etc.
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
- ### mods - rename club names
201
- unless mods.nil? || mods.empty?
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
- puts "!! ERROR: unsupported match status >#{m['status']}< - sorry:"
258
- pp m
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
- team1,
258
+ team1_name,
303
259
  ft,
304
260
  ht,
305
- team2,
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.keys.size} 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 |name, count|
422
- rec = teams_by_name[ name ]
423
- print " #{count}x "
424
- print name
425
- if rec
426
- print " | #{rec['shortName']} " if name != rec['shortName']
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 convert
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 convert
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"
@@ -2,7 +2,7 @@
2
2
  module FootballdataApi
3
3
  MAJOR = 2026 ## todo: namespace inside version or something - why? why not??
4
4
  MINOR = 7
5
- PATCH = 11
5
+ PATCH = 12
6
6
  VERSION = [MAJOR,MINOR,PATCH].join('.')
7
7
 
8
8
  def self.version
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/convert_json-stages'
42
- require_relative 'footballdata/convert_json-teams'
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.11
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 00:00:00.000000000 Z
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