worldfootball 0.3.0 → 0.3.2

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.
@@ -73,11 +73,29 @@ def self.build( rows, season:, league:, stage: '' ) ## rename to fixup or such
73
73
 
74
74
  date_str = row[:date]
75
75
  time_str = row[:time]
76
+
77
+
76
78
  team1_str = row[:team1]
77
79
  team2_str = row[:team2]
78
- score_str = row[:score]
80
+
81
+ ## R. Betis / Jag. Białystok v Celje / Fiorentina
82
+ ## Legia Warszawa / Chelsea v Djurgårdens / Rapid Wien
83
+ team1_ref = row[:team1_ref]
84
+ team2_ref = row[:team2_ref]
85
+
86
+ ## reset team name to N.N. if team_ref is nil and name include " / "
87
+ if team1_ref.nil? && team1_str.index( ' / ')
88
+ puts "!! WARN - change placeholder team #{team1_str} to N.N."
89
+ team1_str = 'N.N.'
90
+ end
91
+ if team2_ref.nil? && team2_str.index( ' / ')
92
+ puts "!! WARN - change placeholder team #{team2_str} to N.N."
93
+ team2_str = 'N.N.'
94
+ end
79
95
 
80
96
 
97
+ score_str = row[:score]
98
+
81
99
 
82
100
  ### check for score_error; first (step 1) lookup by date
83
101
  score_error = score_errors[ date_str ]
@@ -2,13 +2,23 @@
2
2
  module Worldfootball
3
3
 
4
4
 
5
- def self.convert( league:, season: )
5
+ def self.convert( league:, season:,
6
+ overwrite: true )
6
7
  season = Season( season ) ## cast (ensure) season class (NOT string, integer, etc.)
7
8
 
8
9
  league = find_league!( league )
9
10
  pages = league.pages!( season: season )
10
11
 
11
12
 
13
+ out_path = "#{config.convert.out_dir}/#{season.path}/#{league.key}.csv"
14
+ if !overwrite && File.exist?( out_path )
15
+ ## skip generation
16
+ puts " OK #{league.key} #{season} (do NOT overwrite)"
17
+ return
18
+ end
19
+
20
+
21
+
12
22
  ## collect all teams
13
23
  teams_by_ref = {}
14
24
 
@@ -43,22 +53,35 @@ def self.convert( league:, season: )
43
53
  ## e.g. {:count=>2, :name=>"AS Arta", :ref=>"as-arta"},
44
54
  ## {:count=>4, :name=>"Dekedaha FC", :ref=>"dekedaha-fc"},
45
55
  ## ...
56
+ ### {:count=>2, :name=>"Arsenal / Real Madrid", :ref=>nil},
57
+ ## {:count=>2, :name=>"PSG / Aston Villa", :ref=>nil},
58
+ ## {:count=>2, :name=>"Barcelona / Dortmund", :ref=>nil},
59
+ ## {:count=>2, :name=>"Bayern / Inter", :ref=>nil},
60
+ ## {:count=>1, :name=>"Sieger HF 1", :ref=>nil},
61
+ ## {:count=>1, :name=>"Sieger HF 2", :ref=>nil}]
62
+
63
+
46
64
  teams.each do |h|
47
65
  team_count = h[:count]
48
66
  team_name = norm_team( h[:name] ) ## note: norm team name!!!
49
67
  team_ref = h[:ref]
50
68
 
69
+ ###
70
+ ## quick fix for broken refs/links
71
+ ## olympique-lyon => olympique-lyonnais
72
+ # team_ref = 'olympique-lyonnais' if team_ref == 'olympique-lyon'
73
+
51
74
  ## note: skip N.N. (place holder team)
52
75
  ## team_ref is nil etc.
53
76
  next if team_name == 'N.N.'
54
-
77
+ ### warn if team_ref is nil and skip !!!
78
+ next if team_ref.nil?
79
+
80
+
55
81
  team_stat = teams_by_ref[ team_ref ] ||= { count: 0,
56
- name: team_name }
82
+ names: [] }
57
83
  team_stat[:count] += team_count
58
- if team_name != team_stat[:name]
59
- puts "!! ASSERT ERROR - team ref with differet names; expected #{team_stat[:name]} - got #{team_name}"
60
- exit 1
61
- end
84
+ team_stat[:names] << team_name unless team_stat[:names].include?( team_name )
62
85
  end
63
86
 
64
87
 
@@ -73,9 +96,12 @@ def self.convert( league:, season: )
73
96
 
74
97
 
75
98
  clubs_intl = ['uefa.cl', 'uefa.el', 'uefa.conf',
76
- 'copa.l',
99
+ 'uefa.cl.q', 'uefa.el.q', 'uefa.conf.q',
100
+ 'copa.l', 'copa.s',
101
+ 'concacaf.cl',
77
102
  'caf.cl',
78
- 'afl'].include?(league.key) ? true : false
103
+ 'afl',
104
+ ].include?(league.key) ? true : false
79
105
 
80
106
  ####
81
107
  # auto-add (fifa) country code if int'l club tournament
@@ -83,7 +109,6 @@ def self.convert( league:, season: )
83
109
  ##
84
110
  ## get country codes for team ref
85
111
  teams_by_ref.each do |team_slug, h|
86
-
87
112
  Metal.download_team( team_slug, cache: true )
88
113
  team_page = Page::Team.from_cache( team_slug )
89
114
  props = team_page.props
@@ -99,26 +124,36 @@ def self.convert( league:, season: )
99
124
 
100
125
  ## generate lookup by name
101
126
  teams_by_name = teams_by_ref.reduce( {} ) do |h, (slug,rec)|
102
- h[ rec[:name]] = rec
103
- h
127
+ ### todo/fix
128
+ ## report warning if names size is > 1!!!!
129
+ ##
130
+ rec[:names].each do |name|
131
+ h[ name ] = rec
132
+ end
133
+ h
104
134
  end
105
135
 
136
+
106
137
  #####
107
138
  ## dump team refs
108
139
  puts " #{teams_by_ref.size} team(s) by ref:"
109
- pp teams_by_name
140
+ pp teams_by_ref
110
141
 
111
142
  ## quick hack
112
143
  ## add country (fifa) codes to team names
144
+ ##
145
+ ## note - some placeholder teams have no ref!! and, thus no entry with country code
113
146
  recs.each do |rec|
114
147
  team1_org = rec[5]
115
- if team1_org != 'N.N.' ## note - skip place holder; keep as-is
148
+ if team1_org != 'N.N.' && ## note - skip place holder; keep as-is
149
+ teams_by_name[team1_org]
116
150
  country_code = teams_by_name[team1_org][:code]
117
151
  rec[5] = "#{team1_org} (#{country_code})"
118
152
  end
119
153
 
120
154
  team2_org = rec[8]
121
- if team2_org != 'N.N.' ## note - skip place holder; keep as-is
155
+ if team2_org != 'N.N.' && ## note - skip place holder; keep as-is
156
+ teams_by_name[team2_org]
122
157
  country_code = teams_by_name[team2_org][:code]
123
158
  rec[8] = "#{team2_org} (#{country_code})"
124
159
  end
@@ -129,10 +164,22 @@ def self.convert( league:, season: )
129
164
  ## note: sort matches by date before saving/writing!!!!
130
165
  ## note: for now assume date in string in 1999-11-30 format (allows sort by "simple" a-z)
131
166
  ## note: assume date is third column!!! (stage/round/date/...)
132
- recs = recs.sort { |l,r| l[2] <=> r[2] }
167
+
168
+ ### note - do NOT sort for now
169
+ ## keep "original" page order - why? why not?
170
+ ## recs = recs.sort { |l,r| l[2] <=> r[2] }
171
+
172
+
133
173
  ## reformat date / beautify e.g. Sat Aug 7 1993
134
174
  recs.each do |rec|
135
- rec[2] = Date.strptime( rec[2], '%Y-%m-%d' ).strftime( '%a %b %-d %Y' )
175
+ if rec[2]
176
+ if rec[2] =~ /^\d{4}-\d{1,2}-\d{1,2}$/
177
+ rec[2] = Date.strptime( rec[2], '%Y-%m-%d' ).strftime( '%a %b %-d %Y' )
178
+ else
179
+ ## report unknown date format warning
180
+ puts "WARN - unsupported date format (cannot parse?) >#{rec[2]}<"
181
+ end
182
+ end
136
183
  end
137
184
 
138
185
  ## remove unused columns (e.g. stage, et, p, etc.)
@@ -141,10 +188,13 @@ recs.each do |rec|
141
188
  puts headers
142
189
  pp recs[0] ## check first record
143
190
 
144
- out_path = "#{config.convert.out_dir}/#{season.path}/#{league.key}.csv"
145
-
146
- puts "write #{out_path}..."
191
+ puts " writing to >#{out_path}< - #{recs.size} record(s)..."
147
192
  write_csv( out_path, recs, headers: headers )
193
+
194
+ ## add to tmp too for debugging
195
+ out_path2 = "#{config.convert.out_dir}/tmp/#{league.key}/#{season.to_path}.csv"
196
+ puts " writing to >#{out_path2}< - #{recs.size} record(s)..."
197
+ write_csv( out_path2, recs, headers: headers )
148
198
  end
149
199
  end # module Worldfootball
150
200
 
@@ -4,12 +4,16 @@ module Worldfootball
4
4
 
5
5
  #################
6
6
  ## porcelain "api"
7
- def self.schedule( league:, season: )
7
+ def self.schedule( league:, season:, overwrite: true )
8
8
  season = Season( season ) ## cast (ensure) season class (NOT string, integer, etc.)
9
9
 
10
10
  pages = find_league_pages!( league: league, season: season )
11
11
  pages.each do |slug, _|
12
- Metal.download_schedule( slug )
12
+ if !overwrite && Webcache.cached?( Metal.schedule_url( slug ))
13
+ puts " OK #{league} #{season} - #{slug} (do NOT overwrite)"
14
+ else
15
+ Metal.download_schedule( slug )
16
+ end
13
17
  end # each page
14
18
  end
15
19
 
@@ -61,9 +61,12 @@ class LeagueItem # nested inside LeagueConfig
61
61
  season, stage = text.split( ' ', 2 )
62
62
 
63
63
  ## todo/fix: add a waring here and auto log to logs.txt!!!!
64
- next if season == '2019-2021'
65
- next if season == '1958/1960'
66
- next if season == '1955/1958'
64
+ if ['2019-2021',
65
+ '1958/1960',
66
+ '1955/1958' ].include?( season )
67
+ log( "!! WARN - seasons for league #{@key} incl. invalid season #{season} - slug #{slug}; skipping season" )
68
+ next ## note - skip invalid season entry
69
+ end
67
70
 
68
71
  season = Season.parse( season )
69
72
 
@@ -106,6 +109,13 @@ class LeagueItem # nested inside LeagueConfig
106
109
  recs = seasons[season.key]
107
110
  recs ? recs.reverse : nil
108
111
  end
112
+
113
+ def log( msg ) ### append to log
114
+ File.open( './logs.txt', 'a:utf-8' ) do |f|
115
+ f.write( msg )
116
+ f.write( "\n" )
117
+ end
118
+ end
109
119
  end # class LeagueItem
110
120
 
111
121
 
@@ -122,6 +132,9 @@ def size() @table.size; end
122
132
  end # class LeagueConfig
123
133
 
124
134
 
135
+
136
+
137
+
125
138
  LEAGUES = LeagueConfig.new
126
139
  ['africa',
127
140
  'america',
@@ -10,11 +10,20 @@ module Worldfootball
10
10
  def self.norm_team( team )
11
11
  ## clean team name and asciify (e.g. ’->' )
12
12
  team = team.sub( '(old)', '' ).strip
13
- team = team.gsub( '’', "'" ) ## e.g. Hawke’s Bay United FC
14
13
 
15
- ## Criciúma - SC => Criciúma - SC
16
- ## Bahia - BA => Bahia - BA
14
+ ## e.g. Hawke’s Bay United FC or
15
+ ## ASC Monts d`Or Chasselay or
16
+ ## VV Heerlen ´16 / EMM ´15 / Wormer SV´30 / Swift ´36 / etc.
17
+ team = team.gsub( /[’´`]/, "'" )
18
+
19
+
20
+ ## br
21
+ ## Criciúma - SC => Criciúma SC
22
+ ## Bahia - BA => Bahia BA
23
+ ## cz
24
+ ## Baník Most - Souš => Baník Most Souš
17
25
  ## remove inline dash ( - ) with single space
26
+ ## to log
18
27
  team = team.gsub( /[ ]+[-][ ]+/, ' ' )
19
28
 
20
29
 
@@ -24,6 +33,22 @@ def self.norm_team( team )
24
33
  ## others too? - move to mods instead of generic rule - why? why not?
25
34
  team = team.sub( /[ ]+\(A\)/, ' II' )
26
35
 
36
+ ##
37
+ ## remove () - used/reserved for country code for now - why? why not?
38
+ ## e.g. Lloyds FC (Sittingbourne) => Lloyds FC Sittingbourne
39
+ ## August 1st (Army Team) => August 1st Army Team
40
+ ##
41
+ ## add warning - why? why not?
42
+ team = team.sub( /\(
43
+ ([^)]+?) ## eat-up all non-greed to next )
44
+ \)/x, '\1' )
45
+
46
+ ##
47
+ ## strip special case
48
+ ## MFK Frýdek-Místek, a.s. => MFK Frýdek-Místek
49
+ team = team.sub( ', a.s.', '' )
50
+
51
+
27
52
  ################
28
53
  ## quick hack - norm(alize) all N.N. to N.N.
29
54
  ## e.g.
@@ -12,6 +12,15 @@ class Schedule < Page ## note: use nested class for now - why? why not?
12
12
  end
13
13
 
14
14
 
15
+ PLACEHOLDERS = [
16
+ 'N.N.',
17
+ 'Verlierer HF 1',
18
+ 'Verlierer HF 2',
19
+ 'Sieger HF 1',
20
+ 'Sieger HF 2',
21
+ ]
22
+ def placeholder?( str ) PLACEHOLDERS.include?( str ); end
23
+
15
24
 
16
25
  def matches
17
26
  @matches ||= begin
@@ -20,10 +29,12 @@ class Schedule < Page ## note: use nested class for now - why? why not?
20
29
  # <table class="standard_tabelle" cellpadding="3" cellspacing="1">
21
30
 
22
31
  ## note: use > for "strict" sibling (child without any in-betweens)
23
- table = doc.css( 'div.data > table.standard_tabelle' ).first ## get table
32
+ tables = doc.css( 'div.data > table.standard_tabelle' ) ## get table
24
33
  # puts table.class.name #=> Nokogiri::XML::Element
25
34
  # puts table.text
26
35
 
36
+ assert( tables.size==1, "expected one table.standard_tabelle; got #{tables.size}" )
37
+ table = tables.first
27
38
  assert( table, 'no table.standard_tabelle found in schedule page!!')
28
39
 
29
40
  trs = table.css( 'tr' )
@@ -77,8 +88,10 @@ class Schedule < Page ## note: use nested class for now - why? why not?
77
88
  ths = tr.css( 'th' )
78
89
  tds = tr.css( 'td' )
79
90
 
80
- if tr.text.strip =~ /Spieltag/ ||
81
- tr.text.strip =~ /[1-9]\.[ ]Runde|
91
+ tr_text = squish( tr.text )
92
+
93
+ if tr_text =~ /Spieltag/ ||
94
+ tr_text =~ /[1-9]\.[ ]Runde|
82
95
  Qual\.[ ][1-9]\.[ ]Runde| # see EL or CL Quali
83
96
  Qualifikation| # see CA Championship
84
97
  Sechzehntelfinale| # see EL
@@ -110,25 +123,24 @@ class Schedule < Page ## note: use nested class for now - why? why not?
110
123
  if debug?
111
124
  puts
112
125
  print '[%03d] ' % i
113
- ## print squish( tr.text )
114
- print "round >#{tr.text.strip}<"
126
+ print "round >#{tr_text}<"
115
127
  print "\n"
116
128
  end
117
129
 
118
- last_round = tr.text.strip
130
+ last_round = tr_text
119
131
  elsif ths.count > 0 &&
120
132
  tds.count == 0
121
133
  ## check for round NOT yet configured!!!
122
- puts "!! WARN: found unregistered round line >#{tr.text.strip}<"
123
- log( "!! WARN: found unregistered round line >#{tr.text.strip}< in page #{title}" )
134
+ puts "!! WARN: found unregistered round line >#{tr_text}<"
135
+ log( "!! WARN: found unregistered round line >#{tr_text}< in page #{title}" )
124
136
 
125
- last_round = tr.text.strip
137
+ last_round = tr_text
126
138
  else ## assume table row (tr) is match line
127
139
 
128
140
  date_str = squish( tds[0].text )
129
141
  time_str = squish( tds[1].text )
130
142
 
131
- date_str = last_date_str if date_str.empty?
143
+ date_str = last_date_str if date_str.empty? && last_date_str
132
144
 
133
145
  if debug?
134
146
  ## note: for debugging - print as we go along (parsing)
@@ -148,7 +160,7 @@ class Schedule < Page ## note: use nested class for now - why? why not?
148
160
  else
149
161
  team1_str = squish( tds[2].text )
150
162
  team1_ref = nil
151
- puts "!! WARN: no team1_ref for >#{team1_str}< found"
163
+ puts "!! WARN: no team1_ref for >#{team1_str}< found" unless placeholder?( team1_str )
152
164
  end
153
165
 
154
166
  if debug?
@@ -170,9 +182,10 @@ class Schedule < Page ## note: use nested class for now - why? why not?
170
182
  else
171
183
  team2_str = squish( tds[4].text )
172
184
  team2_ref = nil
173
- puts "!! WARN: no team2_ref for >#{team2_str}< found"
185
+ puts "!! WARN: no team2_ref for >#{team2_str}< found" unless placeholder?( team2_str )
174
186
  end
175
187
 
188
+
176
189
  if debug?
177
190
  ## note: for debugging - print as we go along (parsing)
178
191
  print "%-22s | " % team2_str
@@ -198,8 +211,12 @@ class Schedule < Page ## note: use nested class for now - why? why not?
198
211
  ## <img src="https://s.hs-data.com/bilder/shared/live/2.png" /></a>
199
212
  ## </td>
200
213
  img = tds[6].css( 'img' )[0]
214
+
215
+
216
+
201
217
  if img && img[:src].index( '/live/')
202
- puts "!! WARN: live match badge, resetting score from #{score_str} to -:-"
218
+ ## puts "!! WARN: live match badge, resetting score from #{score_str} to -:-"
219
+ print " LIVE BADGE "
203
220
  score_str = '-:-' # note: -:- gets replaced to ---
204
221
  end
205
222
 
@@ -217,8 +234,12 @@ class Schedule < Page ## note: use nested class for now - why? why not?
217
234
  ## special case for '00.00.0000'
218
235
  ## CANNOT parse
219
236
  ## use empty date - why? why not?
237
+ ## if start with 00.00. e.g. 00.00.1939
238
+
220
239
 
221
- date = if date_str == '00.00.0000'
240
+ date = if date_str == '00.00.0000' ||
241
+ date_str.start_with?( '00.00.' ) ||
242
+ date_str.empty?
222
243
  nil
223
244
  else
224
245
  Date.strptime( date_str, '%d.%m.%Y' )
@@ -237,7 +258,9 @@ class Schedule < Page ## note: use nested class for now - why? why not?
237
258
  report_ref: score_ref
238
259
  }
239
260
 
240
- last_date_str = date_str
261
+ ## note - only update last date if date present
262
+ ## might be empty (not available) in the beginning
263
+ last_date_str = date_str if !date_str.empty?
241
264
  end
242
265
  end # each tr (table row)
243
266
 
@@ -2,7 +2,7 @@
2
2
  module Worldfootball
3
3
  MAJOR = 0 ## todo: namespace inside version or something - why? why not??
4
4
  MINOR = 3
5
- PATCH = 0
5
+ PATCH = 2
6
6
  VERSION = [MAJOR,MINOR,PATCH].join('.')
7
7
 
8
8
  def self.version
data/lib/worldfootball.rb CHANGED
@@ -41,6 +41,14 @@ module Worldfootball
41
41
  def self.debug=(value) @debug = value; end
42
42
  def self.debug?() @debug ||= false; end ## note: default is FALSE
43
43
 
44
+ def self.log( msg ) ### append to log
45
+ File.open( './logs.txt', 'a:utf-8' ) do |f|
46
+ f.write( msg )
47
+ f.write( "\n" )
48
+ end
49
+ end
50
+
51
+
44
52
 
45
53
 
46
54
  class Configuration
@@ -71,6 +79,60 @@ end # module Worldfootball
71
79
 
72
80
 
73
81
 
82
+ ###
83
+ # todo - move generate to generate file!!!
84
+ module Worldfootball
85
+ def self.generate( league:, season:,
86
+ overwrite: true )
87
+ season = Season( season ) ## cast (ensure) season class (NOT string, integer, etc.)
88
+
89
+ league = find_league!( league )
90
+ pages = league.pages!( season: season )
91
+
92
+
93
+ out_path = if season >= Season( '2000' )
94
+ "#{config.generate.out_dir}/#{season.to_path}/#{league.key}.txt"
95
+ else
96
+ decade = season.start_year - (season.start_year%10)
97
+ ## use archive-style before 2000!!!
98
+ "#{config.generate.out_dir}/archive/#{decade}s/#{season.to_path}/#{league.key}.txt"
99
+ end
100
+
101
+ ## check if output exists already
102
+ if !overwrite && File.exist?( out_path )
103
+ ## skip generation
104
+ puts " OK #{league.key} #{season} (do NOT overwrite)"
105
+ return
106
+ end
107
+
108
+
109
+ ## get matches
110
+ path = "#{config.convert.out_dir}/#{season.to_path}/#{league.key}.csv"
111
+ puts " ---> reading matches in #{path} ..."
112
+ matches = SportDb::CsvMatchParser.read( path )
113
+ puts " #{matches.size} matches"
114
+
115
+ ## build
116
+ txt = SportDb::TxtMatchWriter.build( matches )
117
+ puts txt
118
+
119
+
120
+ buf = String.new
121
+ ## note - use league key for league name for now!!
122
+ buf << "= #{league.key.upcase.gsub('.', ' ')} #{season.key}\n\n"
123
+ buf << txt
124
+
125
+ puts " writing to >#{out_path}<..."
126
+ write_text( out_path, buf )
127
+
128
+ ## add to tmp too for debugging
129
+ out_path2 = "#{config.generate.out_dir}/tmp/#{league.key}/#{season.to_path}.txt"
130
+ puts " writing to >#{out_path2}<..."
131
+ write_text( out_path2, buf )
132
+ end
133
+ end # module Worldfootball
134
+
135
+
74
136
 
75
137
 
76
138
  puts Worldfootball.banner ## say hello
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: worldfootball
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.2
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-10-06 00:00:00.000000000 Z
11
+ date: 2025-03-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: football-timezones
@@ -106,19 +106,25 @@ dependencies:
106
106
  requirements:
107
107
  - - "~>"
108
108
  - !ruby/object:Gem::Version
109
- version: '4.1'
109
+ version: '4.2'
110
110
  type: :development
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
- version: '4.1'
116
+ version: '4.2'
117
117
  description: worldfootball - get world football (leagues, cups & more) match data
118
118
  via the worldfootball.net/weltfussball.de pages
119
119
  email: gerald.bauer@gmail.com
120
120
  executables:
121
121
  - wfb
122
+ - wfbconf
123
+ - wfbconv
124
+ - wfbdump
125
+ - wfbgen
126
+ - wfbsync
127
+ - wfbup
122
128
  extensions: []
123
129
  extra_rdoc_files:
124
130
  - CHANGELOG.md
@@ -130,6 +136,12 @@ files:
130
136
  - README.md
131
137
  - Rakefile
132
138
  - bin/wfb
139
+ - bin/wfbconf
140
+ - bin/wfbconv
141
+ - bin/wfbdump
142
+ - bin/wfbgen
143
+ - bin/wfbsync
144
+ - bin/wfbup
133
145
  - config/leagues/africa.csv
134
146
  - config/leagues/america.csv
135
147
  - config/leagues/asia.csv
@@ -175,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
175
187
  - !ruby/object:Gem::Version
176
188
  version: '0'
177
189
  requirements: []
178
- rubygems_version: 3.4.10
190
+ rubygems_version: 3.5.22
179
191
  signing_key:
180
192
  specification_version: 4
181
193
  summary: worldfootball - get world football (leagues, cups & more) match data via