footty 2024.8.28 → 2024.9.27
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/README.md +44 -7
- data/Rakefile +4 -4
- data/lib/footty/dataset.rb +111 -64
- data/lib/footty/version.rb +1 -1
- data/lib/footty.rb +16 -11
- metadata +20 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2254b1fa1cf0832e403b6bc0e6509d1ffee06e0f552fec2b805b124c0a867c0d
|
|
4
|
+
data.tar.gz: 8c8182dabe0e72801b580e46bed8471baacd01080fedac360b2532b63673d9cb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3e7421b9f2bf8ec572a55075970301343604a4dbaaabfeceec10827df9a712184fa9372a72c34e0f79811a4ae47b8a773115916e0e195d46def89a9e509b509d
|
|
7
|
+
data.tar.gz: 4ef82377e9caead4e3ec0048b8eac6120fe77c8de4018e69e74faec2842f33909626234a5bc2ccef137661f999c7825f9ef834c64cab292bcf4e9c357467d645
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
# footty - football.db command line
|
|
1
|
+
# footty - football.db command line tool for national & int'l football club leagues (& cups) from around the world (bonus - incl. world cup, euro and more)
|
|
2
|
+
|
|
2
3
|
|
|
3
4
|
* home :: [github.com/sportdb/footty](https://github.com/sportdb/footty)
|
|
4
5
|
* bugs :: [github.com/sportdb/footty/issues](https://github.com/sportdb/footty/issues)
|
|
@@ -11,15 +12,27 @@
|
|
|
11
12
|
|
|
12
13
|
## Usage - Who's playing today?
|
|
13
14
|
|
|
14
|
-
The footty command line tool lets you query the online football.db HTTP
|
|
15
|
+
The footty command line tool lets you query the online football.db via HTTP
|
|
15
16
|
for upcoming or past matches. For example:
|
|
16
17
|
|
|
17
|
-
$ footty
|
|
18
|
+
$ footty # Defaults to today's English Premier League 2024/25 matches
|
|
19
|
+
|
|
20
|
+
prints on Sep 27, 2024:
|
|
21
|
+
|
|
22
|
+
Upcoming matches:
|
|
23
|
+
Sat Sep/28 12:30 (in 1d) Newcastle United FC vs Manchester City FC Matchday 6
|
|
24
|
+
Sat Sep/28 15:00 (in 1d) Arsenal FC vs Leicester City FC Matchday 6
|
|
25
|
+
Sat Sep/28 15:00 (in 1d) Brentford FC vs West Ham United FC Matchday 6
|
|
26
|
+
Sat Sep/28 15:00 (in 1d) Chelsea FC vs Brighton & Hove Albion Matchday 6
|
|
27
|
+
Sat Sep/28 15:00 (in 1d) Everton FC vs Crystal Palace FC Matchday 6
|
|
28
|
+
Sat Sep/28 15:00 (in 1d) Nottingham Forest FC vs Fulham FC Matchday 6
|
|
29
|
+
Sat Sep/28 17:30 (in 1d) Wolverhampton Wanderers FC vs Liverpool FC Matchday 6
|
|
30
|
+
Sun Sep/29 14:00 (in 2d) Ipswich Town FC vs Aston Villa FC Matchday 6
|
|
31
|
+
Sun Sep/29 16:30 (in 2d) Manchester United FC vs Tottenham Hotspur FC Matchday 6
|
|
32
|
+
Mon Sep/30 20:00 (in 3d) AFC Bournemouth vs Southampton FC Matchday 6
|
|
33
|
+
|
|
18
34
|
|
|
19
|
-
prints on Jun/14 2024:
|
|
20
35
|
|
|
21
|
-
#1 Fri Jun/14 Germany (GER) vs Scotland (SCO) Group A / Matchday 1
|
|
22
|
-
|
|
23
36
|
Use `tomorrow` or `t` or `+1` to print tomorrow's matches e.g.:
|
|
24
37
|
|
|
25
38
|
$ footty tomorrow # -or-
|
|
@@ -41,9 +54,34 @@ Use `past` or `p` to print all past matches e.g.:
|
|
|
41
54
|
$ footty p
|
|
42
55
|
|
|
43
56
|
|
|
57
|
+
|
|
44
58
|
That's it. Enjoy the beautiful game.
|
|
45
59
|
|
|
46
60
|
|
|
61
|
+
## Bonus - More Leagues & Cups - Bundesliga, Serie A, Ligue 1, La Liga & More
|
|
62
|
+
|
|
63
|
+
Pass in the league code to display the Germand Bundesliga, Spanish La Liga, etc:
|
|
64
|
+
|
|
65
|
+
$ footty de # who's playing in the bundesliga today?
|
|
66
|
+
$ footty es # who's playing in la liga today?
|
|
67
|
+
...
|
|
68
|
+
|
|
69
|
+
League codes include:
|
|
70
|
+
|
|
71
|
+
- `de` => Bundesliga
|
|
72
|
+
- `es` => La Liga
|
|
73
|
+
- `it` => Serie A
|
|
74
|
+
- `fr` => Ligue 1
|
|
75
|
+
- ...
|
|
76
|
+
|
|
77
|
+
More
|
|
78
|
+
|
|
79
|
+
- `world` => World Cup
|
|
80
|
+
- `euro` => "Euro" - European Championship
|
|
81
|
+
|
|
82
|
+
See [footty/dataset](https://github.com/sportdb/footty/blob/master/lib/footty/dataset.rb) for the complete built-in list of data sources (and league keys).
|
|
83
|
+
|
|
84
|
+
|
|
47
85
|
|
|
48
86
|
|
|
49
87
|
## Trivia
|
|
@@ -66,7 +104,6 @@ Use it as you please with no restrictions whatsoever.
|
|
|
66
104
|
|
|
67
105
|
|
|
68
106
|
|
|
69
|
-
|
|
70
107
|
## Questions? Comments?
|
|
71
108
|
|
|
72
109
|
Yes, you can. More than welcome.
|
data/Rakefile
CHANGED
|
@@ -2,23 +2,23 @@ require 'hoe'
|
|
|
2
2
|
require './lib/footty/version.rb'
|
|
3
3
|
|
|
4
4
|
Hoe.spec 'footty' do
|
|
5
|
-
|
|
6
5
|
self.version = Footty::VERSION
|
|
7
6
|
|
|
8
|
-
self.summary =
|
|
7
|
+
self.summary = "footty - football.db command line tool for national & int'l football club leagues (& cups) from around the world (bonus - incl. world cup, euro and more)"
|
|
9
8
|
self.description = summary
|
|
10
9
|
|
|
11
10
|
self.urls = { home: 'https://github.com/sportdb/footty' }
|
|
12
11
|
|
|
13
12
|
self.author = 'Gerald Bauer'
|
|
14
|
-
self.email
|
|
13
|
+
self.email = 'gerald.bauer@gmail.com'
|
|
15
14
|
|
|
16
15
|
# switch extension to .markdown for gihub formatting
|
|
17
16
|
self.readme_file = 'README.md'
|
|
18
17
|
self.history_file = 'CHANGELOG.md'
|
|
19
18
|
|
|
20
19
|
self.extra_deps = [
|
|
21
|
-
['sportdb-quick']
|
|
20
|
+
['sportdb-quick', '>= 0.2.0'],
|
|
21
|
+
['webget'],
|
|
22
22
|
]
|
|
23
23
|
|
|
24
24
|
self.licenses = ['Public Domain']
|
data/lib/footty/dataset.rb
CHANGED
|
@@ -1,49 +1,106 @@
|
|
|
1
1
|
module Footty
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
|
|
5
4
|
class Dataset
|
|
5
|
+
SOURCES = {
|
|
6
|
+
'world' => { '2022' => [ 'worldcup/2022--qatar/cup.txt',
|
|
7
|
+
'worldcup/2022--qatar/cup_finals.txt'],
|
|
8
|
+
'2018' => [ 'worldcup/2018--russia/cup.txt',
|
|
9
|
+
'worldcup/2018--russia/cup_finals.txt']
|
|
10
|
+
},
|
|
11
|
+
'euro' => { '2024' => 'euro/2024--germany/euro.txt',
|
|
12
|
+
'2021' => 'euro/2021--europe/euro.txt'
|
|
13
|
+
},
|
|
14
|
+
'de' => 'deutschland/$season$/1-bundesliga.txt',
|
|
15
|
+
'de2' => 'deutschland/$season$/2-bundesliga2.txt',
|
|
16
|
+
'en'=> 'england/$season$/1-premierleague.txt',
|
|
17
|
+
'es'=> 'espana/$season$/1-liga.txt',
|
|
18
|
+
'it'=> 'italy/$season$/1-seriea.txt',
|
|
19
|
+
'at'=> 'austria/$season$/1-bundesliga.txt',
|
|
20
|
+
'at2' => 'austria/$season$/2-liga2.txt',
|
|
21
|
+
'at3o' => 'austria/$season$/3-regionalliga-ost.txt',
|
|
22
|
+
'atcup' => 'austria/$season$/cup.txt',
|
|
23
|
+
|
|
24
|
+
'fr'=> 'europe/france/$season$/1-ligue1.txt',
|
|
25
|
+
'nl'=> 'europe/netherlands/$season$/1-eredivisie.txt',
|
|
26
|
+
'be'=> 'europe/belgium/$season$/1-firstdivisiona.txt',
|
|
27
|
+
|
|
28
|
+
'champs'=> 'champions-league/$season$/cl.txt',
|
|
29
|
+
|
|
30
|
+
'br' => 'south-america/brazil/$year$/1-seriea.txt',
|
|
31
|
+
'ar' => 'south-america/argentina/$year$/1-primeradivision.txt',
|
|
32
|
+
'co' => 'south-america/colombia/$year$/1-primeraa.txt',
|
|
33
|
+
## use a different code for copa libertadores? why? why not?
|
|
34
|
+
'copa' => 'south-america/copa-libertadores/$year$/libertadores.txt',
|
|
35
|
+
|
|
36
|
+
'mx' => 'mexico/$season$/1-ligamx.txt',
|
|
37
|
+
|
|
38
|
+
'eg' => 'africa/egypt/$season$/1-premiership.txt',
|
|
39
|
+
'ma' => 'africa/morocco/$season$/1-botolapro1.txt',
|
|
40
|
+
}
|
|
41
|
+
|
|
6
42
|
|
|
7
|
-
|
|
43
|
+
## return built-in league keys
|
|
44
|
+
def self.leagues() SOURCES.keys; end
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def initialize( league:, year: nil )
|
|
8
48
|
@league = league
|
|
9
|
-
|
|
10
|
-
|
|
49
|
+
|
|
50
|
+
spec = SOURCES[ @league.downcase ]
|
|
51
|
+
urls = if spec.is_a?( Hash ) ## assume lookup by year
|
|
52
|
+
if year.nil? ## lookup default first entry
|
|
53
|
+
year = spec.keys[0].to_i
|
|
54
|
+
spec.values[0]
|
|
55
|
+
else
|
|
56
|
+
spec[ year.to_s ]
|
|
57
|
+
end
|
|
58
|
+
else ## assume vanilla urls (no lookup by year)
|
|
59
|
+
## default to 2024 for now
|
|
60
|
+
year = 2024 if year.nil?
|
|
61
|
+
spec
|
|
62
|
+
end
|
|
63
|
+
raise ArgumentError, "no dataset (source) for league #{league} found" if urls.nil?
|
|
64
|
+
|
|
65
|
+
## wrap single sources (strings) in array
|
|
66
|
+
urls = urls.is_a?( Array ) ? urls : [urls]
|
|
67
|
+
## expand shortened url and fill-in template vars
|
|
68
|
+
@urls = urls.map { |url| openfootball_url( url, year: year ) }
|
|
11
69
|
end
|
|
12
70
|
|
|
13
71
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
72
|
+
def openfootball_url( path, year: )
|
|
73
|
+
repo, local_path = path.split( '/', 2)
|
|
74
|
+
url = "https://raw.githubusercontent.com/openfootball/#{repo}/master/#{local_path}"
|
|
75
|
+
## check for template vars too
|
|
76
|
+
season = Season( "#{year}/#{year+1}" )
|
|
77
|
+
url = url.gsub( '$year$', year.to_s )
|
|
78
|
+
url = url.gsub( '$season$', season.to_path )
|
|
79
|
+
url
|
|
80
|
+
end
|
|
81
|
+
|
|
21
82
|
|
|
22
83
|
### note:
|
|
23
84
|
## cache ALL methods - only do one web request for match schedule & results
|
|
24
85
|
def matches
|
|
25
86
|
@data ||= begin
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
res = get!( url ) ## use "memoized" / cached result
|
|
31
|
-
if url.end_with?( '.json' )
|
|
32
|
-
JSON.parse( res.text )
|
|
33
|
-
else ## assume football.txt format
|
|
34
|
-
matches = SportDb::QuickMatchReader.parse( res.text )
|
|
35
|
-
data = matches.map {|match| match.as_json } # convert to json
|
|
36
|
-
## quick hack to get keys as strings not symbols!!
|
|
37
|
-
## fix upstream
|
|
38
|
-
JSON.parse( JSON.generate( data ))
|
|
87
|
+
matches = []
|
|
88
|
+
@urls.each do |url|
|
|
89
|
+
txt = get!( url ) ## use "memoized" / cached result
|
|
90
|
+
matches += SportDb::QuickMatchReader.parse( txt )
|
|
39
91
|
end
|
|
92
|
+
data = matches.map {|match| match.as_json } # convert to json
|
|
93
|
+
## quick hack to get keys as strings not symbols!!
|
|
94
|
+
## fix upstream
|
|
95
|
+
JSON.parse( JSON.generate( data ))
|
|
40
96
|
end
|
|
41
97
|
end
|
|
42
98
|
|
|
99
|
+
|
|
43
100
|
def end_date
|
|
44
101
|
@end_date ||= begin
|
|
45
102
|
end_date = nil
|
|
46
|
-
each do |match|
|
|
103
|
+
matches.each do |match|
|
|
47
104
|
date = Date.strptime(match['date'], '%Y-%m-%d' )
|
|
48
105
|
end_date = date if end_date.nil? ||
|
|
49
106
|
date > end_date
|
|
@@ -55,7 +112,7 @@ module Footty
|
|
|
55
112
|
def start_date
|
|
56
113
|
@start_date ||= begin
|
|
57
114
|
start_date = nil
|
|
58
|
-
each do |match|
|
|
115
|
+
matches.each do |match|
|
|
59
116
|
date = Date.strptime(match['date'], '%Y-%m-%d' )
|
|
60
117
|
start_date = date if start_date.nil? ||
|
|
61
118
|
date < start_date
|
|
@@ -89,54 +146,44 @@ module Footty
|
|
|
89
146
|
def past_matches( date: Date.today )
|
|
90
147
|
matches = select_matches { |match| date > Date.parse( match['date'] ) }
|
|
91
148
|
## note reveserve matches (chronological order/last first)
|
|
92
|
-
matches.reverse
|
|
149
|
+
## matches.reverse
|
|
150
|
+
matches
|
|
93
151
|
end
|
|
94
152
|
|
|
95
153
|
|
|
96
154
|
private
|
|
97
|
-
def
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
round['matches'].each do |match|
|
|
102
|
-
## hack: add (outer) round to match
|
|
103
|
-
match['round'] = round['name']
|
|
104
|
-
yield( match )
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
else ## assume flat matches in Array
|
|
108
|
-
data.each do |match|
|
|
109
|
-
yield( match )
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
def select_matches
|
|
116
|
-
matches = []
|
|
117
|
-
each do |match|
|
|
118
|
-
matches << match if yield( match )
|
|
155
|
+
def select_matches( &blk)
|
|
156
|
+
selected = []
|
|
157
|
+
matches.each do |match|
|
|
158
|
+
selected << match if blk.call( match )
|
|
119
159
|
end
|
|
120
160
|
|
|
121
161
|
## todo/fix:
|
|
122
162
|
## sort matches here; might not be chronologicial (by default)
|
|
123
|
-
|
|
163
|
+
selected
|
|
124
164
|
end # method select_matches
|
|
125
165
|
|
|
126
166
|
|
|
127
|
-
def get!( url )
|
|
128
|
-
response = Webclient.get( url )
|
|
129
167
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
168
|
+
def get!( url )
|
|
169
|
+
## use cached urls for 12h by default
|
|
170
|
+
## if expired in cache (or not present) than get/fetch
|
|
171
|
+
if Webcache.expired_in_12h?( url )
|
|
172
|
+
response = Webget.text( url )
|
|
173
|
+
|
|
174
|
+
if response.status.ok?
|
|
175
|
+
response.text # note - return text (utf-8)
|
|
176
|
+
else
|
|
177
|
+
## dump headers
|
|
178
|
+
response.headers.each do |key,value|
|
|
179
|
+
puts " #{key}: #{value}"
|
|
180
|
+
end
|
|
181
|
+
puts "!! HTTP ERROR - #{response.status.code} #{response.status.message}"
|
|
182
|
+
exit 1
|
|
183
|
+
end
|
|
184
|
+
else
|
|
185
|
+
Webcache.read( url )
|
|
186
|
+
end
|
|
187
|
+
end # method get_txt!
|
|
188
|
+
end # class Dataset
|
|
142
189
|
end # module Footty
|
data/lib/footty/version.rb
CHANGED
data/lib/footty.rb
CHANGED
|
@@ -1,29 +1,34 @@
|
|
|
1
1
|
require 'sportdb/quick' ## note - pulls in cocos et al
|
|
2
|
-
|
|
2
|
+
require 'webget' ## add webcache support
|
|
3
3
|
|
|
4
4
|
# our own code
|
|
5
5
|
require_relative 'footty/version' # let it always go first
|
|
6
6
|
require_relative 'footty/dataset'
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
module Footty
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
## set cache to local .cache dir for now - why? why not?
|
|
11
|
+
Webcache.root = './cache'
|
|
12
|
+
# pp Webcache.root
|
|
13
|
+
Webget.config.sleep = 1 ## set delay in secs (to 1 sec - default is/maybe 3)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
module Footty
|
|
17
|
+
def self.main( args=ARGV )
|
|
12
18
|
puts banner # say hello
|
|
13
19
|
|
|
14
20
|
league = 'en'
|
|
15
|
-
year =
|
|
21
|
+
year = nil
|
|
22
|
+
|
|
23
|
+
leagues = Dataset.leagues ## e.g. ['world','euro',
|
|
24
|
+
## 'de','en','at']
|
|
16
25
|
|
|
17
|
-
## filter
|
|
18
|
-
args =
|
|
26
|
+
## filter args for league or year
|
|
27
|
+
args = args.select do |arg|
|
|
19
28
|
if arg =~ /^\d{4}$/
|
|
20
29
|
year = arg.to_i(10)
|
|
21
30
|
false ## eat-up
|
|
22
|
-
elsif
|
|
23
|
-
'euro',
|
|
24
|
-
'de',
|
|
25
|
-
'en',
|
|
26
|
-
'at'].include?( arg )
|
|
31
|
+
elsif leagues.include?( arg )
|
|
27
32
|
league = arg
|
|
28
33
|
false
|
|
29
34
|
else
|
metadata
CHANGED
|
@@ -1,17 +1,31 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: footty
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2024.
|
|
4
|
+
version: 2024.9.27
|
|
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-
|
|
11
|
+
date: 2024-09-27 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: sportdb-quick
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 0.2.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.2.0
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: webget
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
16
30
|
requirements:
|
|
17
31
|
- - ">="
|
|
@@ -58,8 +72,8 @@ dependencies:
|
|
|
58
72
|
- - "~>"
|
|
59
73
|
- !ruby/object:Gem::Version
|
|
60
74
|
version: '4.1'
|
|
61
|
-
description: footty - football.db command line
|
|
62
|
-
|
|
75
|
+
description: footty - football.db command line tool for national & int'l football
|
|
76
|
+
club leagues (& cups) from around the world (bonus - incl. world cup, euro and more)
|
|
63
77
|
email: gerald.bauer@gmail.com
|
|
64
78
|
executables:
|
|
65
79
|
- footty
|
|
@@ -103,6 +117,6 @@ requirements: []
|
|
|
103
117
|
rubygems_version: 3.4.10
|
|
104
118
|
signing_key:
|
|
105
119
|
specification_version: 4
|
|
106
|
-
summary: footty - football.db command line
|
|
107
|
-
|
|
120
|
+
summary: footty - football.db command line tool for national & int'l football club
|
|
121
|
+
leagues (& cups) from around the world (bonus - incl. world cup, euro and more)
|
|
108
122
|
test_files: []
|