leagues 0.1.0
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 +7 -0
- data/CHANGELOG.md +6 -0
- data/Manifest.txt +19 -0
- data/README.md +25 -0
- data/Rakefile +32 -0
- data/config/codes_alt.csv +61 -0
- data/config/leagues.csv +423 -0
- data/config/leagues_more.csv +40 -0
- data/config/timezones_africa.csv +21 -0
- data/config/timezones_america.csv +41 -0
- data/config/timezones_asia.csv +9 -0
- data/config/timezones_europe.csv +98 -0
- data/config/timezones_middle_east.csv +5 -0
- data/config/timezones_pacific.csv +5 -0
- data/config/timezones_world.csv +45 -0
- data/lib/leagues/league_codes.rb +169 -0
- data/lib/leagues/leagueset.rb +185 -0
- data/lib/leagues/timezones.rb +195 -0
- data/lib/leagues/version.rb +24 -0
- data/lib/leagues.rb +63 -0
- metadata +142 -0
@@ -0,0 +1,195 @@
|
|
1
|
+
####
|
2
|
+
### check - nest CET class inside UTC e.g. UTC::CET - why? why not?
|
3
|
+
## make UTC and CET into a module (not class) - why? why not?
|
4
|
+
|
5
|
+
module CET ## central european time helpers
|
6
|
+
def self.now() zone.now; end
|
7
|
+
def self.today() now.to_date; end
|
8
|
+
def self.strptime( str, format )
|
9
|
+
|
10
|
+
### fix - change to Time.strptime - why? why not?
|
11
|
+
## (simply) ignore offset; double check that hours, minutes
|
12
|
+
## get parsed as is (without applying offset)
|
13
|
+
|
14
|
+
d = DateTime.strptime( str, format )
|
15
|
+
## remove assert check - why? why not?
|
16
|
+
if d.zone != '+00:00' ### use d.offset != Ration(0,1) - why? why not?
|
17
|
+
puts "!! ASSERT - CET parse date; DateTime returns offset != +0:00"
|
18
|
+
pp d.zone
|
19
|
+
pp d
|
20
|
+
exit 1
|
21
|
+
end
|
22
|
+
|
23
|
+
### 2006-03-26 02:00:00
|
24
|
+
## raise exception
|
25
|
+
## is an invalid local time. (TZInfo::PeriodNotFound)
|
26
|
+
## quick fix add +1
|
27
|
+
## 2012-03-25 02:00:00
|
28
|
+
## is an invalid local time. (TZInfo::PeriodNotFound)
|
29
|
+
|
30
|
+
if ['2018-03-25 02:00',
|
31
|
+
'2012-03-25 02:00',
|
32
|
+
'2006-03-26 02:00',
|
33
|
+
].include?( d.strftime( '%Y-%m-%d %H:%M' ))
|
34
|
+
puts "!! hack - fix CET date #{d} - add +1 hour"
|
35
|
+
pp d
|
36
|
+
zone.local_time( d.year, d.month, d.day, d.hour+1, d.min, d.sec )
|
37
|
+
else
|
38
|
+
zone.local_time( d.year, d.month, d.day, d.hour, d.min, d.sec )
|
39
|
+
end
|
40
|
+
end
|
41
|
+
def self.zone() @zone ||= UTC.find_zone( 'Europe/Vienna' ); end
|
42
|
+
end # class CET
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
module UTC
|
47
|
+
def self.now() Time.now.utc; end
|
48
|
+
def self.today() now.to_date; end
|
49
|
+
|
50
|
+
## -- todo - make sure / assert it's always utc - how???
|
51
|
+
## utc = ## tz_utc.strptime( m['utcDate'], '%Y-%m-%dT%H:%M:%SZ' )
|
52
|
+
## note: DateTime.strptime is supposed to be unaware of timezones!!!
|
53
|
+
## use to parse utc
|
54
|
+
## quick hack -
|
55
|
+
## use to_time.getutc instead of utc ???
|
56
|
+
def self.strptime( str, format )
|
57
|
+
d = DateTime.strptime( str, format )
|
58
|
+
## remove assert check - why? why not?
|
59
|
+
if d.zone != '+00:00' ### use d.offset != Ration(0,1) - why? why not?
|
60
|
+
puts "!! ASSERT - UTC parse date; DateTime returns offset != +0:00"
|
61
|
+
pp d.zone
|
62
|
+
pp d
|
63
|
+
exit 1
|
64
|
+
end
|
65
|
+
## note - ignores offset if any !!!!
|
66
|
+
## todo/check - report warn if offset different from 0:00 (0/1) - why? why not?
|
67
|
+
Time.utc( d.year, d.month, d.day, d.hour, d.min, d.sec )
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.find_zone( name )
|
71
|
+
zone = TZInfo::Timezone.get( name )
|
72
|
+
## wrap tzinfo timezone in our own - for adding more (auto)checks etc.
|
73
|
+
zone ? Timezone.new( zone ) : nil
|
74
|
+
end
|
75
|
+
|
76
|
+
class Timezone ## nested inside UTC
|
77
|
+
## todo/fix
|
78
|
+
## cache timezone - why? why not?
|
79
|
+
def initialize( zone )
|
80
|
+
@zone = zone
|
81
|
+
end
|
82
|
+
|
83
|
+
def name() @zone.name; end
|
84
|
+
def dst?() @zone.dst?; end
|
85
|
+
|
86
|
+
|
87
|
+
def to_local( time )
|
88
|
+
## assert time is Time (not Date or DateTIme)
|
89
|
+
## and assert utc!!!
|
90
|
+
assert( time.is_a?( Time ), "time #{time} is NOT of class Time; got #{time.class.name}" )
|
91
|
+
assert( time.utc?, "time #{time} is NOT utc; utc? returns #{time.utc?}" )
|
92
|
+
local = @zone.to_local( time )
|
93
|
+
local
|
94
|
+
end
|
95
|
+
|
96
|
+
def local_time( year, month=1, mday=1, hour=0, min=0, sec=0 )
|
97
|
+
## add auto-fix for ambigious time (dst vs non-dst)
|
98
|
+
## always select first for now (that is, dst)
|
99
|
+
@zone.local_time( year, month, mday, hour, min, sec ) {|time| time.first }
|
100
|
+
end
|
101
|
+
|
102
|
+
def now() @zone.now; end
|
103
|
+
|
104
|
+
|
105
|
+
|
106
|
+
|
107
|
+
def assert( cond, msg )
|
108
|
+
if cond
|
109
|
+
# do nothing
|
110
|
+
else
|
111
|
+
puts "!!! assert failed - #{msg}"
|
112
|
+
exit 1
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end # class Timezone
|
116
|
+
end # module UTC
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
|
121
|
+
module TimezoneHelper
|
122
|
+
|
123
|
+
def find_zone!( league:, season: )
|
124
|
+
zone = find_zone( league: league, season: season )
|
125
|
+
if zone.nil? ## still not found; report error
|
126
|
+
puts "!! ERROR: no timezone found for #{league} #{season}"
|
127
|
+
exit 1
|
128
|
+
end
|
129
|
+
zone
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
def find_zone( league:, season: )
|
134
|
+
## note: do NOT pass in league struct! pass in key (string)
|
135
|
+
raise ArgumentError, "league code as string|symbol expected" unless league.is_a?(String) || league.is_a?(Symbol)
|
136
|
+
|
137
|
+
@zones ||= begin
|
138
|
+
zones = {}
|
139
|
+
['timezones_africa',
|
140
|
+
'timezones_america',
|
141
|
+
'timezones_asia',
|
142
|
+
'timezones_europe',
|
143
|
+
'timezones_middle_east',
|
144
|
+
'timezones_pacific',
|
145
|
+
'timezones_world',].each do |name|
|
146
|
+
recs = read_csv( "#{SportDb::Module::Leagues.root}/config/#{name}.csv" )
|
147
|
+
recs.each do |rec|
|
148
|
+
zone = UTC.find_zone( rec['zone'] )
|
149
|
+
if zone.nil?
|
150
|
+
## raise ArgumentError - invalid zone
|
151
|
+
puts "!! ERROR - cannot find timezone in timezone db:"
|
152
|
+
pp rec
|
153
|
+
exit 1
|
154
|
+
end
|
155
|
+
## todo/fix - rename key to (league) code
|
156
|
+
zones[ rec['key']] = zone
|
157
|
+
end
|
158
|
+
end
|
159
|
+
zones
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
###
|
164
|
+
## map code here - why? why not?
|
165
|
+
## or (always) require canoncial code???
|
166
|
+
season = Season( season )
|
167
|
+
league_info = LeagueCodes.find_by( code: league, season: season )
|
168
|
+
|
169
|
+
league_code = if league_info
|
170
|
+
## lookup first try by league+season
|
171
|
+
league_info['code'] ## use canonical name
|
172
|
+
else
|
173
|
+
## fallback; no league found
|
174
|
+
## or report error in the future - why? why not?
|
175
|
+
league.to_s.downcase
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
## e.g. world+2022, etc.
|
180
|
+
key = "#{league_code}+#{season}"
|
181
|
+
zone = @zones[key]
|
182
|
+
|
183
|
+
## try league e.g. eng.1 etc.
|
184
|
+
zone = @zones[league_code] if zone.nil?
|
185
|
+
|
186
|
+
## try first code only (country code )
|
187
|
+
if zone.nil?
|
188
|
+
code, _ = league_code.split( '.', 2 )
|
189
|
+
zone = @zones[code]
|
190
|
+
end
|
191
|
+
|
192
|
+
zone
|
193
|
+
end
|
194
|
+
end # module TimezoneHelper
|
195
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
|
2
|
+
module SportDb
|
3
|
+
module Module
|
4
|
+
module Leagues
|
5
|
+
MAJOR = 0 ## todo: namespace inside version or something - why? why not??
|
6
|
+
MINOR = 1
|
7
|
+
PATCH = 0
|
8
|
+
VERSION = [MAJOR,MINOR,PATCH].join('.')
|
9
|
+
|
10
|
+
def self.version
|
11
|
+
VERSION
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.banner
|
15
|
+
"leagues/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}] in (#{root})"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.root
|
19
|
+
File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )
|
20
|
+
end
|
21
|
+
|
22
|
+
end # module Leagues
|
23
|
+
end # module Module
|
24
|
+
end # module SportDb
|
data/lib/leagues.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'cocos'
|
2
|
+
require 'season/formats' ## add season support
|
3
|
+
|
4
|
+
|
5
|
+
require 'tzinfo'
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
## our own code
|
11
|
+
require_relative 'leagues/version'
|
12
|
+
require_relative 'leagues/league_codes'
|
13
|
+
|
14
|
+
require_relative 'leagues/leagueset'
|
15
|
+
|
16
|
+
require_relative 'leagues/timezones'
|
17
|
+
|
18
|
+
|
19
|
+
###
|
20
|
+
## note - make LeagueCodes "global" by default for now - why? why not?
|
21
|
+
LeagueCodes = SportDb::LeagueCodes
|
22
|
+
Leagueset = SportDb::Leagueset
|
23
|
+
#### add alias - why? why not?
|
24
|
+
LeagueSet = Leagueset
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
module LeaguesetHelper
|
29
|
+
###
|
30
|
+
### note - make read_leagueset & friends public/global by default - why? why not?
|
31
|
+
def read_leagueset( path ) Leagueset.read( path ); end
|
32
|
+
def parse_leagueset( txt ) Leagueset.parse( txt ); end
|
33
|
+
def parse_leagueset_args( args ) Leagueset.parse_args( args ); end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
module FileHelper
|
39
|
+
def find_file( filename, path: )
|
40
|
+
path.each do |src_dir|
|
41
|
+
path = "#{src_dir}/#{filename}"
|
42
|
+
return path if File.exist?( path )
|
43
|
+
end
|
44
|
+
|
45
|
+
## fix - raise file not found error!!!
|
46
|
+
nil ## not found - raise filenot found error - why? why not?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
####
|
53
|
+
### note - make find_zone! public/global by default - why? why not?
|
54
|
+
module Kernel
|
55
|
+
include FileHelper
|
56
|
+
include LeaguesetHelper
|
57
|
+
include TimezoneHelper
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
puts SportDb::Module::Leagues.banner ## say hello
|
metadata
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: leagues
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gerald Bauer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-04-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: tzinfo
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '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'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: season-formats
|
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'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: cocos
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rdoc
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '4.0'
|
62
|
+
- - "<"
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '7'
|
65
|
+
type: :development
|
66
|
+
prerelease: false
|
67
|
+
version_requirements: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '4.0'
|
72
|
+
- - "<"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '7'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: hoe
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '4.2'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '4.2'
|
89
|
+
description: leagues - football leagues & timezone helpers
|
90
|
+
email: gerald.bauer@gmail.com
|
91
|
+
executables: []
|
92
|
+
extensions: []
|
93
|
+
extra_rdoc_files:
|
94
|
+
- CHANGELOG.md
|
95
|
+
- Manifest.txt
|
96
|
+
- README.md
|
97
|
+
files:
|
98
|
+
- CHANGELOG.md
|
99
|
+
- Manifest.txt
|
100
|
+
- README.md
|
101
|
+
- Rakefile
|
102
|
+
- config/codes_alt.csv
|
103
|
+
- config/leagues.csv
|
104
|
+
- config/leagues_more.csv
|
105
|
+
- config/timezones_africa.csv
|
106
|
+
- config/timezones_america.csv
|
107
|
+
- config/timezones_asia.csv
|
108
|
+
- config/timezones_europe.csv
|
109
|
+
- config/timezones_middle_east.csv
|
110
|
+
- config/timezones_pacific.csv
|
111
|
+
- config/timezones_world.csv
|
112
|
+
- lib/leagues.rb
|
113
|
+
- lib/leagues/league_codes.rb
|
114
|
+
- lib/leagues/leagueset.rb
|
115
|
+
- lib/leagues/timezones.rb
|
116
|
+
- lib/leagues/version.rb
|
117
|
+
homepage: https://github.com/sportdb/sport.db
|
118
|
+
licenses:
|
119
|
+
- Public Domain
|
120
|
+
metadata: {}
|
121
|
+
post_install_message:
|
122
|
+
rdoc_options:
|
123
|
+
- "--main"
|
124
|
+
- README.md
|
125
|
+
require_paths:
|
126
|
+
- lib
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 3.1.0
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
requirements: []
|
138
|
+
rubygems_version: 3.5.22
|
139
|
+
signing_key:
|
140
|
+
specification_version: 4
|
141
|
+
summary: leagues - football leagues & timezone helpers
|
142
|
+
test_files: []
|