footballdata-api 2026.7.2 → 2026.7.11

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: 285333f5aeaa22a6e531e570f7d41ba43970f73d735e1faca3885d1e0c3387f7
4
- data.tar.gz: 8e3fddb191ba66045b9c80526d80187b17ec05281603e17a8ea057c1779b6bd8
3
+ metadata.gz: 7dc56c0d0418eab7317862787fc928fe1102785d1768f75b242fb3ab52e140b6
4
+ data.tar.gz: 83fcf18d6a491b1cc9cff38a38de13cbdfe184b9400ae78678aa479b5517ff92
5
5
  SHA512:
6
- metadata.gz: 54da6c832674994199a490fab7a047872f45c43b0e33f399a081e94ab38157168a6882e675fab18790f2a573011fdf8f698b9a8ac3a727af9626cd4794def106
7
- data.tar.gz: bcff64f55b28e0e62b08d3f7b5e4bf739755c5bf832e6026318935329aebbc82aca3d8e03d7b9a6a49e851b6a7213133a06d7ab4d9c9b5b6bdfddf36596258bc
6
+ metadata.gz: c3c0a16979fc71e903180ddae103249350461d48dab182f90afc94c06b1230e0c1de624b8c1517c79f3a80bb3fadf84d3d7519a64358a96e52fc877b7df6f803
7
+ data.tar.gz: 04ac3d92c132dcce5277300e8ffae5b46eaa16dcede2b780574dbf8a98c6b098fab1e9e2d27231e4fd0aab81a12b8dcc9205c3065f70f79aa48135b9f49894fd
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ### 2026.7.2
1
+ ### 2026.7.11
2
2
  ### 0.0.1 / 2024-07-03
3
3
 
4
4
  * Everything is new. First release.
data/Manifest.txt CHANGED
@@ -6,7 +6,10 @@ bin/fbdat
6
6
  config/leagues_tier1.csv
7
7
  lib/footballdata.rb
8
8
  lib/footballdata/convert-score.rb
9
- lib/footballdata/convert.rb
9
+ lib/footballdata/convert_csv.rb
10
+ lib/footballdata/convert_json-stages.rb
11
+ lib/footballdata/convert_json-teams.rb
12
+ lib/footballdata/convert_json.rb
10
13
  lib/footballdata/download.rb
11
14
  lib/footballdata/leagues.rb
12
15
  lib/footballdata/mods.rb
data/bin/fbdat CHANGED
@@ -200,6 +200,11 @@ autofiller = ->(league_query) {
200
200
  datasets = if opts[:file]
201
201
  read_leagueset( opts[:file], autofill: autofiller )
202
202
  else
203
+
204
+ ### todo or fix/fix/fix - change to build_leagueset
205
+ ## and reserve parse_leagueset( txt ) for
206
+ ## read_leagueset with inline text
207
+
203
208
  parse_leagueset_args( args, autofill: autofiller )
204
209
  end
205
210
 
@@ -244,6 +249,7 @@ if opts[:convert]
244
249
  datasets.each do |league_key, seasons|
245
250
  seasons.each do |season|
246
251
  convert( league: league_key, season: season )
252
+ convert_json( league: league_key, season: season )
247
253
  end
248
254
  end
249
255
  end
@@ -257,4 +263,3 @@ Footballdata.main( ARGV )
257
263
 
258
264
 
259
265
  puts "bye"
260
-
@@ -1,44 +1,44 @@
1
1
  key, code, seasons
2
2
 
3
- eng.1, PL, 2024/25 2023/24 2022/23 2021/22 2020/21
3
+ eng.1, PL, 2026/27 2025/26 2024/25 2023/24 2022/23 2021/22 2020/21
4
4
  # incl. team(s) from wales
5
- eng.2, ELC, 2024/25 2023/24 2022/23 2021/22 2020/21
5
+ eng.2, ELC, 2026/27 2025/26 2024/25 2023/24 2022/23 2021/22 2020/21
6
6
  # PL - Premier League, England 27 seasons | 2019-08-09 - 2020-07-25 / matchday 31
7
7
  # ELC - Championship, England 3 seasons | 2019-08-02 - 2020-07-22 / matchday 38
8
8
 
9
- es.1, PD, 2024/25 2023/24 2022/23 2021/22 2020/21
9
+ es.1, PD, 2026/27 2025/26 2024/25 2023/24 2022/23 2021/22 2020/21
10
10
  # PD - Primera Division, Spain 27 seasons | 2019-08-16 - 2020-07-19 / matchday 31
11
11
 
12
- pt.1, PPL, 2024/25 2023/24 2022/23 2021/22 2020/21
12
+ pt.1, PPL, 2026/27 2025/26 2024/25 2023/24 2022/23 2021/22 2020/21
13
13
  # PPL - Primeira Liga, Portugal 9 seasons | 2019-08-10 - 2020-07-26 / matchday 28
14
14
 
15
- de.1, BL1, 2024/25 2023/24 2022/23 2021/22 2020/21
15
+ de.1, BL1, 2026/27 2025/26 2024/25 2023/24 2022/23 2021/22 2020/21
16
16
  # BL1 - Bundesliga, Germany 24 seasons | 2019-08-16 - 2020-06-27 / matchday 34
17
17
 
18
- nl.1, DED, 2024/25 2023/24 2022/23 2021/22 2020/21
18
+ nl.1, DED, 2026/27 2025/26 2024/25 2023/24 2022/23 2021/22 2020/21
19
19
  # DED - Eredivisie, Netherlands 10 seasons | 2019-08-09 - 2020-03-08 / matchday 34
20
20
 
21
- fr.1, FL1, 2024/25 2023/24 2022/23 2021/22 2020/21
21
+ fr.1, FL1, 2026/27 2025/26 2024/25 2023/24 2022/23 2021/22 2020/21
22
22
  # incl. team(s) monaco
23
23
 
24
- it.1, SA, 2024/25 2023/24 2022/23 2021/22 2020/21
24
+ it.1, SA, 2026/27 2025/26 2024/25 2023/24 2022/23 2021/22 2020/21
25
25
  # SA - Serie A, Italy 15 seasons | 2019-08-24 - 2020-08-02 / matchday 27
26
26
 
27
- br.1, BSA, 2025 2024 2023 2022 2021 2020
27
+ br.1, BSA, 2026 2025 2024 2023 2022 2021 2020
28
28
 
29
29
 
30
30
  ########
31
31
  ## int'l cups
32
- uefa.cl, CL, 2024/25 2023/24 2022/23 2021/22 2020/21
32
+ uefa.cl, CL, 2025/26 2024/25 2023/24 2022/23 2021/22 2020/21
33
33
  ## note: cl is country code for chile!! - use champs - why? why not?
34
34
  ## was europe.cl / cl
35
35
  ## todo/check: use champs and NOT cl - why? why not?
36
36
 
37
- copa.l, CLI, 2025 2024 2023 2022 2021
37
+ copa.l, CLI, 2026 2025 2024 2023 2022 2021
38
38
  ## Copa Libertadores
39
39
 
40
40
 
41
41
  ############
42
42
  ## national teams
43
43
  euro, EC, 2024 2021
44
- world, WC, 2022
44
+ world, WC, 2026 2022
@@ -1,6 +1,15 @@
1
1
 
2
2
  module Footballdata
3
3
 
4
+ ##
5
+ ## note - "weirdo" rule
6
+ ## fullTime is only "classic" fulltime if REGULAR
7
+ ##
8
+ ## otherwise fullTime is aggregate of extraTime AND penalties!!
9
+ ##
10
+ ##
11
+
12
+
4
13
  def self.convert_score( score )
5
14
  ## duration: REGULAR · PENALTY_SHOOTOUT · EXTRA_TIME
6
15
  ft, ht, et, pen = ["","","",""]
@@ -41,4 +50,54 @@ def self.convert_score( score )
41
50
 
42
51
  [ft,ht,et,pen]
43
52
  end
53
+
54
+
55
+
56
+ def self.convert_score_to_hash( score )
57
+ ## duration: REGULAR · PENALTY_SHOOTOUT · EXTRA_TIME
58
+
59
+ if score['duration'] == 'REGULAR'
60
+ { ft: [score['fullTime']['home'],
61
+ score['fullTime']['away']],
62
+ ht: [score['halfTime']['home'],
63
+ score['halfTime']['away']]
64
+ }
65
+ elsif score['duration'] == 'EXTRA_TIME'
66
+ { et: [score['regularTime']['home']+score['extraTime']['home'],
67
+ score['regularTime']['away']+score['extraTime']['away']],
68
+ ft: [score['regularTime']['home'],
69
+ score['regularTime']['away']],
70
+ ht: [score['halfTime']['home'],
71
+ score['halfTime']['away']]
72
+ }
73
+
74
+ elsif score['duration'] == 'PENALTY_SHOOTOUT'
75
+ if score['extraTime']
76
+ ## quick & dirty hack - calc et via regulartime+extratime
77
+ { pen: [score['penalties']['home'],
78
+ score['penalties']['away']],
79
+ et: [score['regularTime']['home']+score['extraTime']['home'],
80
+ score['regularTime']['away']+score['extraTime']['away']],
81
+ ft: [score['regularTime']['home'],
82
+ score['regularTime']['away']],
83
+ ht: [score['halfTime']['home'],
84
+ score['halfTime']['away']]
85
+ }
86
+ else ### south american-style (no extra time)
87
+ ## quick & dirty hacke - calc ft via fullTime-penalties
88
+ { pen: [score['penalties']['home'],
89
+ score['penalties']['away']],
90
+ ft: [score['fullTime']['home']-score['penalties']['home'],
91
+ score['fullTime']['away']-score['penalties']['away']],
92
+ ht: [score['halfTime']['home'],
93
+ score['halfTime']['away']]
94
+ }
95
+ end
96
+ else
97
+ raise ArgumentError, "!! unknown score duration - #{score.inspect}"
98
+ end
99
+ end
100
+
101
+
102
+
44
103
  end # module Footballdata
@@ -26,8 +26,10 @@ STAGES = {
26
26
 
27
27
  'LEAGUE_STAGE' => ['League'],
28
28
  'GROUP_STAGE' => ['Group'],
29
- 'PLAYOFFS' => ['Playoffs'],
29
+ 'PLAYOFFS' => ['Playoffs'], ## used in champs
30
+ 'PLAY_OFFS' => ['Playoffs'], ## used in copa liber.
30
31
 
32
+ 'LAST_32' => ['Finals', 'Round of 32'],
31
33
  'ROUND_OF_16' => ['Finals', 'Round of 16'],
32
34
  'LAST_16' => ['Finals', 'Round of 16'], ## use Last 16 - why? why not?
33
35
  'QUARTER_FINALS' => ['Finals', 'Quarterfinals'],
@@ -67,7 +69,7 @@ def self.convert( league:, season: )
67
69
 
68
70
  season = Season( season ) ## cast (ensure) season class (NOT string, integer, etc.)
69
71
 
70
- ### note - find_league returns the metal_league_code
72
+ ### note - find_league returns the metal_league_code
71
73
  league_code = find_league!( league )
72
74
 
73
75
  matches_url = Metal.competition_matches_url( league_code, season.start_year )
@@ -132,12 +134,6 @@ matches.each do |m|
132
134
  team1 = m['homeTeam']['name'] || 'N.N.'
133
135
  team2 = m['awayTeam']['name'] || 'N.N.'
134
136
 
135
- ## auto-fix copa.l 2024
136
- ## !! ERROR: unsupported match status >IN_PLAY< - sorry:
137
- if m['status'] == 'IN_PLAY' &&
138
- team1 == 'Club Aurora' && team2 == 'FBC Melgar'
139
- m['status'] = 'FINISHED'
140
- end
141
137
 
142
138
 
143
139
 
@@ -185,6 +181,7 @@ matches.each do |m|
185
181
  matchday_num = m['matchday']
186
182
  matchday_num = nil if matchday_num == 0 ## change 0 to nil (empty) too
187
183
 
184
+
188
185
  if stage_round.nil? ## e.g. Regular, League, Group, Playoffs
189
186
  ## keep/assume matchday number is matchday .e.g
190
187
  ## matchday 1, 2 etc.
@@ -206,6 +203,7 @@ matches.each do |m|
206
203
  team2 = mods[ team2 ] if mods[ team2 ]
207
204
  end
208
205
 
206
+
209
207
  ####
210
208
  # auto-add (fifa) country code if int'l club tournament
211
209
  if clubs_intl
@@ -513,5 +511,3 @@ def self.vacuum( rows, headers: MAX_HEADERS, fixed_headers: MIN_HEADERS )
513
511
  [rows, headers]
514
512
  end
515
513
  end # module Footballdata
516
-
517
-
@@ -0,0 +1,20 @@
1
+
2
+ class Stages
3
+ def initialize
4
+ @recs = {}
5
+ end
6
+
7
+ def add_matches( matches )
8
+ matches.each do |m|
9
+ name = m['stage']
10
+ rec = @recs[name] ||= { name: name,
11
+ count: 0 }
12
+ rec[:count] +=1
13
+ end
14
+ end
15
+
16
+ def as_json() @recs.values; end
17
+
18
+ def size() @recs.size; end
19
+
20
+ end # class Stages
@@ -0,0 +1,124 @@
1
+
2
+ =begin
3
+
4
+ note - for address "null null null",
5
+ is street + city + postal_code/
6
+
7
+
8
+ {"area"=>{"id"=>2061, "name"=>"Cyprus", "code"=>"CYP", "flag"=>nil},
9
+ "id"=>11034,
10
+ "name"=>"Paphos FC",
11
+ "shortName"=>"Paphos FC",
12
+ "tla"=>"AEP",
13
+ "address"=>"null null null",
14
+ "website"=>nil,
15
+ "founded"=>nil,
16
+ "clubColors"=>nil,
17
+ "venue"=>"Alphamega Stadium",
18
+
19
+ {"area"=>{"id"=>2119, "name"=>"Kazakhstan", "code"=>"KAZ", "flag"=>nil},
20
+ "id"=>10601,
21
+ "name"=>"FK Kairat",
22
+ "shortName"=>"FK Kairat",
23
+ "tla"=>"KAI",
24
+ "address"=>"null null null",
25
+ "website"=>nil,
26
+ "founded"=>nil,
27
+ "clubColors"=>nil,
28
+ "venue"=>nil,
29
+
30
+ {"area"=>{"id"=>2060, "name"=>"Curaçao", "code"=>"CUW", "flag"=>"https://crests.football-data.org/curacao.svg"},
31
+ "id"=>9460,
32
+ "name"=>"Curaçao",
33
+ "shortName"=>"Curaçao",
34
+ "tla"=>"CUW",
35
+ "address"=>"null null null",
36
+ "website"=>nil,
37
+ "founded"=>nil,
38
+ "clubColors"=>nil,
39
+ "venue"=>nil,
40
+
41
+
42
+
43
+ =end
44
+
45
+
46
+
47
+ def build_team( h )
48
+
49
+ rec = { id: h['id'],
50
+ name: h['name'],
51
+ short_name: h['shortName'],
52
+ code: h['tla'],
53
+ address: h['address'], ### street / city / postal_code
54
+ founded: h['founded'],
55
+ ground: h['venue'], ### use stadium or venue ??
56
+
57
+ ##
58
+ ## or use country { code:, name }
59
+ ## change to cc (country code) - why? why not?
60
+ country: { code: h['area']['code'],
61
+ name: h['area']['name'] },
62
+
63
+ count: 0, ## track - match counts
64
+ }
65
+
66
+ rec
67
+ end
68
+
69
+
70
+ class Teams
71
+ def initialize
72
+ @recs = []
73
+ @by_name = {}
74
+ end
75
+
76
+
77
+ def add( recs )
78
+ recs.each do |h|
79
+ rec = build_team( h )
80
+ @recs << rec
81
+
82
+ ## todo/fix - make sure team name is uniq!!!!
83
+ @by_name[rec[:name]] = rec
84
+ @by_name[rec[:short_name]] = rec
85
+ end
86
+ end
87
+
88
+
89
+
90
+ def find_by!( name: )
91
+ rec = @by_name[ name ]
92
+ raise ArgumentError, "team >#{name}< not found; sorry" if rec.nil?
93
+ rec
94
+ end
95
+
96
+
97
+ def add_matches( matches ) ## use/rename to add_matches - why? why not?
98
+ matches.each do |m|
99
+
100
+ ## note - skip teams without name (e.g. N.N.)
101
+ if m['homeTeam']['name']
102
+ rec = find_by!( name: m['homeTeam']['name'] )
103
+ rec[:count] += 1
104
+ end
105
+
106
+ if m['awayTeam']['name']
107
+ rec = find_by!( name: m['awayTeam']['name'] )
108
+ rec[:count] += 1
109
+ end
110
+ end
111
+ end
112
+
113
+
114
+ def as_json( id: false )
115
+ if id
116
+ @recs
117
+ else
118
+ @recs.map { |rec| rec.except(:id ) }
119
+ end
120
+ end
121
+
122
+ def size() @recs.size; end
123
+
124
+ end # class Teams
@@ -0,0 +1,186 @@
1
+
2
+ module Footballdata
3
+
4
+
5
+
6
+
7
+
8
+ def self.convert_json( league:, season: )
9
+
10
+ season = Season( season ) ## cast (ensure) season class (NOT string, integer, etc.)
11
+
12
+ ### note - find_league returns the metal_league_code
13
+ league_code = find_league!( league )
14
+
15
+ matches_url = Metal.competition_matches_url( league_code, season.start_year )
16
+ teams_url = Metal.competition_teams_url( league_code, season.start_year )
17
+
18
+ data = Webcache.read_json( matches_url )
19
+ data_teams = Webcache.read_json( teams_url )
20
+
21
+
22
+ ## note - for international club tournaments
23
+ ## auto-add (fifa) country code e.g.
24
+ ## Liverpool FC => Liverpool FC (ENG)
25
+ ##
26
+ ## todo/fix - move flag to league_info via .csv config - why? why not?
27
+ ## clubs_intl = ['uefa.cl',
28
+ ## 'copa.l'].include?(league.downcase) ? true : false
29
+
30
+ ## build a team lookup by name (& short_name)
31
+
32
+ teams = Teams.new
33
+ teams.add( data_teams['teams'] )
34
+ puts "#{teams.size} team(s)"
35
+
36
+ ## add/update match counts
37
+ teams.add_matches( data['matches'] )
38
+
39
+
40
+ stages = Stages.new
41
+ stages.add_matches( data['matches'] )
42
+
43
+
44
+ recs = []
45
+
46
+
47
+ ## track (meta stats) stage, match status et
48
+ stats = { status: Hash.new(0), ## e.g. TIMED,etc
49
+ score: Hash.new(0), ## e.g. REGULAR,etc.
50
+ }
51
+
52
+
53
+
54
+
55
+ data[ 'matches'].each do |m|
56
+
57
+ ## use ? or N.N. or ? for nil - why? why not?
58
+ team1_name = m['homeTeam']['name']
59
+ team2_name = m['awayTeam']['name']
60
+
61
+ team1 = team1_name ? teams.find_by!(name: team1_name ) : { name: 'N.N.' }
62
+ team2 = team2_name ? teams.find_by!(name: team2_name ) : { name: 'N.N.' }
63
+
64
+
65
+ stage = m['stage']
66
+ group = m['group']
67
+
68
+ matchday = m['matchday']
69
+ matchday = nil if matchday == 0 ## change 0 to nil (empty) too
70
+
71
+
72
+ stats[:status][m['status']] += 1 ## track status counts
73
+ stats[:score][m['score']['duration']] += 1
74
+
75
+ case m['status']
76
+ when 'SCHEDULED', 'TIMED',
77
+ 'PAUSED', 'IN_PLAY' ## IN_PLAY, PAUSED
78
+ score = []
79
+ when 'FINISHED'
80
+ score = convert_score_to_hash( m['score'] )
81
+ when 'AWARDED' # AWARDED
82
+ assert( m['score']['duration'] == 'REGULAR', 'score.duration REGULAR expected' )
83
+ score = [m['score']['fullTime']['home'],
84
+ m['score']['fullTime']['away']]
85
+ when 'CANCELLED'
86
+ ## note cancelled might have scores!! -- add/fix later!!!
87
+ ## ht only or ft+ht!!! (see fr 2021/22)
88
+ ## score = convert_score_to_hash( m['score'] )
89
+ ##
90
+ ## note - there is cancelled (e.g. not/played) AND
91
+ ## annulled/voided (e.g. played!! with score)
92
+ score = []
93
+ when 'POSTPONED'
94
+ score = []
95
+ else
96
+ raise ArgumentError,
97
+ "unsupported match status >#{m['status']}< - sorry: #{m.pretty_inspect}"
98
+ end
99
+
100
+
101
+
102
+ rec = {
103
+ status: m['status'],
104
+ stage: stage
105
+ }
106
+
107
+
108
+ utc = UTC.strptime( m['utcDate'], '%Y-%m-%dT%H:%M:%SZ' )
109
+ assert( utc.strftime( '%Y-%m-%dT%H:%M:%SZ' ) == m['utcDate'], 'utc time mismatch' )
110
+
111
+
112
+ ## do NOT add time if status is SCHEDULED
113
+ ## or POSTPONED for now
114
+ ## otherwise assume time always present - why? why not?
115
+ ##
116
+ ## assume NOT valid utc time if 00:00
117
+ if utc.hour == 0 && utc.min == 0 &&
118
+ ['SCHEDULED','POSTPONED'].include?( m['status'] )
119
+ ## assume local date - why? why not?
120
+ rec[:date] = utc.strftime( '%Y-%m-%d' )
121
+ else
122
+ rec[:date_utc] = utc.strftime( '%Y-%m-%dT%H:%M:%SZ' )
123
+ end
124
+
125
+
126
+
127
+ rec[:group] = group if group
128
+ rec[:matchday] = matchday if matchday
129
+
130
+ rec[:team1] = team1[:name]
131
+ rec[:team2] = team2[:name]
132
+
133
+ rec[:score] = score unless score.empty?
134
+
135
+
136
+ recs << rec
137
+ end
138
+
139
+
140
+ stats[:matches] = recs.size
141
+ stats[:teams] = teams.size
142
+
143
+ data = {
144
+ slug: league,
145
+ season: season.to_s,
146
+ meta: stats,
147
+ stages: stages.as_json,
148
+ teams: teams.as_json,
149
+ matches: recs
150
+ }
151
+
152
+
153
+ path = "#{config.convert.out_dir}/#{season.to_path}/#{league.downcase}.json"
154
+ ## note: change season_key from 2019/20 to 2019-20 (for path/directory!!!!)
155
+ puts " writing to >#{path}<"
156
+ write_json( path, data )
157
+ end # method convert
158
+
159
+
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"
@@ -53,6 +53,7 @@ class Metal
53
53
 
54
54
  request_headers = request_headers.merge( headers ) unless headers.empty?
55
55
 
56
+ ## pp request_headers
56
57
 
57
58
  ## note: add format: 'json' for pretty printing json (before) save in cache
58
59
  response = Webget.call( url, headers: request_headers )
@@ -117,10 +118,12 @@ class Metal
117
118
  get( "#{BASE_URL}/teams/#{id}" )
118
119
  end
119
120
 
120
- def self.match( id )
121
- get( "#{BASE_URL}/matches/#{id}" )
121
+
122
+ def self.match( id, headers: {} )
123
+ get( "#{BASE_URL}/matches/#{id}", headers: headers )
122
124
  end
123
125
 
126
+
124
127
  def self.person( id )
125
128
  get( "#{BASE_URL}/persons/#{id}" )
126
129
  end
@@ -1,3 +1,10 @@
1
+
2
+ ##
3
+ ## todo/fix cleanup
4
+ ## use a "generic" record for lookup
5
+ ##
6
+
7
+
1
8
  module Footballdata
2
9
 
3
10
  def self.find_league!( league )
@@ -48,4 +55,3 @@ module Footballdata
48
55
  seasons
49
56
  end
50
57
  end # module Footballdata
51
-
@@ -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 = 2
5
+ PATCH = 11
6
6
  VERSION = [MAJOR,MINOR,PATCH].join('.')
7
7
 
8
8
  def self.version
data/lib/footballdata.rb CHANGED
@@ -36,8 +36,13 @@ require_relative 'footballdata/download'
36
36
  require_relative 'footballdata/prettyprint'
37
37
 
38
38
  require_relative 'footballdata/mods'
39
- require_relative 'footballdata/convert'
39
+ require_relative 'footballdata/convert_csv'
40
+ require_relative 'footballdata/convert_json'
41
+ require_relative 'footballdata/convert_json-stages'
42
+ require_relative 'footballdata/convert_json-teams'
40
43
  require_relative 'footballdata/convert-score'
44
+
45
+
41
46
  require_relative 'footballdata/teams'
42
47
 
43
48
 
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.2
4
+ version: 2026.7.11
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-02 00:00:00.000000000 Z
11
+ date: 2026-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: leagues
@@ -105,7 +105,10 @@ files:
105
105
  - config/leagues_tier1.csv
106
106
  - lib/footballdata.rb
107
107
  - lib/footballdata/convert-score.rb
108
- - lib/footballdata/convert.rb
108
+ - lib/footballdata/convert_csv.rb
109
+ - lib/footballdata/convert_json-stages.rb
110
+ - lib/footballdata/convert_json-teams.rb
111
+ - lib/footballdata/convert_json.rb
109
112
  - lib/footballdata/download.rb
110
113
  - lib/footballdata/leagues.rb
111
114
  - lib/footballdata/mods.rb