footballdata-api 0.3.1 → 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 +4 -4
- data/CHANGELOG.md +1 -1
- data/Manifest.txt +1 -2
- data/Rakefile +1 -3
- data/bin/fbdat +8 -3
- data/lib/footballdata/convert-score.rb +44 -0
- data/lib/footballdata/convert.rb +5 -68
- data/lib/footballdata/version.rb +1 -1
- data/lib/footballdata.rb +2 -8
- metadata +4 -33
- data/config/timezones.csv +0 -27
- data/lib/footballdata/timezones.rb +0 -97
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0556b03185d985c2f364151400a6dfe04ee9160e8560739e005e00a3e872b806
|
4
|
+
data.tar.gz: 17711037928d5c213a7915245a2d511e7fba6f4c47ff582357616c87a1ffd7cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d1bbeef48c5633b97e984e535857ba294a3326cddf1fd6d20ea426d33c95c0e0c7d6e9d12f9fa4a97a12291ba3c1d12e4751f57a5f0bfe3e736ebcf34be56f51
|
7
|
+
data.tar.gz: 2640f463715d6a0ff697502dfdd8af38e3c7cf0d6dafc0fb575d44360b548a692ff9c256d6e3ad4e9673dd108636969f372d7a2e153d872ee8c240b2e470e4c6
|
data/CHANGELOG.md
CHANGED
data/Manifest.txt
CHANGED
@@ -4,8 +4,8 @@ README.md
|
|
4
4
|
Rakefile
|
5
5
|
bin/fbdat
|
6
6
|
config/leagues.csv
|
7
|
-
config/timezones.csv
|
8
7
|
lib/footballdata.rb
|
8
|
+
lib/footballdata/convert-score.rb
|
9
9
|
lib/footballdata/convert.rb
|
10
10
|
lib/footballdata/download.rb
|
11
11
|
lib/footballdata/leagues.rb
|
@@ -13,5 +13,4 @@ lib/footballdata/mods.rb
|
|
13
13
|
lib/footballdata/prettyprint.rb
|
14
14
|
lib/footballdata/stat.rb
|
15
15
|
lib/footballdata/teams.rb
|
16
|
-
lib/footballdata/timezones.rb
|
17
16
|
lib/footballdata/version.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
|
-
['
|
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
|
-
|
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'
|
@@ -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
|
data/lib/footballdata/convert.rb
CHANGED
@@ -1,49 +1,6 @@
|
|
1
1
|
|
2
2
|
module Footballdata
|
3
3
|
|
4
|
-
|
5
|
-
def self.convert_score( score )
|
6
|
-
## duration: REGULAR · PENALTY_SHOOTOUT · EXTRA_TIME
|
7
|
-
ft, ht, et, pen = ["","","",""]
|
8
|
-
|
9
|
-
if score['duration'] == 'REGULAR'
|
10
|
-
ft = "#{score['fullTime']['home']}-#{score['fullTime']['away']}"
|
11
|
-
ht = "#{score['halfTime']['home']}-#{score['halfTime']['away']}"
|
12
|
-
elsif score['duration'] == 'EXTRA_TIME'
|
13
|
-
et = "#{score['regularTime']['home']+score['extraTime']['home']}"
|
14
|
-
et << "-"
|
15
|
-
et << "#{score['regularTime']['away']+score['extraTime']['away']}"
|
16
|
-
|
17
|
-
ft = "#{score['regularTime']['home']}-#{score['regularTime']['away']}"
|
18
|
-
ht = "#{score['halfTime']['home']}-#{score['halfTime']['away']}"
|
19
|
-
elsif score['duration'] == 'PENALTY_SHOOTOUT'
|
20
|
-
if score['extraTime']
|
21
|
-
## quick & dirty hack - calc et via regulartime+extratime
|
22
|
-
pen = "#{score['penalties']['home']}-#{score['penalties']['away']}"
|
23
|
-
et = "#{score['regularTime']['home']+score['extraTime']['home']}"
|
24
|
-
et << "-"
|
25
|
-
et << "#{score['regularTime']['away']+score['extraTime']['away']}"
|
26
|
-
|
27
|
-
ft = "#{score['regularTime']['home']}-#{score['regularTime']['away']}"
|
28
|
-
ht = "#{score['halfTime']['home']}-#{score['halfTime']['away']}"
|
29
|
-
else ### south american-style (no extra time)
|
30
|
-
## quick & dirty hacke - calc ft via fullTime-penalties
|
31
|
-
pen = "#{score['penalties']['home']}-#{score['penalties']['away']}"
|
32
|
-
ft = "#{score['fullTime']['home']-score['penalties']['home']}"
|
33
|
-
ft << "-"
|
34
|
-
ft << "#{score['fullTime']['away']-score['penalties']['away']}"
|
35
|
-
ht = "#{score['halfTime']['home']}-#{score['halfTime']['away']}"
|
36
|
-
end
|
37
|
-
else
|
38
|
-
puts "!! unknown score duration:"
|
39
|
-
pp score
|
40
|
-
exit 1
|
41
|
-
end
|
42
|
-
|
43
|
-
[ft,ht,et,pen]
|
44
|
-
end
|
45
|
-
|
46
|
-
|
47
4
|
#######
|
48
5
|
## map round-like to higher-level stages
|
49
6
|
STAGES = {
|
@@ -80,13 +37,6 @@ STAGES = {
|
|
80
37
|
|
81
38
|
def self.convert( league:, season: )
|
82
39
|
|
83
|
-
### note/fix: cl (champions league for now is a "special" case)
|
84
|
-
# if league.downcase == 'cl'
|
85
|
-
# convert_cl( league: league,
|
86
|
-
# season: season )
|
87
|
-
# return
|
88
|
-
# end
|
89
|
-
|
90
40
|
season = Season( season ) ## cast (ensure) season class (NOT string, integer, etc.)
|
91
41
|
|
92
42
|
league_code = find_league!( league )
|
@@ -237,22 +187,16 @@ matches.each do |m|
|
|
237
187
|
end
|
238
188
|
|
239
189
|
|
240
|
-
|
241
|
-
## add time, timezone(tz)
|
242
|
-
## 2023-08-18T18:30:00Z
|
243
|
-
## e.g. "utcDate": "2020-05-09T00:00:00Z",
|
244
|
-
## "utcDate": "2023-08-18T18:30:00Z",
|
245
|
-
|
246
|
-
## -- todo - make sure / assert it's always utc - how???
|
247
|
-
## utc = ## tz_utc.strptime( m['utcDate'], '%Y-%m-%dT%H:%M:%SZ' )
|
248
|
-
## note: DateTime.strptime is supposed to be unaware of timezones!!!
|
249
|
-
## use to parse utc
|
190
|
+
|
250
191
|
utc = UTC.strptime( m['utcDate'], '%Y-%m-%dT%H:%M:%SZ' )
|
251
192
|
assert( utc.strftime( '%Y-%m-%dT%H:%M:%SZ' ) == m['utcDate'], 'utc time mismatch' )
|
252
193
|
|
253
194
|
|
195
|
+
## do NOT add time if status is SCHEDULED
|
196
|
+
## or POSTPONED for now
|
197
|
+
## otherwise assume time always present - why? why not?
|
198
|
+
##
|
254
199
|
## assume NOT valid utc time if 00:00
|
255
|
-
## do
|
256
200
|
if utc.hour == 0 && utc.min == 0 &&
|
257
201
|
['SCHEDULED','POSTPONED'].include?( m['status'] )
|
258
202
|
date = utc.strftime( '%Y-%m-%d' )
|
@@ -266,13 +210,6 @@ matches.each do |m|
|
|
266
210
|
end
|
267
211
|
|
268
212
|
|
269
|
-
## do NOT add time if status is SCHEDULED
|
270
|
-
## or POSTPONED for now
|
271
|
-
## otherwise assume time always present - why? why not?
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
## todo/fix: assert matchday is a number e.g. 1,2,3, etc.!!!
|
276
213
|
recs << [stage,
|
277
214
|
group,
|
278
215
|
matchday,
|
data/lib/footballdata/version.rb
CHANGED
data/lib/footballdata.rb
CHANGED
@@ -1,14 +1,8 @@
|
|
1
1
|
## 3rd party (our own)
|
2
|
-
require '
|
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,13 +30,13 @@ end # module Footballdata
|
|
36
30
|
# our own code
|
37
31
|
require_relative 'footballdata/version'
|
38
32
|
require_relative 'footballdata/leagues'
|
39
|
-
require_relative 'footballdata/timezones'
|
40
33
|
|
41
34
|
require_relative 'footballdata/download'
|
42
35
|
require_relative 'footballdata/prettyprint'
|
43
36
|
|
44
37
|
require_relative 'footballdata/mods'
|
45
38
|
require_relative 'footballdata/convert'
|
39
|
+
require_relative 'footballdata/convert-score'
|
46
40
|
require_relative 'footballdata/teams'
|
47
41
|
|
48
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.
|
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-
|
11
|
+
date: 2024-09-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
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
|
@@ -117,8 +89,8 @@ files:
|
|
117
89
|
- Rakefile
|
118
90
|
- bin/fbdat
|
119
91
|
- config/leagues.csv
|
120
|
-
- config/timezones.csv
|
121
92
|
- lib/footballdata.rb
|
93
|
+
- lib/footballdata/convert-score.rb
|
122
94
|
- lib/footballdata/convert.rb
|
123
95
|
- lib/footballdata/download.rb
|
124
96
|
- lib/footballdata/leagues.rb
|
@@ -126,7 +98,6 @@ files:
|
|
126
98
|
- lib/footballdata/prettyprint.rb
|
127
99
|
- lib/footballdata/stat.rb
|
128
100
|
- lib/footballdata/teams.rb
|
129
|
-
- lib/footballdata/timezones.rb
|
130
101
|
- lib/footballdata/version.rb
|
131
102
|
homepage: https://github.com/sportdb/sport.db
|
132
103
|
licenses:
|
data/config/timezones.csv
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
key, zone
|
2
|
-
eng, Europe/London
|
3
|
-
es, Europe/Madrid
|
4
|
-
de, Europe/Berlin
|
5
|
-
fr, Europe/Paris
|
6
|
-
it, Europe/Rome
|
7
|
-
|
8
|
-
nl, Europe/Amsterdam
|
9
|
-
pt, Europe/Lisbon
|
10
|
-
|
11
|
-
## for champs default for not to cet (central european time) - why? why not?
|
12
|
-
uefa.cl, Europe/Paris
|
13
|
-
euro, Europe/Paris
|
14
|
-
|
15
|
-
## todo/fix - pt.1
|
16
|
-
## one team in madeira!!! check for different timezone??
|
17
|
-
## CD Nacional da Madeira
|
18
|
-
|
19
|
-
br, America/Sao_Paulo
|
20
|
-
## todo/fix - brazil has 4 timezones
|
21
|
-
## really only two in use for clubs
|
22
|
-
## west and east (amazonas et al)
|
23
|
-
## for now use west for all - why? why not?
|
24
|
-
copa.l, America/Sao_Paulo
|
25
|
-
|
26
|
-
|
27
|
-
## world+2022, add quatar here
|
@@ -1,97 +0,0 @@
|
|
1
|
-
|
2
|
-
class UTC
|
3
|
-
def self.now() Time.now.utc; end
|
4
|
-
def self.today() now.to_date; end
|
5
|
-
|
6
|
-
## -- todo - make sure / assert it's always utc - how???
|
7
|
-
## utc = ## tz_utc.strptime( m['utcDate'], '%Y-%m-%dT%H:%M:%SZ' )
|
8
|
-
## note: DateTime.strptime is supposed to be unaware of timezones!!!
|
9
|
-
## use to parse utc
|
10
|
-
## quick hack -
|
11
|
-
## use to_time.getutc instead of utc ???
|
12
|
-
def self.strptime( str, format )
|
13
|
-
DateTime.strptime( str, format ).to_time.utc
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.find_zone( name )
|
17
|
-
zone = TZInfo::Timezone.get( name )
|
18
|
-
## wrap tzinfo timezone in our own - for adding more (auto)checks etc.
|
19
|
-
zone ? Timezone.new( zone ) : nil
|
20
|
-
end
|
21
|
-
|
22
|
-
class Timezone ## nested inside UTC
|
23
|
-
## todo/fix
|
24
|
-
## cache timezone - why? why not?
|
25
|
-
def initialize( zone )
|
26
|
-
@zone = zone
|
27
|
-
end
|
28
|
-
|
29
|
-
def to_local( time )
|
30
|
-
## assert time is Time (not Date or DateTIme)
|
31
|
-
## and assert utc!!!
|
32
|
-
assert( time.is_a?( Time ), "time #{time} is NOT of class Time; got #{time.class.name}" )
|
33
|
-
assert( time.utc?, "time #{time} is NOT utc; utc? returns #{time.utc?}" )
|
34
|
-
local = @zone.to_local( time )
|
35
|
-
local
|
36
|
-
end
|
37
|
-
|
38
|
-
def assert( cond, msg )
|
39
|
-
if cond
|
40
|
-
# do nothing
|
41
|
-
else
|
42
|
-
puts "!!! assert failed - #{msg}"
|
43
|
-
exit 1
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end # class Timezone
|
47
|
-
end # class UTC
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
module Footballdata
|
52
|
-
def self.find_zone!( league:, season: )
|
53
|
-
@zones ||= begin
|
54
|
-
recs = read_csv( "#{FootballdataApi.root}/config/timezones.csv" )
|
55
|
-
zones = {}
|
56
|
-
recs.each do |rec|
|
57
|
-
zone = UTC.find_zone( rec['zone'] )
|
58
|
-
if zone.nil?
|
59
|
-
## raise ArgumentError - invalid zone
|
60
|
-
puts "!! ERROR - cannot find timezone in timezone db:"
|
61
|
-
pp rec
|
62
|
-
exit 1
|
63
|
-
end
|
64
|
-
zones[ rec['key']] = zone
|
65
|
-
end
|
66
|
-
zones
|
67
|
-
end
|
68
|
-
|
69
|
-
|
70
|
-
## lookup first try by league+season
|
71
|
-
league_code = league.downcase
|
72
|
-
season = Season( season )
|
73
|
-
|
74
|
-
## e.g. world+2022, etc.
|
75
|
-
key = "#{league_code}+#{season}"
|
76
|
-
zone = @zones[key]
|
77
|
-
|
78
|
-
## try league e.g. eng.1 etc.
|
79
|
-
zone = @zones[league_code] if zone.nil?
|
80
|
-
|
81
|
-
## try first code only (country code )
|
82
|
-
if zone.nil?
|
83
|
-
code, _ = league_code.split( '.', 2 )
|
84
|
-
zone = @zones[code]
|
85
|
-
end
|
86
|
-
|
87
|
-
if zone.nil? ## still not found; report error
|
88
|
-
puts "!! ERROR: no timezone found for #{league} #{season}"
|
89
|
-
exit 1
|
90
|
-
end
|
91
|
-
|
92
|
-
zone
|
93
|
-
end
|
94
|
-
end # module Footballdata
|
95
|
-
|
96
|
-
|
97
|
-
|