worldfootball 0.1.2 → 0.2.1

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: 99623775fef73f0837946ba44625a572bbe5fee3a64aa6aa9a2f6f79702a0d01
4
- data.tar.gz: 1ed058214bcca9fad1aac5b205e73c101a79a14ef979dbdee37c3a784fe03460
3
+ metadata.gz: 0c86445bc20b0caf099381fbae9fbf39fa270a66323883873956632759c3ac4f
4
+ data.tar.gz: b25de731e07a047ac3562bb21d5ea2c26c6eae0eab18ad9ba4d9607a5868b242
5
5
  SHA512:
6
- metadata.gz: 2b2ec98872c3cf9ae5b9f39cd6ac5bcd205ea35a4ea1282a575f8ea9256226f4395c4021b57417e6d77db38b474127b35cd2836aee3d381a8138b318cb588be0
7
- data.tar.gz: dff2a077af11f10c6c0f1e923e42710b04b198a5c7a7677363a25bfa7e508ec56867d64c2df8f907a51584613b0d86a8f246f6727755fa1dfa1e6c1135962877
6
+ metadata.gz: 791384fb869d7ee752b5558b3929a8c55785150ab6308fbbb69f736e832de6911f6cc3ca630af32dad3ace29d83a795dd8d2cd54524966a792d160ffedd92430
7
+ data.tar.gz: 5494cb8022f2be71c73da4ff3a42fd84e844116b003b52f1108f075bd7371cf774379fcd9d9db4571453b91bfedc8090533ccd7395b827d3b0a9545c5c551749
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ### 0.1.2
1
+ ### 0.2.1
2
2
 
3
3
  ### 0.0.1 / 2024-07-04
4
4
 
data/Manifest.txt CHANGED
@@ -3,12 +3,17 @@ Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
5
  bin/wfb
6
- config/leagues.csv
6
+ config/leagues_america.csv
7
+ config/leagues_asia.csv
8
+ config/leagues_europe.csv
9
+ config/leagues_middle_east.csv
10
+ config/leagues_pacific.csv
11
+ config/rounds.csv
12
+ config/stages.csv
7
13
  lib/worldfootball.rb
8
14
  lib/worldfootball/build-parse_score.rb
9
15
  lib/worldfootball/build.rb
10
16
  lib/worldfootball/cache.rb
11
- lib/worldfootball/config.rb
12
17
  lib/worldfootball/convert.rb
13
18
  lib/worldfootball/convert_reports.rb
14
19
  lib/worldfootball/download.rb
@@ -17,5 +22,6 @@ lib/worldfootball/mods.rb
17
22
  lib/worldfootball/page.rb
18
23
  lib/worldfootball/page_report.rb
19
24
  lib/worldfootball/page_schedule.rb
25
+ lib/worldfootball/stages.rb
20
26
  lib/worldfootball/vacuum.rb
21
27
  lib/worldfootball/version.rb
data/Rakefile CHANGED
@@ -18,11 +18,9 @@ Hoe.spec 'worldfootball' do
18
18
  self.history_file = 'CHANGELOG.md'
19
19
 
20
20
  self.extra_deps = [
21
- ## ['tzinfo'],
22
- ['season-formats'],
21
+ ['football-timezones'],
23
22
  ['webget'],
24
23
  ['nokogiri'],
25
- ['cocos'], ## later pull in with sportsdb-writers
26
24
  ]
27
25
 
28
26
  self.licenses = ['Public Domain']
data/bin/wfb CHANGED
@@ -15,7 +15,7 @@ Webcache.root = if File.exist?( '/sports/cache' )
15
15
 
16
16
  ## convert (default) output directory
17
17
  Worldfootball.config.convert.out_dir = if File.exist?( '/sports/cache.wfb')
18
- puts " setting convert out_dir to >/sports/cache.wfb<"
18
+ puts " setting convert out_dir to >/sports/cache.wfb<"
19
19
  '/sports/cache.wfb'
20
20
  else
21
21
  '.' ## use working dir
@@ -102,12 +102,16 @@ if opts[:dry]
102
102
  end
103
103
 
104
104
 
105
- season = Season( args[1] || '2024/25' )
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] )
106
109
 
107
110
  pages = league.pages!( season: season )
108
111
 
109
112
 
110
113
  puts
114
+ pp [league.key, season.key]
111
115
  pp pages
112
116
  puts " #{pages.size} page(s)"
113
117
 
@@ -0,0 +1,70 @@
1
+ key, slug
2
+
3
+
4
+ # todo/fix: adjust date/time by -6 or 7 hours!!!
5
+ # /can-canadian-championship-2020/
6
+ # - Qual. 1. Runde
7
+ # - Qual. 2. Runde
8
+ # - Qual. 3. Runde
9
+ # todo/fix: check for leagues - premier league? championship? soccer league?
10
+ ca.1, can-premier-league-2024
11
+ ca.cup, can-canadian-championship-2024
12
+
13
+
14
+ # todo/fix: adjust date/time by -7 hours!!!
15
+ ## e.g. 25.07.2020 02:30 => 24.07.2020 19.30
16
+ # 11.01.2020 04:00 => 10.01.2020 21.00
17
+ #
18
+ # e.g. /mex-primera-division-2020-2021-apertura/
19
+ # /mex-primera-division-2019-2020-clausura/
20
+ # /mex-primera-division-2019-2020-apertura-playoffs/
21
+ # - Viertelfinale
22
+ # - Halbfinale
23
+ # - Finale
24
+ # /mex-primera-division-2018-2019-clausura-playoffs/
25
+ mx.1, mex-primera-division-2024-2025-apertura_2
26
+ mx.2, mex-liga-de-expansion-2024-2025-apertura
27
+ mx.cup, mex-copa-mx-2019-2020
28
+
29
+
30
+
31
+ ## change to mls - why? why not?
32
+ us.1, usa-major-league-soccer-2024
33
+ us.2, usa-usl-championship-2024
34
+ us.cup, usa-u-s-open-cup-2024
35
+
36
+
37
+
38
+ br.1, bra-serie-a-2024
39
+ br.2, bra-serie-b-2024
40
+ br.cup, bra-copa-do-brasil-2024
41
+
42
+
43
+ co.1, col-primera-a-2024-clausura
44
+ co.2, col-primera-b-2024-clausura
45
+ co.cup, col-copa-colombia-2024
46
+
47
+
48
+ cl.1, chi-primera-division-2024
49
+ cl.cup, chi-copa-chile-2024
50
+
51
+ ec.1, ecu-serie-a-2024-segunda-etapa
52
+ ec.2, ecu-serie-b-2024_2
53
+
54
+ bo.1, bol-liga-profesional-2024-clausura
55
+
56
+
57
+ ar.1, arg-primera-division-2024
58
+ ar.2.nacional, arg-primera-b-nacional-2024
59
+ ar.2.metro, arg-primera-b-metropolitana-2024-clausura
60
+ ar.cup, arg-copa-argentina-2024
61
+
62
+ py.1, par-primera-division-2024-clausura
63
+
64
+ pe.1, per-primera-division-2024-clausura_2
65
+
66
+ uy.1, uru-primera-division-2024-clausura
67
+ uy.2, uru-segunda-division-2024-fase-regular
68
+ uy.cup, uru-copa-2024
69
+
70
+ ve.1, ven-primera-division-2024-clausura
@@ -0,0 +1,10 @@
1
+ key, slug
2
+
3
+ jp.1, jpn-j1-league-2024
4
+ jp.2, jpn-j2-league-2024
5
+ jp.cup, jpn-emperors-cup-2024
6
+
7
+ cn.1, chn-super-league-2024
8
+
9
+ kr.1, kor-k-league-1-2024
10
+
@@ -0,0 +1,122 @@
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.4.n, regionalliga-nord-2024-2025
8
+ de.4.no, regionalliga-nordost-2024-2025
9
+ de.4.w, regionalliga-west-2024-2025
10
+ de.4.sw, regionalliga-suedwest-2024-2025
11
+ de.cup, dfb-pokal-2024-2025
12
+
13
+ at.1, aut-bundesliga-2024-2025
14
+ at.2, aut-2-liga-2024-2025
15
+ at.3.o, aut-regionalliga-ost-2024-2025
16
+ at.cup, aut-oefb-cup-2024-2025
17
+
18
+
19
+ ch.1, sui-super-league-2024-2025
20
+ ch.2, sui-challenge-league-2024-2025
21
+ ch.cup, sui-cup-2024-2025
22
+
23
+
24
+ hu.1, hun-nb-i-2024-2025
25
+
26
+ cz.1, cze-1-fotbalova-liga-2024-2025
27
+ cz.2, cze-2-fotbalova-liga-2024-2025
28
+ cz.3, cze-3-fotbalova-liga-2024-2025-cfl-a
29
+
30
+ sk.1, svk-super-liga-2024-2025
31
+
32
+ pl.1, pol-ekstraklasa-2024-2025
33
+
34
+
35
+
36
+ eng.1, eng-premier-league-2024-2025
37
+ eng.2, eng-championship-2024-2025
38
+ eng.3, eng-league-one-2024-2025
39
+ eng.4, eng-league-two-2024-2025
40
+ eng.5, eng-national-league-2024-2025
41
+ eng.cup, eng-fa-cup-2023-2024 ### update to 2024-2025 later!!!
42
+ eng.cup.l, eng-league-cup-2024-2025
43
+
44
+
45
+
46
+ sco.1, sco-premiership-2024-2025
47
+
48
+ ie.1, irl-premier-division-2024
49
+
50
+
51
+ fr.1, fra-ligue-1-2024-2025
52
+ fr.2, fra-ligue-2-2024-2025
53
+ fr.cup, fra-coupe-de-france-2023-2024 ### update to 2024-2025 later!!!
54
+
55
+
56
+ lu.1, lux-nationaldivision-2024-2025
57
+
58
+ nl.1, ned-eredivisie-2024-2025
59
+ nl.2, ned-eerste-divisie-2024-2025
60
+ nl.cup, ned-knvb-beker-2024-2025
61
+
62
+ be.1, bel-eerste-klasse-a-2024-2025
63
+ be.2, bel-eerste-klasse-b-2024-2025
64
+ be.cup, bel-beker-van-belgie-2024-2025
65
+
66
+
67
+ it.1, ita-serie-a-2024-2025
68
+ it.2, ita-serie-b-2024-2025
69
+ it.cup, ita-coppa-italia-2024-2025
70
+
71
+ pt.1, por-primeira-liga-2024-2025
72
+ pt.2, por-segunda-liga-2024-2025
73
+
74
+ es.1, esp-primera-division-2024-2025
75
+ es.2, esp-segunda-division-2024-2025
76
+ es.cup, esp-copa-del-rey-2023-2024 ## update to 2024-2025 later!!!
77
+
78
+
79
+ ro.1, rou-liga-1-2024-2025
80
+ ro.cup, rou-cupa-romaniei-2024-2025
81
+
82
+ ru.1, rus-premier-liga-2024-2025
83
+ ru.2, rus-premier-liga-2024-2025
84
+
85
+ ua.1, ukr-premyer-liga-2024-2025
86
+
87
+
88
+
89
+ tr.1, tur-sueperlig-2024-2025
90
+ tr.2, tur-1-lig-2024-2025
91
+
92
+ gr.1, gre-super-league-2024-2025
93
+
94
+ hr.1, cro-1-hnl-2024-2025
95
+ ba.1, bih-premier-liga-2024-2025
96
+
97
+ al.1, alb-kategoria-superiore-2024-2025
98
+
99
+
100
+ is.1, isl-urvalsdeild-2024
101
+
102
+ se.1, swe-allsvenskan-2024
103
+ se.2, swe-superettan-2024
104
+
105
+ no.1, nor-eliteserien-2024
106
+ fi.1, fin-veikkausliiga-2024-championship
107
+ dk.1, den-superliga-2024-2025
108
+
109
+
110
+
111
+
112
+ uefa.cl, champions-league-2024-2025
113
+ uefa.cl.q, champions-league-qual-2024-2025
114
+ uefa.el, europa-league-2024-2025
115
+ uefa.el.q, europa-league-qual-2024-2025
116
+ uefa.conf, conference-league-2024-2025
117
+ uefa.conf.q, europa-conference-league-qual-2024-2025
118
+
119
+ uefa.nl.a, nations-league-a-2024-2025
120
+ uefa.nl.b, nations-league-b-2024-2025
121
+ uefa.nl.c, nations-league-c-2024-2025
122
+ uefa.nl.d, nations-league-d-2024-2025
@@ -0,0 +1,5 @@
1
+ key, slug
2
+
3
+ il.1, isr-ligat-haal-2024-2025
4
+ il.2, isr-liga-leumit-2024-2025
5
+
@@ -0,0 +1,8 @@
1
+ key, slug
2
+
3
+
4
+ au.1, aus-a-league-2024-2025
5
+ au.cup, aus-australia-cup-2024
6
+
7
+ nz.1, nzl-national-league-2023
8
+
data/config/rounds.csv ADDED
@@ -0,0 +1,16 @@
1
+ key, name1, name2
2
+
3
+ *, 1. Runde, Round 1
4
+ *, 2. Runde, Round 2
5
+ *, 3. Runde, Round 3
6
+ *, 4. Runde, Round 4
7
+ *, 5. Runde, Round 5
8
+ *, 6. Runde, Round 6
9
+ *, 7. Runde, Round 7
10
+ *, 8. Runde, Round 8
11
+ *, 9. Runde, Round 9
12
+ *, Achtelfinale, Round of 16
13
+ *, Viertelfinale, Quarterfinals
14
+ *, Halbfinale, Semifinals
15
+ *, Finale, Final
16
+
data/config/stages.csv ADDED
@@ -0,0 +1,64 @@
1
+ key, name1, name2,
2
+
3
+ *, Meisterschaft, Playoffs - Championship
4
+ *, Abstieg, Playoffs - Relegation
5
+ *, Relegation, Playoffs - Relegation
6
+
7
+
8
+ sco.1, Championship, Playoffs - Championship
9
+ sco.1, Relegation', Playoffs - Relegation
10
+
11
+
12
+ at.1, Meistergruppe, Playoffs - Championship
13
+ at.1, Qualifikationsgruppe, Playoffs - Relegation
14
+ at.1, Playoff, Europa League Finals
15
+
16
+
17
+ pl.1, Playoffs, Playoffs - Championship
18
+ pl.2, Abstieg, Playoffs - Relegation
19
+
20
+
21
+ sk.1, Meisterschaft, Playoffs - Championship
22
+ sk.1, Abstieg, Playoffs - Relegation
23
+ sk.1, Europa League, Europa League Finals
24
+
25
+
26
+ ro.1, Championship, Playoffs - Championship
27
+ ro.1, Relegation, Playoffs - Relegation
28
+
29
+ ru.1, Meisterschaft, Playoffs - Championship
30
+ ru.1, Relegation, Playoffs - Relegation
31
+
32
+
33
+ ua.1, Meisterschaft, Playoffs - Championship
34
+ ua.1, Abstieg, Playoffs - Relegation
35
+ ua.1, Playoffs EL, Europa League Finals
36
+
37
+
38
+ fi.1, Meisterschaft, Playoffs - Championship
39
+ fi.1, Abstieg, Playoffs - Challenger
40
+ fi.1, Playoff EL, Europa League Finals
41
+
42
+ dk.1, Meisterschaft, Playoffs - Championship
43
+ dk.1, Abstieg, Playoffs - Relegation
44
+ dk.1, Europa League, Europa League Finals
45
+
46
+
47
+ gr.1, Meisterschaft, Playoffs - Championship
48
+ gr.1, Abstieg, Playoffs - Relegation
49
+ gr.1, Playoffs, Playoffs
50
+ gr.1, Spiel um Platz 6, Match 6th Place
51
+
52
+
53
+
54
+ mx.1, Apertura Playoffs, Apertura - Liguilla
55
+ mx.1, Clausura Playoffs, Clausura - Liguilla
56
+
57
+
58
+ kr.1, Meisterschaft, Playoffs - Championship
59
+ kr.1, Abstieg, Playoffs - Relegation
60
+
61
+
62
+ nz.1, Playoffs, Playoff Finals
63
+
64
+
@@ -2,21 +2,6 @@
2
2
  module Worldfootball
3
3
 
4
4
 
5
- ROUND_TO_EN = {
6
- '1. Runde' => 'Round 1',
7
- '2. Runde' => 'Round 2',
8
- '3. Runde' => 'Round 3',
9
- '4. Runde' => 'Round 4',
10
- '5. Runde' => 'Round 5',
11
- '6. Runde' => 'Round 6',
12
- '7. Runde' => 'Round 7',
13
- 'Achtelfinale' => 'Round of 16',
14
- 'Viertelfinale' => 'Quarterfinals',
15
- 'Halbfinale' => 'Semifinals',
16
- 'Finale' => 'Final',
17
- }
18
-
19
-
20
5
  ## todo/check: english league cup/trophy has NO ET - also support - make more flexible!!!
21
6
 
22
7
  ## build "standard" match records from "raw" table rows
@@ -24,13 +9,16 @@ def self.build( rows, season:, league:, stage: '' ) ## rename to fixup or such
24
9
  season = Season( season ) ## cast (ensure) season class (NOT string, integer, etc.)
25
10
 
26
11
  ## note: do NOT pass in league struct! pass in key (string)
27
- raise ArgumentError, "league key as string expected" unless league.is_a?(String)
12
+ raise ArgumentError, "league key as string expected" unless league.is_a?(String)
28
13
 
29
14
  print " #{rows.size} row(s) - Worldfootball.build #{league} #{season}"
30
15
  print " - #{stage}" unless stage.empty?
31
16
  print "\n"
32
17
 
33
18
 
19
+ zone = find_zone!( league: league, season: season )
20
+
21
+
34
22
  ## note: use only first part from key for lookup
35
23
  ## e.g. at.1 => at
36
24
  ## eng.1 => eng
@@ -61,39 +49,25 @@ def self.build( rows, season:, league:, stage: '' ) ## rename to fixup or such
61
49
  exit 1
62
50
  end
63
51
  print "\n"
64
-
65
- ## note - must start line e.g.
66
- ## do NOT match => Qual. 1. Runde (1. Runde)!!!
67
- elsif row[:round] =~ /^(
68
- [1-9]\.[ ]Runde|
69
- Achtelfinale|
70
- Viertelfinale|
71
- Halbfinale|
72
- Finale
73
- )$
74
- /x
52
+
53
+ ## note - must start line e.g.
54
+ ## do NOT match => Qual. 1. Runde (1. Runde)!!!
55
+ else
75
56
  puts
76
57
  print '[%03d] ' % (i+1)
77
58
  print row[:round]
78
59
 
79
- round = ROUND_TO_EN[ row[:round] ]
80
- print " => #{round}"
81
- print "\n"
60
+ round_new = map_round( row[:round], league: league, season: season )
82
61
 
83
- if round.nil?
84
- puts "!! ERROR: no mapping for round to english (en) found >#{row[:round]}<:"
62
+ if round_new
63
+ round = round_new
64
+ print " => #{round}"
65
+ print "\n"
66
+ else
67
+ round = row[:round]
68
+ puts "!! WARN: unknown round >#{row[:round]}< for league >#{league} #{season}<:"
85
69
  pp row
86
- exit 1
87
70
  end
88
- else
89
- puts
90
- print '[%03d] ' % (i+1)
91
- print row[:round]
92
- print "\n"
93
-
94
- puts "!! WARN: unknown round >#{row[:round]}< for league >#{league}<:"
95
- pp row
96
- round = row[:round]
97
71
  end
98
72
 
99
73
 
@@ -103,12 +77,10 @@ def self.build( rows, season:, league:, stage: '' ) ## rename to fixup or such
103
77
  team2_str = row[:team2]
104
78
  score_str = row[:score]
105
79
 
106
- ## convert date from string e.g. 2019-25-10
107
- date = Date.strptime( date_str, '%Y-%m-%d' )
108
80
 
109
81
 
110
82
  ### check for score_error; first (step 1) lookup by date
111
- score_error = score_errors[ date.strftime('%Y-%m-%d') ]
83
+ score_error = score_errors[ date_str ]
112
84
  if score_error
113
85
  if team1_str == score_error[0] &&
114
86
  team2_str == score_error[1]
@@ -145,17 +117,55 @@ def self.build( rows, season:, league:, stage: '' ) ## rename to fixup or such
145
117
  ht, ft, et, pen, comments = parse_score( score_str )
146
118
 
147
119
 
120
+ ###################
121
+ ### calculate date & times
122
+ ## convert date from string e.g. 2019-25-10
123
+ ## date = Date.strptime( date_str, '%Y-%m-%d' )
124
+
125
+ if time_str.nil? || time_str.empty?
126
+ ## no time
127
+ ## assume 00:00:00T
128
+ time_str = ''
129
+ timezone = ''
130
+ utc = ''
131
+ else
132
+ ## note - assume central european (summer) time (cet/cest) - UTC+1 or UTC+2
133
+ cet = CET.strptime( "#{date_str} #{time_str}", '%Y-%m-%d %H:%M' )
134
+
135
+ utc = cet.getutc ## convert to utc
136
+ local = zone.to_local( utc ) # convert to local via utc
137
+ ## overwrite old with local
138
+ date_str = local.strftime( '%Y-%m-%d' )
139
+ time_str = local.strftime( '%H:%M' )
140
+
141
+ ## pretty print timezone
142
+ ### todo/fix - bundle into fmt_timezone method or such for reuse
143
+ tz_abbr = local.strftime( '%Z' ) ## e.g. EEST or if not available +03 or such
144
+ tz_offset = local.strftime( '%z' ) ## e.g. +0300
145
+
146
+ timezone = if tz_abbr =~ /^[+-][0-9]+$/ ## only digits (no abbrev.)
147
+ tz_offset
148
+ else
149
+ "#{tz_abbr}/#{tz_offset}"
150
+ end
151
+
152
+ utc = utc.strftime( '%Y-%m-%dT%H:%MZ' )
153
+ end
154
+
155
+
148
156
  recs << [stage,
149
157
  round,
150
- date.strftime( '%Y-%m-%d' ),
158
+ date_str,
151
159
  time_str,
160
+ timezone,
152
161
  team1_str,
153
162
  ft,
154
163
  ht,
155
164
  team2_str,
156
165
  et, # extra: incl. extra time
157
166
  pen, # extra: incl. penalties
158
- comments]
167
+ comments,
168
+ utc]
159
169
  end # each row
160
170
  recs
161
171
  end # build
@@ -15,6 +15,14 @@ def self.convert( league:, season: )
15
15
  ## todo/fix: report error/check if stage is nil!!!
16
16
  stage ||= ''
17
17
 
18
+ ## try to map stage name if new name defined/found
19
+ unless stage.empty?
20
+ stage_new = map_stage( stage, league: league.key,
21
+ season: season )
22
+ stage = stage_new if stage_new
23
+ end
24
+
25
+
18
26
  print " parsing #{slug}..."
19
27
 
20
28
  # unless File.exist?( path )
@@ -37,9 +45,6 @@ def self.convert( league:, season: )
37
45
  end
38
46
 
39
47
 
40
- recs = fix_dates( recs, league: league.key )
41
-
42
-
43
48
  ## note: sort matches by date before saving/writing!!!!
44
49
  ## note: for now assume date in string in 1999-11-30 format (allows sort by "simple" a-z)
45
50
  ## note: assume date is third column!!! (stage/round/date/...)
@@ -60,63 +65,5 @@ recs.each do |rec|
60
65
  puts "write #{out_path}..."
61
66
  write_csv( out_path, recs, headers: headers )
62
67
  end
63
-
64
-
65
- ## helper to fix dates to use local timezone (and not utc/london time)
66
- def self.fix_dates( rows, league: )
67
-
68
- ## check: rename (optional) offset to time_offset or such?
69
- ## note - retry with league_country (e.g. eng.1 => eng etc.)
70
- offset = OFFSETS[ league ] ||
71
- OFFSETS[ league.split('.')[0] ]
72
-
73
- if offset.nil?
74
- puts "!! ERROR - no timezone/offset configured for league >#{league}<:"
75
- pp rows[0] ## print first row too (for dates etc.)
76
- exit 1
77
- end
78
-
79
-
80
- ## todo/check - rename offset to timezone
81
- ## or utc_offset or such - why? why not
82
-
83
- ## note - assume central european time (cet) - GMT/UTC+1
84
- ## e.g. offset = 1 for cet (and 0 for gmt/london) etc.
85
- diff_cet = offset-1
86
-
87
- return rows if diff_cet == 0 ## no need to convert if in cet
88
-
89
- rows.map { |row| _fix_date( row, offset ) }
90
- end
91
-
92
-
93
- def self._fix_date( row, offset )
94
- ## note: time (column) required for fix
95
- return row if row[3].nil? || row[3].empty?
96
-
97
- ## note - assume central european time (cet) - GMT/UTC+1
98
- diff_cet = offset-1
99
-
100
- return row if diff_cet == 0
101
-
102
-
103
-
104
- col = row[2]
105
- if col =~ /^\d{4}-\d{2}-\d{2}$/
106
- date_fmt = '%Y-%m-%d' # e.g. 2002-08-17
107
- else
108
- puts "!!! ERROR - wrong (unknown) date format >>#{col}<<; cannot continue; fix it; sorry"
109
- ## todo/fix: add to errors/warns list - why? why not?
110
- exit 1
111
- end
112
-
113
- date = DateTime.strptime( "#{row[2]} #{row[3]}", "#{date_fmt} %H:%M" )
114
- ## NOTE - MUST be -7/24.0!!!! or such to work
115
- date = date + (diff_cet/24.0)
116
-
117
- row[2] = date.strftime( date_fmt ) ## overwrite "old"
118
- row[3] = date.strftime( '%H:%M' )
119
- row ## return row for possible pipelining - why? why not?
120
- end
121
-
122
68
  end # module Worldfootball
69
+
@@ -51,12 +51,16 @@ class LeagueItem # nested inside LeagueConfig
51
51
  ## ["2019-2021 Playoffs", "regionalliga-bayern-2019-2021-playoffs"],
52
52
  ## ["2019-2021", "regionalliga-bayern-2019-2021"],
53
53
  ##
54
-
54
+ ##
55
+ ## ["1955/1958", "europa-league-1955-1958"]]
56
+ ## ["1958/1960", "uefa-cup-1958-1960"],
55
57
 
56
58
  season, stage = text.split( ' ', 2 )
57
59
 
58
60
  ## todo/fix: add a waring here and auto log to logs.txt!!!!
59
61
  next if season == '2019-2021'
62
+ next if season == '1958/1960'
63
+ next if season == '1955/1958'
60
64
 
61
65
  season = Season.parse( season )
62
66
 
@@ -73,7 +77,7 @@ class LeagueItem # nested inside LeagueConfig
73
77
  pages = pages( season: season )
74
78
  if pages.nil?
75
79
  puts "!! ERROR - no season #{season} found for #{key}; seasons incl:"
76
- pp seasons.keys
80
+ puts seasons.keys.join( ', ' )
77
81
  puts " #{seasons.keys.size} season(s)"
78
82
  exit 1
79
83
  end
@@ -116,11 +120,16 @@ end # class LeagueConfig
116
120
 
117
121
 
118
122
  LEAGUES = LeagueConfig.new
119
- recs = read_csv( "#{Worldfootball.root}/config/leagues.csv" )
120
- pp recs
121
- puts " #{recs.size} league(s)"
122
- LEAGUES.add( recs )
123
-
123
+ ['leagues_america',
124
+ 'leagues_asia',
125
+ 'leagues_europe',
126
+ 'leagues_middle_east',
127
+ 'leagues_pacific'].each do |name|
128
+ recs = read_csv( "#{Worldfootball.root}/config/#{name}.csv" )
129
+ pp recs
130
+ puts " #{recs.size} league(s) in #{name}"
131
+ LEAGUES.add( recs )
132
+ end
124
133
 
125
134
 
126
135
  ###########
@@ -130,7 +139,7 @@ def self.find_league!( league_code )
130
139
  league = LEAGUES[ league_code ]
131
140
  if league.nil?
132
141
  puts "!! ERROR - no config found for #{league_code}; leagues incl:"
133
- pp LEAGUES.keys
142
+ puts LEAGUES.keys.join( ', ' )
134
143
  puts " #{LEAGUES.size} leagues(s)"
135
144
  exit 1
136
145
  end
@@ -11,6 +11,19 @@ def self.norm_team( team )
11
11
  ## clean team name and asciify (e.g. ’->' )
12
12
  team = team.sub( '(old)', '' ).strip
13
13
  team = team.gsub( '’', "'" ) ## e.g. Hawke’s Bay United FC
14
+
15
+ ## Criciúma - SC => Criciúma - SC
16
+ ## Bahia - BA => Bahia - BA
17
+ ## remove inline dash ( - ) with single space
18
+ team = team.gsub( /[ ]+[-][ ]+/, ' ' )
19
+
20
+
21
+ ## todo:
22
+ ## replace (A) with II
23
+ ## Austria Wien (A) => Austria Wien (A)
24
+ ## others too? - move to mods instead of generic rule - why? why not?
25
+ team = team.sub( /[ ]+\(A\)/, ' II' )
26
+
14
27
  team
15
28
  end
16
29
 
@@ -71,8 +84,8 @@ SCORE_ERRORS = {
71
84
  },
72
85
  'at.cup' => {
73
86
  ## 2023/24
74
- '2023-07-22' => [ 'SV Leobendorf', 'SV Horn', ['3-2 (2-0, 2-2, 3-2) n.V.', '3-2 (2-0, 2-2) n.V.']],
75
- },
87
+ '2023-07-22' => [ 'SV Leobendorf', 'SV Horn', ['3-2 (2-0, 2-2, 3-2) n.V.', '3-2 (2-0, 2-2) n.V.']],
88
+ },
76
89
  }
77
90
 
78
91
 
@@ -106,7 +106,7 @@ end
106
106
  def log( msg ) ### append to log
107
107
  File.open( './logs.txt', 'a:utf-8' ) do |f|
108
108
  f.write( msg )
109
- f.write( "\n" )
109
+ f.write( "\n" )
110
110
  end
111
111
  end
112
112
 
@@ -0,0 +1,47 @@
1
+
2
+
3
+ module Worldfootball
4
+
5
+ def self.map_stage( stage, league:, season: )
6
+ @stages ||= begin
7
+ stages = {}
8
+ recs = read_csv( "#{Worldfootball.root}/config/stages.csv" )
9
+ recs.each do |rec|
10
+ stages[ rec['key'] ] ||= Hash.new
11
+ stages[ rec['key'] ][ rec['name1'] ] = rec['name2']
12
+ end
13
+ stages
14
+ end
15
+
16
+ ## pp @stages
17
+
18
+ league_code = league.to_s.downcase
19
+
20
+ name = nil
21
+ name = @stages[league_code][ stage ] if @stages.has_key?( league_code )
22
+ name = @stages['*'][stage] if name.nil? ## try generic (*) lookup
23
+ name
24
+ end
25
+
26
+
27
+ def self.map_round( round, league:, season: )
28
+ @rounds ||= begin
29
+ rounds = {}
30
+ recs = read_csv( "#{Worldfootball.root}/config/rounds.csv" )
31
+ recs.each do |rec|
32
+ rounds[ rec['key'] ] ||= Hash.new
33
+ rounds[ rec['key'] ][ rec['name1'] ] = rec['name2']
34
+ end
35
+ rounds
36
+ end
37
+
38
+ ## pp @stages
39
+
40
+ league_code = league.to_s.downcase
41
+
42
+ name = nil
43
+ name = @rounds[league_code][ round ] if @rounds.has_key?( league_code )
44
+ name = @rounds['*'][round] if name.nil? ## try generic (*) lookup
45
+ name
46
+ end
47
+ end # module Worldfootball
@@ -6,13 +6,15 @@ MAX_HEADERS = [
6
6
  'Round',
7
7
  'Date',
8
8
  'Time',
9
+ 'Timezone',
9
10
  'Team 1',
10
11
  'FT',
11
12
  'HT',
12
13
  'Team 2',
13
14
  'ET',
14
15
  'P',
15
- 'Comments'] ## e.g. awarded, cancelled/canceled, etc.
16
+ 'Comments', ## e.g. awarded, cancelled/canceled, etc.
17
+ 'UTC']
16
18
 
17
19
  MIN_HEADERS = [ ## always keep even if all empty
18
20
  'Date',
@@ -1,8 +1,8 @@
1
1
 
2
2
  module Worldfootball
3
3
  MAJOR = 0 ## todo: namespace inside version or something - why? why not??
4
- MINOR = 1
5
- PATCH = 2
4
+ MINOR = 2
5
+ PATCH = 1
6
6
  VERSION = [MAJOR,MINOR,PATCH].join('.')
7
7
 
8
8
  def self.version
data/lib/worldfootball.rb CHANGED
@@ -1,19 +1,17 @@
1
1
  ## 3rd party (our own)
2
- require 'season/formats' ## add season support
3
- require 'webget' ## incl. webget, webcache, webclient, etc.
4
-
5
- require 'cocos'
6
-
7
- ## 3rd party
2
+ require 'football/timezones' ## note - pulls in season/formats, cocos & tzinfo
3
+ require 'webget' ## incl. webget, webcache, webclient, etc.
8
4
  require 'nokogiri'
9
5
 
10
6
 
11
-
12
7
  ###
13
8
  # our own code
14
9
  require_relative 'worldfootball/version'
15
10
  require_relative 'worldfootball/leagues'
16
- require_relative 'worldfootball/config' ## rename to setup/timezones/layouts or such?
11
+ require_relative 'worldfootball/stages'
12
+
13
+
14
+
17
15
  require_relative 'worldfootball/download'
18
16
  require_relative 'worldfootball/page'
19
17
  require_relative 'worldfootball/page_schedule'
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: worldfootball
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.1
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-09 00:00:00.000000000 Z
11
+ date: 2024-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: season-formats
14
+ name: football-timezones
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -52,20 +52,6 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: cocos
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
55
  - !ruby/object:Gem::Dependency
70
56
  name: rdoc
71
57
  requirement: !ruby/object:Gem::Requirement
@@ -116,12 +102,17 @@ files:
116
102
  - README.md
117
103
  - Rakefile
118
104
  - bin/wfb
119
- - config/leagues.csv
105
+ - config/leagues_america.csv
106
+ - config/leagues_asia.csv
107
+ - config/leagues_europe.csv
108
+ - config/leagues_middle_east.csv
109
+ - config/leagues_pacific.csv
110
+ - config/rounds.csv
111
+ - config/stages.csv
120
112
  - lib/worldfootball.rb
121
113
  - lib/worldfootball/build-parse_score.rb
122
114
  - lib/worldfootball/build.rb
123
115
  - lib/worldfootball/cache.rb
124
- - lib/worldfootball/config.rb
125
116
  - lib/worldfootball/convert.rb
126
117
  - lib/worldfootball/convert_reports.rb
127
118
  - lib/worldfootball/download.rb
@@ -130,6 +121,7 @@ files:
130
121
  - lib/worldfootball/page.rb
131
122
  - lib/worldfootball/page_report.rb
132
123
  - lib/worldfootball/page_schedule.rb
124
+ - lib/worldfootball/stages.rb
133
125
  - lib/worldfootball/vacuum.rb
134
126
  - lib/worldfootball/version.rb
135
127
  homepage: https://github.com/sportdb/sport.db
data/config/leagues.csv DELETED
@@ -1,16 +0,0 @@
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
-
16
-
@@ -1,220 +0,0 @@
1
- module Worldfootball
2
-
3
- #################
4
- # todo/fix - use timezone instead of offset !!!
5
- # e.g
6
- =begin
7
- TIMEZONES = {
8
- 'eng.1' => 'Europe/London',
9
- 'eng.2' => 'Europe/London',
10
-
11
- 'es.1' => 'Europe/Madrid',
12
-
13
- 'de.1' => 'Europe/Berlin',
14
- 'fr.1' => 'Europe/Paris',
15
- 'it.1' => 'Europe/Rome',
16
- 'nl.1' => 'Europe/Amsterdam',
17
-
18
- 'pt.1' => 'Europe/Lisbon',
19
-
20
- ## todo/fix - pt.1
21
- ## one team in madeira!!! check for different timezone??
22
- ## CD Nacional da Madeira
23
-
24
- 'br.1' => 'America/Sao_Paulo',
25
- ## todo/fix - brazil has 4 timezones
26
- ## really only two in use for clubs
27
- ## west and east (amazonas et al)
28
- ## for now use west for all - why? why not?
29
- }
30
- =end
31
-
32
- ## todo - find "proper/classic" timezone ("winter time")
33
-
34
- ## Brasilia - Distrito Federal, Brasil (GMT-3) -- summer time?
35
- ## Ciudad de México, CDMX, México (GMT-5) -- summer time?
36
- ## Londres, Reino Unido (GMT+1)
37
- ## Madrid -- ?
38
- ## Lisboa -- ?
39
- ## Moskow -- ?
40
- ##
41
- ## todo/check - quick fix timezone offsets for leagues for now
42
- ## - find something better - why? why not?
43
- ## note: assume time is in GMT/UTC+1 - PLUS SUMMERTIME!!!
44
- ## todo/fix - consider summertime before conversion too!!!
45
-
46
-
47
- OFFSETS = {
48
-
49
- ## fix - change to gmt/utc offset
50
- ## if offset == 1 (GMT/UTC+1)
51
- ## do NOTHING (default date/timezone of pages)
52
-
53
- 'eng' => 0,
54
- # 'eng.1' => 0,
55
- # 'eng.2' => 0,
56
- # 'eng.3' => 0,
57
- # 'eng.4' => 0,
58
- # 'eng.5' => 0,
59
-
60
- 'ie' => 0,
61
- 'sco' => 0,
62
-
63
- 'pt' => 0,
64
- # 'pt.1' => 0,
65
- # 'pt.2' => 0,
66
-
67
- 'fi' => 2, # +2
68
- 'gr' => 2, # +2
69
- 'ro' => 2, # +2
70
- 'ua' => 2, # +2
71
-
72
- 'ru' => 3, # +3
73
- 'tr' => 3, # +3 turkey time/moscow time
74
-
75
-
76
- 'us' => -5, # (gmt-5) new york
77
-
78
- 'mx' => -6,
79
- # 'mx.1' => -6,
80
- # 'mx.2' => -6,
81
- # 'mx.3' => -6,
82
- # 'mx.cup' => -6,
83
-
84
- 'cr' => -6, # gmt-6
85
- 'gt' => -6, # gmt-6
86
- 'hn' => -6, # gmt-6
87
- 'sv' => -6, # gmt-6
88
- 'ni' => -6, # gmt-6
89
-
90
- 'uy' => -3, # gmt-3
91
- 'pe' => -5, # gmt-5
92
- 'ec' => -5, # gmt-5
93
- 'co' => -5, # gmt-5
94
- 'bo' => -4, # gmt-4
95
- 'cl' => -4, # gmt-4
96
-
97
- 'br' => -4, # gmt-3 - change to -3?
98
- # 'br.1' => -4,
99
- 'ar' => -4, # gmt-3 - change to -3?
100
- # 'ar.1' => -4,
101
-
102
-
103
- 'eg' => 3, # +3 (gmt+3)
104
- 'jp' => 9, # +9 (gmt+9)
105
- 'cn' => 7, # +7 (gmt+7)
106
-
107
-
108
- ## note - central european time (cet) - no need for date auto-fix
109
- 'at' => 1,
110
- 'de' => 1,
111
- 'ch' => 1,
112
- 'hu' => 1,
113
- 'cz' => 1,
114
- 'pl' => 1,
115
- 'nl' => 1,
116
- 'lu' => 1,
117
- 'be' => 1,
118
- 'dk' => 1,
119
- 'se' => 1,
120
- 'it' => 1,
121
- 'fr' => 1,
122
- 'es' => 1,
123
- ## see https://en.wikipedia.org/wiki/Time_in_Europe
124
-
125
-
126
- ################
127
- ## int'l tournaments
128
- # 'uefa.cl'
129
- # 'uefa.el'
130
- 'uefa.cl' => 1,
131
- 'uefa.el' => 1,
132
-
133
- 'concacaf.cl' => -6, ### use mx time
134
- 'copa.l' => -4, ### use brazil time
135
- }
136
-
137
-
138
- ####
139
- # config for slug to local basename / directories
140
- # e.g.
141
- # aut-bundesliga-2023-2024 => austria/2023-24/1_bundesliga.txt
142
-
143
-
144
- ## add (timezone) offset here too - why? why not?
145
- LEAGUE_SETUPS = {
146
- ## note - for now auto-generate path via name (downcased)
147
- ## e.g. Belgium => /belgium
148
-
149
- ## top five (europe)
150
- 'eng' => { code: 'eng', name: 'England' },
151
- 'es' => { code: 'esp', name: 'Spain' },
152
- # 'fr' => { code: 'fra', name: 'France' },
153
- # 'de' => { code: '???', name: 'Germany' },
154
- 'it' => { code: 'ita', name: 'Italy' },
155
-
156
-
157
- 'be' => { code: 'bel', name: 'Belgium' },
158
- 'at' => { code: 'aut', name: 'Austria' },
159
- 'hu' => { code: 'hun', name: 'Hungary' },
160
-
161
- 'tr' => { code: 'tur', name: 'Turkey' },
162
- 'nl' => { code: 'ned', name: 'Netherlands' },
163
- 'ch' => { code: 'sui', name: 'Switzerland' },
164
-
165
-
166
- 'cz' => { code: 'cze', name: 'Czech Republic' },
167
- 'dk' => { code: 'den', name: 'Denmark' },
168
- 'fi' => { code: 'fin', name: 'Finland' },
169
- 'gr' => { code: 'gre', name: 'Greece' },
170
-
171
- 'ie' => { code: 'irl', name: 'Ireland' },
172
- 'sco' => { code: 'sco', name: 'Scotland' },
173
-
174
- 'lu' => { code: 'lux', name: 'Luxembourg' },
175
- 'pl' => { code: 'pol', name: 'Poland' },
176
- 'pt' => { code: 'por', name: 'Portugal' },
177
- 'ro' => { code: 'rou', name: 'Romania' },
178
- 'ru' => { code: 'rus', name: 'Russia' },
179
- 'se' => { code: 'swe', name: 'Sweden' },
180
- 'ua' => { code: 'ukr', name: 'Ukraine' },
181
-
182
-
183
- 'eg' => { code: 'egy', name: 'Egypt' },
184
- 'jp' => { code: 'jpn', name: 'Japan' },
185
- 'cn' => { code: 'chn', name: 'China' },
186
-
187
- ## note - for now do NOT add United States to league name
188
- ## e.g. 1 - Major League Soccer
189
- ## 2 - USL Championship
190
- ## cup - U.S. Open Cup
191
- 'us' => { code: 'usa', name: nil, path: 'united-states' },
192
-
193
- 'mx' => { code: 'mex', name: 'Mexico' },
194
- 'ar' => { code: 'arg', name: 'Argentina' },
195
- 'br' => { code: 'bra', name: 'Brazil' },
196
-
197
- 'uy' => { code: 'uru', name: 'Uruguay' },
198
- 'pe' => { code: 'per', name: 'Peru' },
199
- 'ec' => { code: 'ecu', name: 'Ecuador' },
200
- 'bo' => { code: 'bol', name: 'Bolivia' },
201
- 'cl' => { code: 'chi', name: 'Chile' },
202
- 'co' => { code: 'col', name: 'Colombia' },
203
-
204
- 'cr' => { code: 'crc', name: 'Costa Rica' },
205
- 'gt' => { code: 'gua', name: 'Guatemala' },
206
- 'hn' => { code: 'hon', name: 'Honduras' },
207
- 'sv' => { code: 'slv', name: 'El Salvador' },
208
- 'ni' => { code: 'nca', name: 'Nicaragua' },
209
-
210
-
211
- ## int'l tournaments
212
- 'uefa.cl' => { code: nil, name: 'UEFA', path: 'europe' },
213
- 'uefa.el' => { code: nil, name: 'UEFA', path: 'europe' },
214
- 'concacaf.cl' => { code: nil, name: nil, path: 'north-america' },
215
- 'copa.l' => { code: nil, name: nil, path: 'south-america' },
216
- }
217
-
218
-
219
-
220
- end # module Worldfootball