footballdata-api 0.4.1 → 0.4.3
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 -1
- data/README.md +3 -4
- data/Rakefile +1 -0
- data/bin/fbdat +96 -47
- data/config/leagues_tier1.csv +44 -0
- data/lib/footballdata/convert.rb +105 -33
- data/lib/footballdata/leagues.rb +1 -1
- data/lib/footballdata/prettyprint.rb +6 -1
- data/lib/footballdata/version.rb +1 -1
- data/lib/footballdata.rb +1 -0
- metadata +17 -3
- data/config/leagues.csv +0 -54
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6712b00c0f67e3c23fbdd0cd9f5436e9683dedc75fa53028cc72a07fa36437e2
|
4
|
+
data.tar.gz: 8d9ae9147cba11203f2f9755ad1d0a79b52715dab2d03027bdc340a6e4e50d87
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4a5f064656d889e36b352dcedfc77cd503c6f5f2f9ce8fc25a84ac3ece1ecb8acab941a3f21a647e1278f9f87b8e232e1958acca8138b50a6f073351c677856
|
7
|
+
data.tar.gz: f9bdb77161614d3d381e187aad999f5f0ff67835b920bdd0d31ea553cdab89ab849489f59cb95c98f78088a79cb39a4e9f94d673914048f83b179b6a207dbbc5
|
data/CHANGELOG.md
CHANGED
data/Manifest.txt
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# footballdata-api - get football data via Daniel Freitag's football-data.org api v4
|
1
|
+
# footballdata-api - get football data via Daniel Freitag's football-data.org api v4
|
2
2
|
|
3
3
|
|
4
4
|
* home :: [github.com/sportdb/sport.db](https://github.com/sportdb/sport.db)
|
@@ -48,14 +48,13 @@ Footballdata.schedule( league: 'eng.2', season: '2020/21' )
|
|
48
48
|
|
49
49
|
Footballdata.schedule( league: 'de.1', season: '2020/21' )
|
50
50
|
Footballdata.schedule( league: 'es.1', season: '2020/21' )
|
51
|
-
|
52
51
|
Footballdata.schedule( league: 'fr.1', season: '2020/21' )
|
53
52
|
Footballdata.schedule( league: 'it.1', season: '2020/21' )
|
54
53
|
|
55
54
|
Footballdata.schedule( league: 'nl.1', season: '2020/21' )
|
56
55
|
Footballdata.schedule( league: 'pt.1', season: '2020/21' )
|
57
56
|
|
58
|
-
Footballdata.schedule( league: 'cl',
|
57
|
+
Footballdata.schedule( league: 'uefa.cl', season: '2020/21' )
|
59
58
|
|
60
59
|
# note: Brasileirão - season is a calendar year (NOT an academic year)
|
61
60
|
Footballdata.schedule( league: 'br.1', season: '2020' )
|
@@ -83,7 +82,7 @@ require 'footballdata'
|
|
83
82
|
'it.1',
|
84
83
|
'nl.1',
|
85
84
|
'pt.1',
|
86
|
-
'cl',
|
85
|
+
'uefa.cl',
|
87
86
|
].each do |league|
|
88
87
|
Footballdata.convert( league: league, season: '2020/21' )
|
89
88
|
end
|
data/Rakefile
CHANGED
data/bin/fbdat
CHANGED
@@ -16,14 +16,6 @@ Webcache.root = if File.exist?( '/sports/cache' )
|
|
16
16
|
'./cache'
|
17
17
|
end
|
18
18
|
|
19
|
-
## note - free tier (tier one) plan - 10 requests/minute
|
20
|
-
## (one request every 6 seconds 6*10=60 secs)
|
21
|
-
## 10 API calls per minute max.
|
22
|
-
## note - default sleep (delay in secs) is 3 sec(s)
|
23
|
-
|
24
|
-
## change from 10 to 1 sec(s) for interactive use
|
25
|
-
Webget.config.sleep = 1
|
26
|
-
|
27
19
|
|
28
20
|
Footballdata.config.convert.out_dir = if File.exist?( '/sports/cache.api.fbdat' )
|
29
21
|
puts " setting convert out_dir to >/sports/cache.api.fbdat<"
|
@@ -43,6 +35,7 @@ def self.main( args=ARGV )
|
|
43
35
|
opts = {
|
44
36
|
cached: false,
|
45
37
|
convert: true,
|
38
|
+
file: nil,
|
46
39
|
}
|
47
40
|
|
48
41
|
parser = OptionParser.new do |parser|
|
@@ -53,9 +46,20 @@ parser = OptionParser.new do |parser|
|
|
53
46
|
opts[:cached] = cached
|
54
47
|
end
|
55
48
|
|
56
|
-
parser.on( "--no-convert",
|
57
|
-
"turn off conversion to .csv in #{Footballdata.config.convert.out_dir} - default is (#{
|
58
|
-
opts[:convert] =
|
49
|
+
parser.on( "--[no-]convert",
|
50
|
+
"turn on/off conversion to .csv in #{Footballdata.config.convert.out_dir} - default is (#{opts[:convert]})" ) do |convert|
|
51
|
+
opts[:convert] = convert
|
52
|
+
end
|
53
|
+
|
54
|
+
parser.on( "--print", "--pp",
|
55
|
+
"pretty print cached data in #{Webcache.root}; no download & conversion") do |print|
|
56
|
+
opts[:cached] = true
|
57
|
+
opts[:convert] = false
|
58
|
+
end
|
59
|
+
|
60
|
+
parser.on( "-f FILE", "--file FILE",
|
61
|
+
"read leagues (and seasons) via .csv file") do |file|
|
62
|
+
opts[:file] = file
|
59
63
|
end
|
60
64
|
end
|
61
65
|
parser.parse!( args )
|
@@ -68,6 +72,19 @@ puts "ARGV:"
|
|
68
72
|
p args
|
69
73
|
|
70
74
|
|
75
|
+
## note - free tier (tier one) plan - 10 requests/minute
|
76
|
+
## (one request every 6 seconds 6*10=60 secs)
|
77
|
+
## 10 API calls per minute max.
|
78
|
+
## note - default sleep (delay in secs) is 3 sec(s)
|
79
|
+
|
80
|
+
## change from 10 to 1 sec(s) for interactive use
|
81
|
+
## assume --file/-f as non-interactive/batch use for now
|
82
|
+
Webget.config.sleep = opts[:file] ? 10 : 1
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
|
71
88
|
## try special args
|
72
89
|
|
73
90
|
if ['plan', 'plans',
|
@@ -118,11 +135,13 @@ end
|
|
118
135
|
##
|
119
136
|
## todo - add more date offsets - t+2,t+3,t+4, etc.
|
120
137
|
|
138
|
+
|
139
|
+
|
121
140
|
date = if ['y', 'yesterday', 't-1', '-1'].include?( args[0] )
|
122
141
|
Date.today-1
|
123
142
|
elsif ['t', 'tomorrow', 't+1', '1', '+1'].include?( args[0] )
|
124
143
|
Date.today+1
|
125
|
-
elsif ['m', 'match', 'matches', 'today'].include?( args[0]
|
144
|
+
elsif ['m', 'match', 'matches', 'today'].include?( args[0] )
|
126
145
|
Date.today
|
127
146
|
else
|
128
147
|
nil
|
@@ -170,51 +189,81 @@ end
|
|
170
189
|
##
|
171
190
|
## note - only use "generic" uniform league codes for now!!
|
172
191
|
|
173
|
-
league_code = (args[0] || 'eng.1').downcase
|
174
|
-
|
175
|
-
## todo - find a better name
|
176
|
-
## use internal_league_code or such - why? why not?
|
177
|
-
### convenience helpers - lets you use eng.1, euro, etc.
|
178
|
-
## check if mapping for league_code
|
179
|
-
metal_league_code = find_league!( league_code )
|
180
192
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
193
|
+
datasets = if opts[:file]
|
194
|
+
read_datasets( opts[:file] )
|
195
|
+
else
|
196
|
+
parse_datasets_args( args )
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
## step 0 - validate and fill-up seasons etc.
|
201
|
+
datasets.each do |dataset|
|
202
|
+
league_key, seasons = dataset
|
203
|
+
|
204
|
+
## todo - find a better name
|
205
|
+
## use internal_league_code or such - why? why not?
|
206
|
+
### convenience helpers - lets you use eng.1, euro, etc.
|
207
|
+
## check if mapping for league_code
|
208
|
+
metal_league_code = find_league!( league_key )
|
209
|
+
|
210
|
+
## note - default to latest season of league
|
211
|
+
## might be 2024/25 or 2024 or
|
212
|
+
# for world cup 2022 or such
|
213
|
+
if seasons.empty?
|
214
|
+
seasons = case league_key
|
215
|
+
when 'world' then [Season('2022')]
|
216
|
+
when 'euro' then [Season('2024')]
|
217
|
+
when 'br.1', 'copa.l' then [Season('2024')]
|
218
|
+
else [Season('2024/25')]
|
219
|
+
end
|
220
|
+
dataset[1] = seasons
|
221
|
+
end
|
199
222
|
end
|
200
223
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
224
|
+
## step 1 - download
|
225
|
+
datasets.each do |league_key, seasons|
|
226
|
+
## todo - find a better name
|
227
|
+
## use internal_league_code or such - why? why not?
|
228
|
+
### convenience helpers - lets you use eng.1, euro, etc.
|
229
|
+
## check if mapping for league_code
|
230
|
+
metal_league_code = find_league!( league_key )
|
231
|
+
seasons.each do |season|
|
232
|
+
season_start_year = season.start_year ## use year - why? why not?
|
233
|
+
pp [metal_league_code, season_start_year]
|
234
|
+
|
235
|
+
if opts[:cached]
|
236
|
+
## do nothing
|
237
|
+
else
|
238
|
+
## download dataset(s)
|
239
|
+
## try download
|
240
|
+
## note: include teams (for convert) for now too!!
|
241
|
+
Metal.teams( metal_league_code, season_start_year )
|
242
|
+
Metal.matches( metal_league_code, season_start_year )
|
243
|
+
end
|
244
|
+
|
245
|
+
url = Metal.competition_matches_url( metal_league_code,
|
246
|
+
season_start_year )
|
247
|
+
pp url
|
248
|
+
#=> "http://api.football-data.org/v4/competitions/EC/matches?season=2024"
|
205
249
|
|
206
|
-
data = Webcache.read_json( url )
|
207
|
-
## pp data
|
250
|
+
data = Webcache.read_json( url )
|
251
|
+
## pp data
|
208
252
|
|
209
|
-
pp_matches( data )
|
253
|
+
pp_matches( data )
|
254
|
+
end # each season
|
255
|
+
end # each dataset
|
210
256
|
|
211
257
|
|
212
258
|
if opts[:convert]
|
213
|
-
|
214
|
-
|
259
|
+
puts "==> converting to .csv"
|
260
|
+
datasets.each do |league_key, seasons|
|
261
|
+
seasons.each do |season|
|
262
|
+
convert( league: league_key, season: season )
|
263
|
+
end
|
264
|
+
end
|
215
265
|
end
|
216
266
|
|
217
|
-
|
218
267
|
end # def self.main
|
219
268
|
end # module Footballdata
|
220
269
|
|
@@ -0,0 +1,44 @@
|
|
1
|
+
key, code, seasons
|
2
|
+
|
3
|
+
eng.1, PL, 2024/25 2023/24 2022/23 2021/22 2020/21
|
4
|
+
# incl. team(s) from wales
|
5
|
+
eng.2, ELC, 2024/25 2023/24 2022/23 2021/22 2020/21
|
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
|
+
es.1, PD, 2024/25 2023/24 2022/23 2021/22 2020/21
|
10
|
+
# PD - Primera Division, Spain 27 seasons | 2019-08-16 - 2020-07-19 / matchday 31
|
11
|
+
|
12
|
+
pt.1, PPL, 2024/25 2023/24 2022/23 2021/22 2020/21
|
13
|
+
# PPL - Primeira Liga, Portugal 9 seasons | 2019-08-10 - 2020-07-26 / matchday 28
|
14
|
+
|
15
|
+
de.1, BL1, 2024/25 2023/24 2022/23 2021/22 2020/21
|
16
|
+
# BL1 - Bundesliga, Germany 24 seasons | 2019-08-16 - 2020-06-27 / matchday 34
|
17
|
+
|
18
|
+
nl.1, DED, 2024/25 2023/24 2022/23 2021/22 2020/21
|
19
|
+
# DED - Eredivisie, Netherlands 10 seasons | 2019-08-09 - 2020-03-08 / matchday 34
|
20
|
+
|
21
|
+
fr.1, FL1, 2024/25 2023/24 2022/23 2021/22 2020/21
|
22
|
+
# incl. team(s) monaco
|
23
|
+
|
24
|
+
it.1, SA, 2024/25 2023/24 2022/23 2021/22 2020/21
|
25
|
+
# SA - Serie A, Italy 15 seasons | 2019-08-24 - 2020-08-02 / matchday 27
|
26
|
+
|
27
|
+
br.1, BSA, 2024 2023 2022 2021 2020
|
28
|
+
|
29
|
+
|
30
|
+
########
|
31
|
+
## int'l cups
|
32
|
+
uefa.cl, CL, 2024/25 2023/24 2022/23 2021/22 2020/21
|
33
|
+
## note: cl is country code for chile!! - use champs - why? why not?
|
34
|
+
## was europe.cl / cl
|
35
|
+
## todo/check: use champs and NOT cl - why? why not?
|
36
|
+
|
37
|
+
copa.l, CLI, 2024 2023 2022 2021
|
38
|
+
## Copa Libertadores
|
39
|
+
|
40
|
+
|
41
|
+
############
|
42
|
+
## national teams
|
43
|
+
euro, EC, 2024 2021
|
44
|
+
world, WC, 2022
|
data/lib/footballdata/convert.rb
CHANGED
@@ -3,18 +3,21 @@ module Footballdata
|
|
3
3
|
|
4
4
|
#######
|
5
5
|
## map round-like to higher-level stages
|
6
|
+
## fix - map by league codes
|
7
|
+
## or * (all)
|
6
8
|
STAGES = {
|
7
9
|
'REGULAR_SEASON' => ['Regular'],
|
8
10
|
|
11
|
+
'QUALIFICATION' => ['Qualifying'],
|
9
12
|
'PRELIMINARY_ROUND' => ['Qualifying', 'Preliminary Round' ],
|
10
13
|
'PRELIMINARY_SEMI_FINALS' => ['Qualifying', 'Preliminary Semifinals' ],
|
11
14
|
'PRELIMINARY_FINAL' => ['Qualifying', 'Preliminary Final' ],
|
12
|
-
'1ST_QUALIFYING_ROUND' => ['Qualifying', '
|
13
|
-
'2ND_QUALIFYING_ROUND' => ['Qualifying', '
|
14
|
-
'3RD_QUALIFYING_ROUND' => ['Qualifying', '
|
15
|
-
'QUALIFICATION_ROUND_1' => ['Qualifying', '
|
16
|
-
'QUALIFICATION_ROUND_2' => ['Qualifying', '
|
17
|
-
'QUALIFICATION_ROUND_3' => ['Qualifying', '
|
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' ],
|
18
21
|
'ROUND_1' => ['Qualifying', 'Round 1'], ## use Qual. Round 1 - why? why not?
|
19
22
|
'ROUND_2' => ['Qualifying', 'Round 2'],
|
20
23
|
'ROUND_3' => ['Qualifying', 'Round 3'],
|
@@ -29,11 +32,37 @@ STAGES = {
|
|
29
32
|
'LAST_16' => ['Finals', 'Round of 16'], ## use Last 16 - why? why not?
|
30
33
|
'QUARTER_FINALS' => ['Finals', 'Quarterfinals'],
|
31
34
|
'SEMI_FINALS' => ['Finals', 'Semifinals'],
|
35
|
+
'THIRD_PLACE' => ['Finals', 'Third place play-off'],
|
32
36
|
'FINAL' => ['Finals', 'Final'],
|
33
37
|
}
|
34
38
|
|
35
39
|
|
36
40
|
|
41
|
+
def self.team_autofill( name, teams: )
|
42
|
+
## note - no country for place holder teams
|
43
|
+
return name if name == 'N.N.'
|
44
|
+
|
45
|
+
## add (fifa) country code e.g.
|
46
|
+
## Liverpool FC => Liverpool FC (ENG)
|
47
|
+
## or Liverpool FC => Liverpool FC (URU)
|
48
|
+
rec = teams[ name ]
|
49
|
+
if rec.nil?
|
50
|
+
puts "!! ERROR - no team record found in teams.json for #{name}"
|
51
|
+
pp teams.keys
|
52
|
+
exit 1
|
53
|
+
end
|
54
|
+
|
55
|
+
country_name = rec['area']['name']
|
56
|
+
country = Fifa.world.find_by_name( country_name )
|
57
|
+
if country.nil?
|
58
|
+
puts "!! ERROR - no country record found for #{country_name}"
|
59
|
+
exit 1
|
60
|
+
end
|
61
|
+
|
62
|
+
"#{name} (#{country.code})"
|
63
|
+
end
|
64
|
+
|
65
|
+
|
37
66
|
|
38
67
|
def self.convert( league:, season: )
|
39
68
|
|
@@ -48,6 +77,14 @@ def self.convert( league:, season: )
|
|
48
77
|
data_teams = Webcache.read_json( teams_url )
|
49
78
|
|
50
79
|
|
80
|
+
## note - for internation club tournaments
|
81
|
+
## auto-add (fifa) country code e.g.
|
82
|
+
## Liverpool FC => Liverpool FC (ENG)
|
83
|
+
##
|
84
|
+
## todo/fix - move flag to league_info via .csv config - why? why not?
|
85
|
+
clubs_intl = ['uefa.cl',
|
86
|
+
'copa.l'].include?(league.downcase) ? true : false
|
87
|
+
|
51
88
|
|
52
89
|
## check for time zone
|
53
90
|
tz = find_zone!( league: league,
|
@@ -92,15 +129,50 @@ matches.each do |m|
|
|
92
129
|
team1 = m['homeTeam']['name'] || 'N.N.'
|
93
130
|
team2 = m['awayTeam']['name'] || 'N.N.'
|
94
131
|
|
132
|
+
## auto-fix copa.l 2024
|
133
|
+
## !! ERROR: unsupported match status >IN_PLAY< - sorry:
|
134
|
+
if m['status'] == 'IN_PLAY' &&
|
135
|
+
team1 == 'Club Aurora' && team2 == 'FBC Melgar'
|
136
|
+
m['status'] = 'FINISHED'
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
|
95
141
|
score = m['score']
|
96
142
|
|
143
|
+
group = m['group']
|
144
|
+
## GROUP_A
|
145
|
+
## shorten group to A|B|C etc.
|
146
|
+
if group && group =~ /^(GROUP_|Group )/
|
147
|
+
group = group.sub( /^(GROUP_|Group )/, '' )
|
148
|
+
else
|
149
|
+
if group.nil?
|
150
|
+
group = ''
|
151
|
+
else
|
152
|
+
puts "!! WARN - group defined with NON GROUP!? >#{group}< reset to empty"
|
153
|
+
puts " and matchday to >#{m['matchday']}<"
|
154
|
+
## reset group to empty
|
155
|
+
group = ''
|
156
|
+
end
|
157
|
+
end
|
97
158
|
|
98
|
-
stage_key = m['stage']
|
99
159
|
|
160
|
+
stage_key = m['stage']
|
100
161
|
stats['stage'][ stage_key ] += 1 ## track stage counts
|
101
162
|
|
102
|
-
|
103
|
-
stage, stage_round
|
163
|
+
|
164
|
+
stage, stage_round = if group.empty?
|
165
|
+
## map stage to stage + round
|
166
|
+
STAGES[ stage_key ]
|
167
|
+
else
|
168
|
+
## if group defined ignore stage
|
169
|
+
## hard-core always to group for now
|
170
|
+
if stage_key != 'GROUP_STAGE'
|
171
|
+
puts "!! WARN - group defined BUT stage set to >#{stage_key}<"
|
172
|
+
puts " and matchday to >#{m['matchday']}<"
|
173
|
+
end
|
174
|
+
['Group', nil]
|
175
|
+
end
|
104
176
|
|
105
177
|
if stage.nil?
|
106
178
|
puts "!! ERROR - no stage mapping found for stage >#{stage_key}<"
|
@@ -115,25 +187,22 @@ matches.each do |m|
|
|
115
187
|
## matchday 1, 2 etc.
|
116
188
|
matchday = matchday_num.to_s
|
117
189
|
else
|
118
|
-
## note - if matchday defined
|
119
|
-
##
|
120
|
-
matchday =
|
121
|
-
matchday << stage_round
|
122
|
-
matchday << " | Leg #{matchday_num}" if matchday_num &&
|
123
|
-
(matchday_num == 1 || matchday_num == 2)
|
190
|
+
## note - if matchday/round defined, use it
|
191
|
+
## note - ignore possible leg in matchday for now
|
192
|
+
matchday = stage_round
|
124
193
|
end
|
125
194
|
|
126
195
|
|
196
|
+
teams[ team1 ] += 1
|
197
|
+
teams[ team2 ] += 1
|
127
198
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
199
|
+
####
|
200
|
+
# auto-add (fifa) country code if int'l club tournament
|
201
|
+
if clubs_intl
|
202
|
+
team1 = team_autofill( team1, teams: teams_by_name )
|
203
|
+
team2 = team_autofill( team2, teams: teams_by_name )
|
204
|
+
end
|
134
205
|
|
135
|
-
teams[ team1 ] += 1
|
136
|
-
teams[ team2 ] += 1
|
137
206
|
|
138
207
|
### mods - rename club names
|
139
208
|
unless mods.nil? || mods.empty?
|
@@ -142,13 +211,6 @@ matches.each do |m|
|
|
142
211
|
end
|
143
212
|
|
144
213
|
|
145
|
-
## auto-fix copa.l 2024
|
146
|
-
## !! ERROR: unsupported match status >IN_PLAY< - sorry:
|
147
|
-
if m['status'] == 'IN_PLAY' &&
|
148
|
-
team1 == 'Club Aurora' && team2 == 'FBC Melgar'
|
149
|
-
m['status'] = 'FINISHED'
|
150
|
-
end
|
151
|
-
|
152
214
|
|
153
215
|
comments = ''
|
154
216
|
ft = ''
|
@@ -159,12 +221,12 @@ matches.each do |m|
|
|
159
221
|
stats['status'][m['status']] += 1 ## track status counts
|
160
222
|
|
161
223
|
case m['status']
|
162
|
-
when 'SCHEDULED', 'TIMED' ## , 'IN_PLAY'
|
224
|
+
when 'SCHEDULED', 'TIMED' ## , 'IN_PLAY', 'PAUSED'
|
163
225
|
ft = ''
|
164
226
|
ht = ''
|
165
227
|
when 'FINISHED'
|
166
228
|
ft, ht, et, pen = convert_score( score )
|
167
|
-
when 'AWARDED'
|
229
|
+
when 'AWARDED' # AWARDED
|
168
230
|
assert( score['duration'] == 'REGULAR', 'score.duration REGULAR expected' )
|
169
231
|
ft = "#{score['fullTime']['home']}-#{score['fullTime']['away']}"
|
170
232
|
ft << ' (*)'
|
@@ -206,7 +268,17 @@ matches.each do |m|
|
|
206
268
|
local = tz.to_local( utc )
|
207
269
|
date = local.strftime( '%Y-%m-%d' )
|
208
270
|
time = local.strftime( '%H:%M' )
|
209
|
-
|
271
|
+
|
272
|
+
## pretty print timezone
|
273
|
+
### todo/fix - bundle into fmt_timezone method or such for reuse
|
274
|
+
tz_abbr = local.strftime( '%Z' ) ## e.g. EEST or if not available +03 or such
|
275
|
+
tz_offset = local.strftime( '%z' ) ## e.g. +0300
|
276
|
+
|
277
|
+
timezone = if tz_abbr =~ /^[+-][0-9]+$/ ## only digits (no abbrev.)
|
278
|
+
tz_offset
|
279
|
+
else
|
280
|
+
"#{tz_abbr}/#{tz_offset}"
|
281
|
+
end
|
210
282
|
end
|
211
283
|
|
212
284
|
|
data/lib/footballdata/leagues.rb
CHANGED
@@ -2,7 +2,7 @@ module Footballdata
|
|
2
2
|
|
3
3
|
def self.find_league!( league )
|
4
4
|
@leagues ||= begin
|
5
|
-
recs = read_csv( "#{FootballdataApi.root}/config/
|
5
|
+
recs = read_csv( "#{FootballdataApi.root}/config/leagues_tier1.csv" )
|
6
6
|
leagues = {}
|
7
7
|
recs.each do |rec|
|
8
8
|
leagues[ rec['key'] ] = rec['code']
|
@@ -39,6 +39,7 @@ def self.fmt_match( rec )
|
|
39
39
|
TIMED
|
40
40
|
FINISHED
|
41
41
|
POSTPONED
|
42
|
+
AWARDED
|
42
43
|
IN_PLAY
|
43
44
|
].include?( status ), "unknown status - #{status}" )
|
44
45
|
|
@@ -89,7 +90,11 @@ def self.fmt_match( rec )
|
|
89
90
|
score << "#{et} a.e.t. "
|
90
91
|
score << "(#{ft}, #{ht})"
|
91
92
|
else
|
92
|
-
|
93
|
+
if !ht.empty?
|
94
|
+
score << "#{ft} (#{ht})"
|
95
|
+
else
|
96
|
+
score << "#{ft}"
|
97
|
+
end
|
93
98
|
end
|
94
99
|
|
95
100
|
buf << score
|
data/lib/footballdata/version.rb
CHANGED
data/lib/footballdata.rb
CHANGED
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: 0.4.
|
4
|
+
version: 0.4.3
|
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-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: football-timezones
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: fifa
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: webget
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -88,7 +102,7 @@ files:
|
|
88
102
|
- README.md
|
89
103
|
- Rakefile
|
90
104
|
- bin/fbdat
|
91
|
-
- config/
|
105
|
+
- config/leagues_tier1.csv
|
92
106
|
- lib/footballdata.rb
|
93
107
|
- lib/footballdata/convert-score.rb
|
94
108
|
- lib/footballdata/convert.rb
|
data/config/leagues.csv
DELETED
@@ -1,54 +0,0 @@
|
|
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
|