footballdata-api 0.3.0 → 0.4.1

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: a0fe438df785fdc33e14a57346b2ec720029a97e34ae4a5eaeddf4e7fa4d8cda
4
- data.tar.gz: e4eaf71567d20a666525139d94dbe4323fb2c8773e245b67454281e6740a9cb4
3
+ metadata.gz: 0556b03185d985c2f364151400a6dfe04ee9160e8560739e005e00a3e872b806
4
+ data.tar.gz: 17711037928d5c213a7915245a2d511e7fba6f4c47ff582357616c87a1ffd7cc
5
5
  SHA512:
6
- metadata.gz: 4081619b75253f9ad57b77ef6232e262b37af91a6e154e3832274520d7363a150a38ddf5a6596d12c5e28646419e530c569a902a74b807f78c987de02104e92f
7
- data.tar.gz: 2639c457fea6f4c4a7cae24196f8133e72ccfa80c433963726b17b498f7e2fcb34dfbe7ae64afb78c76ebc5ff120905cc2f71b3ceec05deb5a535140b6761faa
6
+ metadata.gz: d1bbeef48c5633b97e984e535857ba294a3326cddf1fd6d20ea426d33c95c0e0c7d6e9d12f9fa4a97a12291ba3c1d12e4751f57a5f0bfe3e736ebcf34be56f51
7
+ data.tar.gz: 2640f463715d6a0ff697502dfdd8af38e3c7cf0d6dafc0fb575d44360b548a692ff9c256d6e3ad4e9673dd108636969f372d7a2e153d872ee8c240b2e470e4c6
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ### 0.3.0
1
+ ### 0.4.1
2
2
 
3
3
  ### 0.0.1 / 2024-07-03
4
4
 
data/Manifest.txt CHANGED
@@ -3,7 +3,9 @@ Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
5
  bin/fbdat
6
+ config/leagues.csv
6
7
  lib/footballdata.rb
8
+ lib/footballdata/convert-score.rb
7
9
  lib/footballdata/convert.rb
8
10
  lib/footballdata/download.rb
9
11
  lib/footballdata/leagues.rb
data/Rakefile CHANGED
@@ -18,10 +18,8 @@ Hoe.spec 'footballdata-api' do
18
18
  self.history_file = 'CHANGELOG.md'
19
19
 
20
20
  self.extra_deps = [
21
- ['tzinfo'],
22
- ['season-formats'],
21
+ ['football-timezones'],
23
22
  ['webget'],
24
- ['cocos'], ## later pull in with sportsdb-writers
25
23
  ]
26
24
 
27
25
  self.licenses = ['Public Domain']
data/bin/fbdat CHANGED
@@ -20,12 +20,17 @@ Webcache.root = if File.exist?( '/sports/cache' )
20
20
  ## (one request every 6 seconds 6*10=60 secs)
21
21
  ## 10 API calls per minute max.
22
22
  ## note - default sleep (delay in secs) is 3 sec(s)
23
- Webget.config.sleep = 10
24
23
 
25
-
26
- Footballdata.config.convert.out_dir = '/sports/cache.api.fbdat' if File.exist?( '/sports/cache.api.fbdat' )
24
+ ## change from 10 to 1 sec(s) for interactive use
25
+ Webget.config.sleep = 1
27
26
 
28
27
 
28
+ Footballdata.config.convert.out_dir = if File.exist?( '/sports/cache.api.fbdat' )
29
+ puts " setting convert out_dir to >/sports/cache.api.fbdat<"
30
+ '/sports/cache.api.fbdat'
31
+ else
32
+ '.' ## use working dir
33
+ end
29
34
 
30
35
 
31
36
  require 'optparse'
@@ -166,19 +171,12 @@ end
166
171
  ## note - only use "generic" uniform league codes for now!!
167
172
 
168
173
  league_code = (args[0] || 'eng.1').downcase
169
- metal_league_code = nil ## todo - find a better name
170
- ## use internal_league_code or such - why? why not?
171
174
 
175
+ ## todo - find a better name
176
+ ## use internal_league_code or such - why? why not?
172
177
  ### convenience helpers - lets you use eng.1, euro, etc.
173
178
  ## check if mapping for league_code
174
- if LEAGUES.has_key?( league_code )
175
- metal_league_code = LEAGUES[ league_code ]
176
- else
177
- puts "!! ERROR - no code/mapping found for league >#{league_code}<"
178
- puts " mappings include:"
179
- pp LEAGUES
180
- exit 1
181
- end
179
+ metal_league_code = find_league!( league_code )
182
180
 
183
181
 
184
182
  season = Season( args[1] ||
@@ -0,0 +1,54 @@
1
+ key, code
2
+
3
+ eng.1, PL # incl. team(s) from wales
4
+ eng.2, ELC
5
+ # PL - Premier League, England 27 seasons | 2019-08-09 - 2020-07-25 / matchday 31
6
+ # ELC - Championship, England 3 seasons | 2019-08-02 - 2020-07-22 / matchday 38
7
+ #
8
+ # 2019 => 2019/20
9
+ # 2018 => 2018/19
10
+ # 2017 => xxx 2017-18 - requires subscription !!!
11
+
12
+ es.1, PD
13
+ # PD - Primera Division, Spain 27 seasons | 2019-08-16 - 2020-07-19 / matchday 31
14
+
15
+ pt.1, PPL
16
+ # PPL - Primeira Liga, Portugal 9 seasons | 2019-08-10 - 2020-07-26 / matchday 28
17
+
18
+ de.1, BL1
19
+ # BL1 - Bundesliga, Germany 24 seasons | 2019-08-16 - 2020-06-27 / matchday 34
20
+
21
+ nl.1, DED
22
+ # DED - Eredivisie, Netherlands 10 seasons | 2019-08-09 - 2020-03-08 / matchday 34
23
+
24
+ fr.1, FL1 # incl. team(s) monaco
25
+ # FL1 - Ligue 1, France
26
+ # 9 seasons | 2019-08-09 - 2020-05-31 / matchday 38
27
+ #
28
+ # 2019 => 2019/20
29
+ # 2018 => 2018/19
30
+ # 2017 => xxx 2017-18 - requires subscription !!!
31
+
32
+ it.1, SA
33
+ # SA - Serie A, Italy 15 seasons | 2019-08-24 - 2020-08-02 / matchday 27
34
+
35
+ br.1, BSA
36
+ # BSA - Série A, Brazil
37
+ # 4 seasons | 2020-05-03 - 2020-12-06 / matchday 10
38
+ #
39
+ # 2020 => 2020
40
+ # 2019 => 2019
41
+ # 2018 => 2018
42
+ # 2017 => xxx 2017 - requires subscription !!!
43
+
44
+ uefa.cl, CL ## note: cl is country code for chile!! - use champs - why? why not?
45
+ ## was europe.cl / cl
46
+ ## todo/check: use champs and NOT cl - why? why not?
47
+
48
+ copa.l, CLI
49
+ ## Copa Libertadores
50
+
51
+ ############
52
+ ## national teams
53
+ euro, EC
54
+ world, WC
@@ -0,0 +1,44 @@
1
+
2
+ module Footballdata
3
+
4
+ def self.convert_score( score )
5
+ ## duration: REGULAR · PENALTY_SHOOTOUT · EXTRA_TIME
6
+ ft, ht, et, pen = ["","","",""]
7
+
8
+ if score['duration'] == 'REGULAR'
9
+ ft = "#{score['fullTime']['home']}-#{score['fullTime']['away']}"
10
+ ht = "#{score['halfTime']['home']}-#{score['halfTime']['away']}"
11
+ elsif score['duration'] == 'EXTRA_TIME'
12
+ et = "#{score['regularTime']['home']+score['extraTime']['home']}"
13
+ et << "-"
14
+ et << "#{score['regularTime']['away']+score['extraTime']['away']}"
15
+
16
+ ft = "#{score['regularTime']['home']}-#{score['regularTime']['away']}"
17
+ ht = "#{score['halfTime']['home']}-#{score['halfTime']['away']}"
18
+ elsif score['duration'] == 'PENALTY_SHOOTOUT'
19
+ if score['extraTime']
20
+ ## quick & dirty hack - calc et via regulartime+extratime
21
+ pen = "#{score['penalties']['home']}-#{score['penalties']['away']}"
22
+ et = "#{score['regularTime']['home']+score['extraTime']['home']}"
23
+ et << "-"
24
+ et << "#{score['regularTime']['away']+score['extraTime']['away']}"
25
+
26
+ ft = "#{score['regularTime']['home']}-#{score['regularTime']['away']}"
27
+ ht = "#{score['halfTime']['home']}-#{score['halfTime']['away']}"
28
+ else ### south american-style (no extra time)
29
+ ## quick & dirty hacke - calc ft via fullTime-penalties
30
+ pen = "#{score['penalties']['home']}-#{score['penalties']['away']}"
31
+ ft = "#{score['fullTime']['home']-score['penalties']['home']}"
32
+ ft << "-"
33
+ ft << "#{score['fullTime']['away']-score['penalties']['away']}"
34
+ ht = "#{score['halfTime']['home']}-#{score['halfTime']['away']}"
35
+ end
36
+ else
37
+ puts "!! unknown score duration:"
38
+ pp score
39
+ exit 1
40
+ end
41
+
42
+ [ft,ht,et,pen]
43
+ end
44
+ end # module Footballdata
@@ -1,83 +1,6 @@
1
1
 
2
-
3
-
4
2
  module Footballdata
5
3
 
6
-
7
- TIMEZONES = {
8
- 'eng.1' => 'Europe/London',
9
- 'eng.2' => 'Europe/London',
10
-
11
- 'es.1' => 'Europe/Madrid',
12
-
13
- 'de.1' => 'Europe/Berlin',
14
- 'fr.1' => 'Europe/Paris',
15
- 'it.1' => 'Europe/Rome',
16
- 'nl.1' => 'Europe/Amsterdam',
17
-
18
- 'pt.1' => 'Europe/Lisbon',
19
-
20
- ## for champs default for not to cet (central european time) - why? why not?
21
- 'uefa.cl' => 'Europe/Paris',
22
- 'euro' => 'Europe/Paris',
23
-
24
- ## todo/fix - pt.1
25
- ## one team in madeira!!! check for different timezone??
26
- ## CD Nacional da Madeira
27
-
28
- 'br.1' => 'America/Sao_Paulo',
29
- ## todo/fix - brazil has 4 timezones
30
- ## really only two in use for clubs
31
- ## west and east (amazonas et al)
32
- ## for now use west for all - why? why not?
33
- 'copa.l' => 'America/Sao_Paulo',
34
- }
35
-
36
-
37
-
38
-
39
- def self.convert_score( score )
40
- ## duration: REGULAR · PENALTY_SHOOTOUT · EXTRA_TIME
41
- ft, ht, et, pen = ["","","",""]
42
-
43
- if score['duration'] == 'REGULAR'
44
- ft = "#{score['fullTime']['home']}-#{score['fullTime']['away']}"
45
- ht = "#{score['halfTime']['home']}-#{score['halfTime']['away']}"
46
- elsif score['duration'] == 'EXTRA_TIME'
47
- et = "#{score['regularTime']['home']+score['extraTime']['home']}"
48
- et << "-"
49
- et << "#{score['regularTime']['away']+score['extraTime']['away']}"
50
-
51
- ft = "#{score['regularTime']['home']}-#{score['regularTime']['away']}"
52
- ht = "#{score['halfTime']['home']}-#{score['halfTime']['away']}"
53
- elsif score['duration'] == 'PENALTY_SHOOTOUT'
54
- if score['extraTime']
55
- ## quick & dirty hack - calc et via regulartime+extratime
56
- pen = "#{score['penalties']['home']}-#{score['penalties']['away']}"
57
- et = "#{score['regularTime']['home']+score['extraTime']['home']}"
58
- et << "-"
59
- et << "#{score['regularTime']['away']+score['extraTime']['away']}"
60
-
61
- ft = "#{score['regularTime']['home']}-#{score['regularTime']['away']}"
62
- ht = "#{score['halfTime']['home']}-#{score['halfTime']['away']}"
63
- else ### south american-style (no extra time)
64
- ## quick & dirty hacke - calc ft via fullTime-penalties
65
- pen = "#{score['penalties']['home']}-#{score['penalties']['away']}"
66
- ft = "#{score['fullTime']['home']-score['penalties']['home']}"
67
- ft << "-"
68
- ft << "#{score['fullTime']['away']-score['penalties']['away']}"
69
- ht = "#{score['halfTime']['home']}-#{score['halfTime']['away']}"
70
- end
71
- else
72
- puts "!! unknown score duration:"
73
- pp score
74
- exit 1
75
- end
76
-
77
- [ft,ht,et,pen]
78
- end
79
-
80
-
81
4
  #######
82
5
  ## map round-like to higher-level stages
83
6
  STAGES = {
@@ -114,16 +37,9 @@ STAGES = {
114
37
 
115
38
  def self.convert( league:, season: )
116
39
 
117
- ### note/fix: cl (champions league for now is a "special" case)
118
- # if league.downcase == 'cl'
119
- # convert_cl( league: league,
120
- # season: season )
121
- # return
122
- # end
123
-
124
40
  season = Season( season ) ## cast (ensure) season class (NOT string, integer, etc.)
125
41
 
126
- league_code = LEAGUES[league.downcase]
42
+ league_code = find_league!( league )
127
43
 
128
44
  matches_url = Metal.competition_matches_url( league_code, season.start_year )
129
45
  teams_url = Metal.competition_teams_url( league_code, season.start_year )
@@ -132,14 +48,10 @@ def self.convert( league:, season: )
132
48
  data_teams = Webcache.read_json( teams_url )
133
49
 
134
50
 
135
- ## check for time zone
136
- tz_name = TIMEZONES[ league.downcase ]
137
- if tz_name.nil?
138
- puts "!! ERROR - sorry no timezone configured for league #{league}"
139
- exit 1
140
- end
141
51
 
142
- tz = TZInfo::Timezone.get( tz_name )
52
+ ## check for time zone
53
+ tz = find_zone!( league: league,
54
+ season: season )
143
55
  pp tz
144
56
 
145
57
  ## build a (reverse) team lookup by name
@@ -275,35 +187,35 @@ matches.each do |m|
275
187
  end
276
188
 
277
189
 
278
- ##
279
- ## add time, timezone(tz)
280
- ## 2023-08-18T18:30:00Z
281
- ## e.g. "utcDate": "2020-05-09T00:00:00Z",
282
- ## "utcDate": "2023-08-18T18:30:00Z",
283
-
284
- ## -- todo - make sure / assert it's always utc - how???
285
- ## utc = ## tz_utc.strptime( m['utcDate'], '%Y-%m-%dT%H:%M:%SZ' )
286
- ## note: DateTime.strptime is supposed to be unaware of timezones!!!
287
- ## use to parse utc
288
- utc = DateTime.strptime( m['utcDate'], '%Y-%m-%dT%H:%M:%SZ' ).to_time.utc
289
- assert( utc.strftime( '%Y-%m-%dT%H:%M:%SZ' ) == m['utcDate'], 'utc time mismatch' )
290
190
 
291
- local = tz.to_local( utc )
191
+ utc = UTC.strptime( m['utcDate'], '%Y-%m-%dT%H:%M:%SZ' )
192
+ assert( utc.strftime( '%Y-%m-%dT%H:%M:%SZ' ) == m['utcDate'], 'utc time mismatch' )
292
193
 
293
194
 
294
195
  ## do NOT add time if status is SCHEDULED
295
196
  ## or POSTPONED for now
296
197
  ## otherwise assume time always present - why? why not?
198
+ ##
199
+ ## assume NOT valid utc time if 00:00
200
+ if utc.hour == 0 && utc.min == 0 &&
201
+ ['SCHEDULED','POSTPONED'].include?( m['status'] )
202
+ date = utc.strftime( '%Y-%m-%d' )
203
+ time = ''
204
+ timezone = ''
205
+ else
206
+ local = tz.to_local( utc )
207
+ date = local.strftime( '%Y-%m-%d' )
208
+ time = local.strftime( '%H:%M' )
209
+ timezone = local.strftime( '%Z/%z' )
210
+ end
297
211
 
298
212
 
299
-
300
- ## todo/fix: assert matchday is a number e.g. 1,2,3, etc.!!!
301
213
  recs << [stage,
302
214
  group,
303
215
  matchday,
304
- local.strftime( '%Y-%m-%d' ),
305
- ['SCHEDULED','POSTPONED'].include?( m['status'] ) ? '' : local.strftime( '%H:%M' ),
306
- local.strftime( '%Z / UTC%z' ),
216
+ date,
217
+ time,
218
+ timezone,
307
219
  team1,
308
220
  ft,
309
221
  ht,
@@ -6,7 +6,7 @@ module Footballdata
6
6
  def self.schedule( league:, season: )
7
7
  season = Season( season ) ## cast (ensure) season class (NOT string, integer, etc.)
8
8
 
9
- league_code = LEAGUES[ league.downcase ]
9
+ league_code = find_league!( league )
10
10
  puts " mapping league >#{league}< to >#{league_code}<"
11
11
 
12
12
  Metal.teams( league_code, season.start_year )
@@ -17,7 +17,7 @@ end
17
17
  def self.matches( league:, season: )
18
18
  season = Season( season ) ## cast (ensure) season class (NOT string, integer, etc.)
19
19
 
20
- league_code = LEAGUES[ league.downcase ]
20
+ league_code = find_league!( league )
21
21
  puts " mapping league >#{league}< to >#{league_code}<"
22
22
  Metal.matches( league_code, season.start_year )
23
23
  end
@@ -26,7 +26,7 @@ end
26
26
  def self.teams( league:, season: )
27
27
  season = Season( season ) ## cast (ensure) season class (NOT string, integer, etc.)
28
28
 
29
- league_code = LEAGUES[ league.downcase ]
29
+ league_code = find_league!( league )
30
30
  puts " mapping league >#{league}< to >#{league_code}<"
31
31
  Metal.teams( league_code, season.start_year )
32
32
  end
@@ -38,7 +38,7 @@ end
38
38
 
39
39
  class Metal
40
40
 
41
- def self.get( url,
41
+ def self.get( url,
42
42
  auth: true,
43
43
  headers: {} )
44
44
 
@@ -84,19 +84,19 @@ class Metal
84
84
  def self.competition_teams_url( code, year ) "#{BASE_URL}/competitions/#{code}/teams?season=#{year}"; end
85
85
  def self.competition_standings_url( code, year ) "#{BASE_URL}/competitions/#{code}/standings?season=#{year}"; end
86
86
  def self.competition_scorers_url( code, year ) "#{BASE_URL}/competitions/#{code}/scorers?season=#{year}"; end
87
-
87
+
88
88
  def self.matches( code, year,
89
- headers: {} )
90
- get( competition_matches_url( code, year ),
91
- headers: headers )
89
+ headers: {} )
90
+ get( competition_matches_url( code, year ),
91
+ headers: headers )
92
92
  end
93
93
 
94
- def self.todays_matches_url( date=Date.today )
94
+ def self.todays_matches_url( date=Date.today )
95
95
  "#{BASE_URL}/matches?"+
96
96
  "dateFrom=#{date.strftime('%Y-%m-%d')}&"+
97
- "dateTo=#{(date+1).strftime('%Y-%m-%d')}"
97
+ "dateTo=#{(date+1).strftime('%Y-%m-%d')}"
98
98
  end
99
- def self.todays_matches( date=Date.today ) ## use/rename to matches_today or such - why? why not?
99
+ def self.todays_matches( date=Date.today ) ## use/rename to matches_today or such - why? why not?
100
100
  get( todays_matches_url( date ) )
101
101
  end
102
102
 
@@ -1,59 +1,24 @@
1
1
  module Footballdata
2
2
 
3
- LEAGUES = {
4
- 'eng.1' => 'PL', # incl. team(s) from wales
5
- 'eng.2' => 'ELC',
6
- # PL - Premier League , England 27 seasons | 2019-08-09 - 2020-07-25 / matchday 31
7
- # ELC - Championship , England 3 seasons | 2019-08-02 - 2020-07-22 / matchday 38
8
- #
9
- # 2019 => 2019/20
10
- # 2018 => 2018/19
11
- # 2017 => xxx 2017-18 - requires subscription !!!
12
-
13
- 'es.1' => 'PD',
14
- # PD - Primera Division , Spain 27 seasons | 2019-08-16 - 2020-07-19 / matchday 31
15
-
16
- 'pt.1' => 'PPL',
17
- # PPL - Primeira Liga , Portugal 9 seasons | 2019-08-10 - 2020-07-26 / matchday 28
18
-
19
- 'de.1' => 'BL1',
20
- # BL1 - Bundesliga , Germany 24 seasons | 2019-08-16 - 2020-06-27 / matchday 34
21
-
22
- 'nl.1' => 'DED',
23
- # DED - Eredivisie , Netherlands 10 seasons | 2019-08-09 - 2020-03-08 / matchday 34
24
-
25
- 'fr.1' => 'FL1', # incl. team(s) monaco
26
- # FL1 - Ligue 1, France
27
- # 9 seasons | 2019-08-09 - 2020-05-31 / matchday 38
28
- #
29
- # 2019 => 2019/20
30
- # 2018 => 2018/19
31
- # 2017 => xxx 2017-18 - requires subscription !!!
32
-
33
- 'it.1' => 'SA',
34
- # SA - Serie A , Italy 15 seasons | 2019-08-24 - 2020-08-02 / matchday 27
35
-
36
- 'br.1' => 'BSA',
37
- # BSA - Série A, Brazil
38
- # 4 seasons | 2020-05-03 - 2020-12-06 / matchday 10
39
- #
40
- # 2020 => 2020
41
- # 2019 => 2019
42
- # 2018 => 2018
43
- # 2017 => xxx 2017 - requires subscription !!!
44
-
45
- ## todo/check: use champs and NOT cl - why? why not?
46
- 'uefa.cl' => 'CL', ## note: cl is country code for chile!! - use champs - why? why not?
47
- ## was europe.cl / cl
48
-
49
- ## Copa Libertadores
50
- 'copa.l' => 'CLI',
51
-
52
- ############
53
- ## national teams
54
- 'euro' => 'EC',
55
- 'world' => 'WC',
56
-
57
- }
3
+ def self.find_league!( league )
4
+ @leagues ||= begin
5
+ recs = read_csv( "#{FootballdataApi.root}/config/leagues.csv" )
6
+ leagues = {}
7
+ recs.each do |rec|
8
+ leagues[ rec['key'] ] = rec['code']
9
+ end
10
+ leagues
11
+ end
12
+
13
+ key = league.downcase
14
+ code = @leagues[ key ]
15
+ if code.nil?
16
+ puts "!! ERROR - no code/mapping found for league >#{league}<"
17
+ puts " mappings include:"
18
+ pp @leagues
19
+ exit 1
20
+ end
21
+ code
22
+ end
58
23
  end # module Footballdata
59
24
 
@@ -8,9 +8,9 @@ module Footballdata
8
8
  def self.export_teams( league:, season: )
9
9
 
10
10
  season = Season( season ) ## cast (ensure) season class (NOT string, integer, etc.)
11
- league_code = LEAGUES[league.downcase]
11
+ league_code = find_league!( league )
12
12
 
13
- teams_url = Metal.competition_teams_url( league_code,
13
+ teams_url = Metal.competition_teams_url( league_code,
14
14
  season.start_year )
15
15
  data_teams = Webcache.read_json( teams_url )
16
16
 
@@ -22,12 +22,12 @@ def self.export_teams( league:, season: )
22
22
  clubs = {} ## by country
23
23
 
24
24
  data_teams['teams'].each do |rec|
25
-
26
- buf = String.new ### use for string buffer (or String.new('') - why? why not?
25
+
26
+ buf = String.new ### use for string buffer (or String.new('') - why? why not?
27
27
  buf << "#{rec['name']}"
28
28
  buf << ", #{rec['founded']}" if rec['founded']
29
- if rec['venue']
30
- buf << ", @ #{rec['venue']}"
29
+ if rec['venue']
30
+ buf << ", @ #{rec['venue']}"
31
31
  # buf << " # #{rec['area']['name']}"
32
32
  end
33
33
  buf << "\n"
@@ -39,7 +39,7 @@ def self.export_teams( league:, season: )
39
39
 
40
40
  alt_names << " | #{rec['tla']}" if rec['tla'] &&
41
41
  rec['tla'] != rec['name']
42
-
42
+
43
43
  if alt_names.size > 0
44
44
  buf << " "
45
45
  buf << alt_names
@@ -48,7 +48,7 @@ def self.export_teams( league:, season: )
48
48
 
49
49
  ## clean null in address (or keep nulls) - why? why not?
50
50
  ## e.g. null Rionegro null
51
- ## Calle 104 No. 13a - 32 Bogotá null
51
+ ## Calle 104 No. 13a - 32 Bogotá null
52
52
 
53
53
  buf << " address: #{rec['address'].gsub( /\bnull\b/, '')}"
54
54
  buf << "\n"
@@ -57,21 +57,21 @@ def self.export_teams( league:, season: )
57
57
  buf << " colors: #{rec['clubColors']}"
58
58
  buf << "\n"
59
59
 
60
- country = rec['area']['name']
60
+ country = rec['area']['name']
61
61
  ary = clubs[ country] ||= []
62
62
  ary << buf
63
63
  end
64
64
  # puts buf
65
-
65
+
66
66
  ## pp clubs
67
67
 
68
-
68
+
69
69
  buf = String.new
70
70
 
71
71
  if clubs.size > 1
72
72
  clubs.each do |country, ary|
73
73
  buf << "# #{country} - #{ary.size} clubs\n"
74
- end
74
+ end
75
75
  buf << "\n"
76
76
  end
77
77
 
@@ -82,9 +82,8 @@ def self.export_teams( league:, season: )
82
82
  end
83
83
 
84
84
  path = "#{config.convert.out_dir}/#{season.to_path}/#{league.downcase}.clubs.txt"
85
- write_text( path, buf )
85
+ write_text( path, buf )
86
86
  end
87
87
 
88
88
 
89
89
  end # module Footballdata
90
-
@@ -1,8 +1,8 @@
1
1
 
2
2
  module FootballdataApi
3
3
  MAJOR = 0 ## todo: namespace inside version or something - why? why not??
4
- MINOR = 3
5
- PATCH = 0
4
+ MINOR = 4
5
+ PATCH = 1
6
6
  VERSION = [MAJOR,MINOR,PATCH].join('.')
7
7
 
8
8
  def self.version
data/lib/footballdata.rb CHANGED
@@ -1,14 +1,8 @@
1
1
  ## 3rd party (our own)
2
- require 'season/formats' ## add season support
2
+ require 'football/timezones' # note - pulls in season/formats, cocos & tzinfo
3
3
  require 'webget' ## incl. webget, webcache, webclient, etc.
4
4
 
5
5
 
6
- require 'cocos' ## check if webget incl. cocos ??
7
-
8
-
9
- require 'tzinfo'
10
-
11
-
12
6
  module Footballdata
13
7
  class Configuration
14
8
  #########
@@ -36,11 +30,13 @@ end # module Footballdata
36
30
  # our own code
37
31
  require_relative 'footballdata/version'
38
32
  require_relative 'footballdata/leagues'
33
+
39
34
  require_relative 'footballdata/download'
40
35
  require_relative 'footballdata/prettyprint'
41
36
 
42
37
  require_relative 'footballdata/mods'
43
38
  require_relative 'footballdata/convert'
39
+ require_relative 'footballdata/convert-score'
44
40
  require_relative 'footballdata/teams'
45
41
 
46
42
 
metadata CHANGED
@@ -1,31 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: footballdata-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-08 00:00:00.000000000 Z
11
+ date: 2024-09-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: tzinfo
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: season-formats
14
+ name: football-timezones
29
15
  requirement: !ruby/object:Gem::Requirement
30
16
  requirements:
31
17
  - - ">="
@@ -52,20 +38,6 @@ dependencies:
52
38
  - - ">="
53
39
  - !ruby/object:Gem::Version
54
40
  version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: cocos
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
41
  - !ruby/object:Gem::Dependency
70
42
  name: rdoc
71
43
  requirement: !ruby/object:Gem::Requirement
@@ -116,7 +88,9 @@ files:
116
88
  - README.md
117
89
  - Rakefile
118
90
  - bin/fbdat
91
+ - config/leagues.csv
119
92
  - lib/footballdata.rb
93
+ - lib/footballdata/convert-score.rb
120
94
  - lib/footballdata/convert.rb
121
95
  - lib/footballdata/download.rb
122
96
  - lib/footballdata/leagues.rb