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