worldfootball 0.1.1 → 0.2.0

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: 170277c7714f9b75e93176eb5fff6242fb6efb85051bc8977f7f635dbebf0513
4
- data.tar.gz: 5b15d132765c3ee2df4cbdd847b43ba6c7e7bd617ed55bb5fe4dfabc0becb0e0
3
+ metadata.gz: 78c749dd421814981a58c87104761091471a4ffe26a8261df132d77bca5ffb8f
4
+ data.tar.gz: 23a146156f4e38f0e92ef9689ed6a965b044e6ae2e489cffb5da56883c7e6e7a
5
5
  SHA512:
6
- metadata.gz: c95b4b2becf545be2c208a207e8980d06369148d18b0657cddfb81470331c828ee8492649908ece372fb996b9d1a6dfc8eeaa45c54a3757eba7fb6d02e363bf0
7
- data.tar.gz: ca127cb3f69c861dba48b049ed6da30b9ecde1f3935b30422d6184869b650b5cafc056be7fa37c7198bbd72ad65bdd262e56c82631c62629f4bbb4222992a9c9
6
+ metadata.gz: 64e28d3ffdb1056f9db34459ca7d23ba2116a9aeb8130d3b81a310590fc0ad5079eff635664d153a2798b5e9765a10e7508311d0c899b82c1c59f98bedecc60c
7
+ data.tar.gz: 52ef6922b2b1e735a67b9aae8ecd409c3314aa3d2a48b056d2be2d272b85c4e48735e983dda88630c461a25354a5f6f9cb64eb0cb4d6f642cf873263da3af954
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ### 0.1.1
1
+ ### 0.2.0
2
2
 
3
3
  ### 0.0.1 / 2024-07-04
4
4
 
data/Manifest.txt CHANGED
@@ -3,24 +3,17 @@ Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
5
  bin/wfb
6
+ config/leagues_asia.csv
7
+ config/leagues_europe.csv
6
8
  lib/worldfootball.rb
9
+ lib/worldfootball/build-parse_score.rb
7
10
  lib/worldfootball/build.rb
11
+ lib/worldfootball/cache.rb
12
+ lib/worldfootball/config.rb
8
13
  lib/worldfootball/convert.rb
9
14
  lib/worldfootball/convert_reports.rb
10
15
  lib/worldfootball/download.rb
11
- lib/worldfootball/generator.rb
12
16
  lib/worldfootball/leagues.rb
13
- lib/worldfootball/leagues/asia.rb
14
- lib/worldfootball/leagues/europe--british_isles.rb
15
- lib/worldfootball/leagues/europe--central.rb
16
- lib/worldfootball/leagues/europe--eastern.rb
17
- lib/worldfootball/leagues/europe--northern.rb
18
- lib/worldfootball/leagues/europe--southern.rb
19
- lib/worldfootball/leagues/europe--western.rb
20
- lib/worldfootball/leagues/europe.rb
21
- lib/worldfootball/leagues/north_america.rb
22
- lib/worldfootball/leagues/pacific.rb
23
- lib/worldfootball/leagues/south_america.rb
24
17
  lib/worldfootball/mods.rb
25
18
  lib/worldfootball/page.rb
26
19
  lib/worldfootball/page_report.rb
data/README.md CHANGED
@@ -11,7 +11,42 @@
11
11
  ## Usage
12
12
 
13
13
 
14
- To be done
14
+ To get started use the `wfb` command-line tool.
15
+
16
+ List all (pre-configured) leagues:
17
+
18
+ ```
19
+ $ wfb leagues
20
+ ```
21
+
22
+ Print the match schedue of a league (season). Let's try the English Premier League:
23
+
24
+ ```
25
+ $ wfb eng.1 2024/25
26
+ $ wfb eng.1 2024/25 --offline # use cached (offline local) pages
27
+ ```
28
+
29
+ Or try the DFB Pokal (that is, the German Cup):
30
+
31
+ ```
32
+ $ wfb de.cup 2024/25 --offline # use cached (offline local) pages
33
+ ```
34
+
35
+ and so on.
36
+
37
+
38
+
39
+
40
+
41
+
42
+ ### More
43
+
44
+ Debugging tips. List all cached (offline local) match schedule pages:
45
+
46
+ ```
47
+ $ wfb cache
48
+ ```
49
+
15
50
 
16
51
 
17
52
 
data/Rakefile CHANGED
@@ -18,17 +18,15 @@ Hoe.spec 'worldfootball' do
18
18
  self.history_file = 'CHANGELOG.md'
19
19
 
20
20
  self.extra_deps = [
21
- ## ['tzinfo'],
22
- ['season-formats'],
23
- ['webget'],
21
+ ['football-timezones'],
22
+ ['webget'],
24
23
  ['nokogiri'],
25
- ['cocos'], ## later pull in with sportsdb-writers
26
24
  ]
27
25
 
28
26
  self.licenses = ['Public Domain']
29
27
 
30
28
  self.spec_extras = {
31
- required_ruby_version: '>= 2.2.2'
29
+ required_ruby_version: '>= 3.1.0'
32
30
  }
33
31
 
34
32
  end
data/bin/wfb CHANGED
@@ -9,18 +9,30 @@ require 'worldfootball'
9
9
  Webcache.root = if File.exist?( '/sports/cache' )
10
10
  puts " setting web cache to >/sports/cache<"
11
11
  '/sports/cache'
12
- else
12
+ else
13
13
  './cache'
14
14
  end
15
15
 
16
+ ## convert (default) output directory
17
+ Worldfootball.config.convert.out_dir = if File.exist?( '/sports/cache.wfb')
18
+ puts " setting convert out_dir to >/sports/cache.wfb<"
19
+ '/sports/cache.wfb'
20
+ else
21
+ '.' ## use working dir
22
+ end
16
23
 
17
24
  require 'optparse'
18
25
 
19
26
 
20
27
  module Worldfootball
21
- def self.main( args=ARGV )
28
+ def self.main( args=ARGV )
29
+
30
+ opts = {
31
+ cached: false,
32
+ convert: true,
33
+ }
34
+
22
35
 
23
- opts = {}
24
36
  parser = OptionParser.new do |parser|
25
37
  parser.banner = "Usage: #{$PROGRAM_NAME} [options]"
26
38
 
@@ -28,12 +40,27 @@ parser = OptionParser.new do |parser|
28
40
  ## check if git has a offline option?? (use same)
29
41
  ## check for other tools - why? why not?
30
42
 
43
+ ## todo - add a single letter option for offline/cached
31
44
 
32
45
  parser.on( "--cache", "--cached", "--offline",
33
- "use cached data in #{Webcache.root}" ) do |cached|
46
+ "use cached data in >#{Webcache.root}<" ) do |cached|
34
47
  opts[:cached] = cached
35
48
  end
49
+
50
+ parser.on( "--no-convert",
51
+ "turn off conversion to .csv in #{Worldfootball.config.convert.out_dir} - default is (#{!opts[:convert]})" ) do |convert|
52
+ opts[:convert] = !convert
53
+ end
54
+
55
+ parser.on( "--dry",
56
+ "dry run / show league page meta info" ) do |dry|
57
+ opts[:dry] = dry
58
+ end
36
59
  end
60
+
61
+
62
+
63
+
37
64
  parser.parse!( args )
38
65
 
39
66
  puts "OPTS:"
@@ -42,12 +69,19 @@ puts "ARGV:"
42
69
  p args
43
70
 
44
71
 
72
+ ### check special (built-in) commands first
73
+ if ['cache'].include?( args[0] )
74
+ Worldfootball.list_pages
75
+ exit 0
76
+ end
77
+
78
+
45
79
  if ['league', 'leagues', 'ls'].include?( args[0] || 'leagues' )
46
80
  keys = LEAGUES.keys
47
-
81
+
48
82
  pp keys
49
83
  puts " #{keys.size} league(s)"
50
-
84
+
51
85
  # puts
52
86
  # puts " pages:"
53
87
  # pp Worldfootball::PAGES
@@ -59,33 +93,46 @@ end
59
93
 
60
94
  league_code = args[0].downcase
61
95
 
62
- league = find_league( league_code ) ## league info lookup
63
-
64
- season = Season( args[1] || '2024/25' )
96
+ league = find_league!( league_code ) ## league info lookup
97
+
98
+ if opts[:dry]
99
+ ## output more page meta info
100
+ puts "league meta:"
101
+ pp league
102
+ end
103
+
104
+
105
+ ## note - default to latest season of league
106
+ ## might be 2024/25 or 2024 or
107
+ # for world cup 2022 or such
108
+ season = Season( args[1] || league.seasons.keys[0] )
109
+
110
+ pages = league.pages!( season: season )
65
111
 
66
- pages = league.pages( season: season )
67
112
 
113
+ puts
114
+ pp [league.key, season.key]
68
115
  pp pages
69
116
  puts " #{pages.size} page(s)"
70
117
 
71
118
 
72
- ## wrap single page record into array
73
- pages = pages.is_a?( Array ) ? pages : [pages]
119
+ if opts[:dry]
120
+ ## stop here if dry run
121
+ exit 0
122
+ end
74
123
 
75
- if opts[:cached]
124
+
125
+ if opts[:cached]
76
126
  # do nothing
77
127
  else ## download to cache
78
- pages.each_with_index do |page_rec,i|
79
- slug = page_rec[:slug]
80
- puts "==> #{i+1}/#{pages.size} - #{league_code} @ #{slug}..."
81
- page = Metal.download_schedule( slug )
82
- end
128
+ pages.each_with_index do |(slug,_),i|
129
+ puts "==> #{i+1}/#{pages.size} - #{league_code} @ #{slug}..."
130
+ page = Metal.download_schedule( slug )
131
+ end
83
132
  end
84
133
 
85
134
 
86
- pages.each_with_index do |page_rec,i|
87
- slug = page_rec[:slug]
88
-
135
+ pages.each_with_index do |(slug,_),i|
89
136
  puts "==> #{i+1}/#{pages.size} - #{league_code} @ #{slug}..."
90
137
  page = Page::Schedule.from_cache( slug )
91
138
  matches = page.matches
@@ -94,11 +141,16 @@ pages.each_with_index do |page_rec,i|
94
141
  end
95
142
 
96
143
 
144
+ if opts[:convert]
145
+ ## write out (export to) comma-separated values (.csv) datafile
146
+ convert( league: league_code,
147
+ season: season )
148
+ end
97
149
  end # def self.main
98
150
  end # module Worldfootball
99
-
151
+
100
152
 
101
153
  Worldfootball.main( ARGV )
102
154
 
103
-
155
+
104
156
  puts "bye"
@@ -0,0 +1,6 @@
1
+ key, slug
2
+
3
+ cn.1, chn-super-league-2024
4
+ jp.1, jpn-j1-league-2024
5
+ kr.1, kor-k-league-1-2024
6
+
@@ -0,0 +1,75 @@
1
+ key, slug
2
+
3
+ de.1, bundesliga-2024-2025
4
+ de.2, 2-bundesliga-2024-2025
5
+ de.3, 3-liga-2024-2025
6
+ de.4.bayern, regionalliga-bayern-2024-2025
7
+ de.cup, dfb-pokal-2024-2025
8
+
9
+ at.1, aut-bundesliga-2024-2025
10
+ at.2, aut-2-liga-2024-2025
11
+ at.3.o, aut-regionalliga-ost-2024-2025
12
+ at.cup, aut-oefb-cup-2024-2025
13
+
14
+
15
+ ch.1, sui-super-league-2024-2025
16
+ ch.2, sui-challenge-league-2024-2025
17
+ ch.cup, sui-cup-2024-2025
18
+
19
+
20
+ hu.1, hun-nb-i-2024-2025
21
+
22
+ cz.1, cze-1-fotbalova-liga-2024-2025
23
+ sk.1, svk-super-liga-2024-2025
24
+
25
+ pl.1, pol-ekstraklasa-2024-2025
26
+
27
+
28
+
29
+ eng.1, eng-premier-league-2024-2025
30
+ eng.2, eng-championship-2024-2025
31
+ eng.3, eng-league-one-2024-2025
32
+ eng.4, eng-league-two-2024-2025
33
+ eng.5, eng-national-league-2024-2025
34
+ eng.cup, eng-fa-cup-2023-2024 ### update to 2024-2025 later!!!
35
+ eng.cup.l, eng-league-cup-2024-2025
36
+
37
+
38
+ sco.1, sco-premiership-2024-2025
39
+
40
+ ie.1, irl-premier-division-2024
41
+
42
+
43
+ fr.1, fra-ligue-1-2024-2025
44
+ fr.2, fra-ligue-2-2024-2025
45
+ fr.cup, fra-coupe-de-france-2023-2024 ### update to 2024-2025 later!!!
46
+
47
+
48
+ lu.1, lux-nationaldivision-2024-2025
49
+ nl.1, ned-eredivisie-2024-2025
50
+ nl.2, ned-eerste-divisie-2024-2025
51
+ nl.cup, ned-knvb-beker-2024-2025
52
+
53
+ be.1, bel-eerste-klasse-a-2024-2025
54
+ be.2, bel-eerste-klasse-b-2024-2025
55
+ be.cup, bel-beker-van-belgie-2024-2025
56
+
57
+
58
+ it.1, ita-serie-a-2024-2025
59
+ it.2, ita-serie-b-2024-2025
60
+ it.cup, ita-coppa-italia-2024-2025
61
+
62
+ pt.1, por-primeira-liga-2024-2025
63
+ pt.2, por-segunda-liga-2024-2025
64
+
65
+ es.1, esp-primera-division-2024-2025
66
+ es.2, esp-segunda-division-2024-2025
67
+ es.cup, esp-copa-del-rey-2023-2024 ## update to 2024-2025 later!!!
68
+
69
+
70
+ tr.1, tur-sueperlig-2024-2025
71
+ tr.2, tur-1-lig-2024-2025
72
+
73
+ gr.1, gre-super-league-2024-2025
74
+
75
+ hr.1, cro-1-hnl-2024-2025
@@ -0,0 +1,156 @@
1
+ module Worldfootball
2
+
3
+
4
+
5
+ def self.parse_score( score_str )
6
+ ## add support for
7
+ ## 3-0 (0-0, 0-0) Wert.
8
+ ## 3-0 (0-0, 0-0) awd.
9
+
10
+ ## check for 0:3 Wert. - change Wert. to awd. (awarded)
11
+ ## todo/fix - use "hardcoded" Wert\. in regex - why? why not?
12
+ ## score_str = score_str.sub( /Wert\./i, 'awd.' )
13
+
14
+
15
+ comments = String.new ## check - rename to/use status or such - why? why not?
16
+
17
+ ## split score
18
+ ft = ''
19
+ ht = ''
20
+ et = ''
21
+ pen = ''
22
+
23
+
24
+ if score_str == '---' ## in the future (no score yet) - was -:-
25
+ ft = ''
26
+ ht = ''
27
+ elsif score_str == 'n.gesp.' || ## cancelled (british) / canceled (us)
28
+ score_str == 'ausg.' || ## todo/check: change to some other status ????
29
+ score_str == 'annull.' ## todo/check: change to some other status (see ie 2012) ????
30
+ ft = '(*)'
31
+ ht = ''
32
+ comments = 'cancelled'
33
+ elsif score_str == 'abgebr.' ## abandoned -- waiting for replay?
34
+ ft = '(*)'
35
+ ht = ''
36
+ comments = 'abandoned'
37
+ elsif score_str == 'verl.' ## postponed
38
+ ft = ''
39
+ ht = ''
40
+ comments = 'postponed'
41
+ # 5-4 (0-0, 1-1, 2-2) i.E.
42
+ elsif score_str =~ /([0-9]+) [ ]*-[ ]* ([0-9]+)
43
+ [ ]*
44
+ \(([0-9]+) [ ]*-[ ]* ([0-9]+)
45
+ [ ]*,[ ]*
46
+ ([0-9]+) [ ]*-[ ]* ([0-9]+)
47
+ [ ]*,[ ]*
48
+ ([0-9]+) [ ]*-[ ]* ([0-9]+)\)
49
+ [ ]*
50
+ i\.E\.
51
+ /x
52
+ pen = "#{$1}-#{$2}"
53
+ ht = "#{$3}-#{$4}"
54
+ ft = "#{$5}-#{$6}"
55
+ et = "#{$7}-#{$8}"
56
+ # 3-2 (0-0, 1-1) i.E. - note: no extra time!!! only ht,ft!!!
57
+ # "popular" in southamerica & mexico
58
+ elsif score_str =~ /([0-9]+) [ ]*-[ ]* ([0-9]+)
59
+ [ ]*
60
+ \(([0-9]+) [ ]*-[ ]* ([0-9]+)
61
+ [ ]*,[ ]*
62
+ ([0-9]+) [ ]*-[ ]* ([0-9]+)\)
63
+ [ ]*
64
+ i\.E\.
65
+ /x
66
+ pen = "#{$1}-#{$2}"
67
+ ht = "#{$3}-#{$4}"
68
+ ft = "#{$5}-#{$6}"
69
+ et = ''
70
+ # 2-1 (1-0, 1-1) n.V
71
+ elsif score_str =~ /([0-9]+) [ ]*-[ ]* ([0-9]+)
72
+ [ ]*
73
+ \(([0-9]+) [ ]*-[ ]* ([0-9]+)
74
+ [ ]*,[ ]*
75
+ ([0-9]+) [ ]*-[ ]* ([0-9]+)
76
+ \)
77
+ [ ]*
78
+ n\.V\.
79
+ /x
80
+ et = "#{$1}-#{$2}"
81
+ ht = "#{$3}-#{$4}"
82
+ ft = "#{$5}-#{$6}"
83
+ ### auto-patch fix drop last score
84
+ ## 1-3 (0-1, 1-1, 0-2) n.V. => 1-3 (0-1, 1-1) n.V.
85
+ elsif score_str =~ /([0-9]+) [ ]*-[ ]* ([0-9]+)
86
+ [ ]*
87
+ \(([0-9]+) [ ]*-[ ]* ([0-9]+)
88
+ [ ]*,[ ]*
89
+ ([0-9]+) [ ]*-[ ]* ([0-9]+)
90
+ [ ]*,[ ]*
91
+ ([0-9]+) [ ]*-[ ]* ([0-9]+)
92
+ \)
93
+ [ ]*
94
+ n\.V\.
95
+ /x
96
+ et = "#{$1}-#{$2}"
97
+ ht = "#{$3}-#{$4}"
98
+ ft = "#{$5}-#{$6}"
99
+
100
+ puts "!! WARN - auto-fix/patch score - >#{score_str}<"
101
+ ### todo/fix - log auto-patch/fix - for double checking!!!!!
102
+ elsif score_str =~ /([0-9]+) [ ]*-[ ]* ([0-9]+)
103
+ [ ]*
104
+ \(([0-9]+) [ ]*-[ ]* ([0-9]+)
105
+ \)
106
+ /x
107
+ ft = "#{$1}-#{$2}"
108
+ ht = "#{$3}-#{$4}"
109
+ elsif score_str =~ /([0-9]+) [ ]*-[ ]* ([0-9]+)
110
+ [ ]*
111
+ Wert\. # ([a-z.]+)
112
+ /x ### assume awd. (awarded) always - why? why not?
113
+ ft = "#{$1}-#{$2} (*)"
114
+ ht = ''
115
+ comments = 'awd.' # awarded - $3
116
+ ## auto-fix/patch
117
+ ## drop last scores (only use ft)
118
+ ## 3-0 (0-0, 0-0) awd.
119
+ elsif score_str =~ /([0-9]+) [ ]*-[ ]* ([0-9]+)
120
+ [ ]*
121
+ \(([0-9]+) [ ]*-[ ]* ([0-9]+)
122
+ [ ]*,[ ]*
123
+ ([0-9]+) [ ]*-[ ]* ([0-9]+)
124
+ \)
125
+ [ ]*
126
+ Wert\. # ([a-z.]+)
127
+ /x ### assume awd. (awarded) always - why? why not?
128
+ ft = "#{$1}-#{$2} (*)"
129
+ ht = ''
130
+ comments = 'awd.' # awarded - $7
131
+ ## (auto) log case for double checking - why? why not?
132
+ elsif score_str =~ /^([0-9]+)-([0-9]+)$/
133
+ ft = "#{$1}-#{$2}" ## e.g. see luxemburg and others
134
+ ht = ''
135
+ ## auto-fix/patch
136
+ # 3-3 (0-3, 3-3) => 3-3 (0-3) - drop last score
137
+ elsif score_str =~ /^([0-9]+) [ ]*-[ ]* ([0-9]+)
138
+ [ ]*
139
+ \(([0-9]+) [ ]*-[ ]* ([0-9]+)
140
+ [ ]*,[ ]*
141
+ ([0-9]+) [ ]*-[ ]* ([0-9]+)
142
+ \)$
143
+ /x
144
+ ft = "#{$1}-#{$2}"
145
+ ht = "#{$3}-#{$4}"
146
+
147
+ puts "!! WARN - auto-fix/patch score - >#{score_str}<"
148
+ ### todo/fix - log auto-patch/fix - for double checking!!!!!
149
+ else
150
+ puts "!! ERROR - unsupported score format >#{score_str}< - sorry; maybe add a score error fix/patch"
151
+ exit 1
152
+ end
153
+
154
+ [ht, ft, et, pen, comments]
155
+ end
156
+ end # module Worldfootball