footballdata-api 0.3.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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