sportdb-config 0.0.1
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/HISTORY.md +3 -0
- data/Manifest.txt +65 -0
- data/README.md +27 -0
- data/Rakefile +26 -0
- data/config/geos/eng.txt +162 -0
- data/config/leagues/eng.txt +40 -0
- data/config/leagues/fr.txt +9 -0
- data/config/leagues/gr.txt +7 -0
- data/config/leagues/sco.txt +19 -0
- data/config/teams/al.txt +6 -0
- data/config/teams/at.txt +26 -0
- data/config/teams/be.txt +58 -0
- data/config/teams/bg.txt +6 -0
- data/config/teams/by.txt +5 -0
- data/config/teams/ca.txt +4 -0
- data/config/teams/ch.txt +10 -0
- data/config/teams/cy.txt +7 -0
- data/config/teams/cz.txt +6 -0
- data/config/teams/de.txt +129 -0
- data/config/teams/dk.txt +6 -0
- data/config/teams/eng.txt +294 -0
- data/config/teams/es.txt +148 -0
- data/config/teams/fi.txt +6 -0
- data/config/teams/fr.txt +98 -0
- data/config/teams/ga.txt +5 -0
- data/config/teams/gr.txt +87 -0
- data/config/teams/hr.txt +9 -0
- data/config/teams/hu.txt +5 -0
- data/config/teams/ie.txt +5 -0
- data/config/teams/is.txt +6 -0
- data/config/teams/it.txt +99 -0
- data/config/teams/lu.txt +6 -0
- data/config/teams/mc.txt +4 -0
- data/config/teams/md.txt +4 -0
- data/config/teams/mt.txt +6 -0
- data/config/teams/mx.txt +30 -0
- data/config/teams/nir.txt +6 -0
- data/config/teams/nl.txt +45 -0
- data/config/teams/no.txt +7 -0
- data/config/teams/pl.txt +6 -0
- data/config/teams/pt.txt +53 -0
- data/config/teams/ro.txt +5 -0
- data/config/teams/rs.txt +6 -0
- data/config/teams/ru.txt +5 -0
- data/config/teams/sco.txt +73 -0
- data/config/teams/se.txt +6 -0
- data/config/teams/si.txt +5 -0
- data/config/teams/sk.txt +5 -0
- data/config/teams/tr.txt +39 -0
- data/config/teams/ua.txt +5 -0
- data/config/teams/us.txt +44 -0
- data/config/teams/wal.txt +16 -0
- data/lib/sportdb/config.rb +26 -0
- data/lib/sportdb/config/config.rb +77 -0
- data/lib/sportdb/config/league.rb +118 -0
- data/lib/sportdb/config/league_reader.rb +65 -0
- data/lib/sportdb/config/structs/team.rb +45 -0
- data/lib/sportdb/config/team_reader.rb +108 -0
- data/lib/sportdb/config/utils/league_utils.rb +24 -0
- data/lib/sportdb/config/utils/season_utils.rb +116 -0
- data/lib/sportdb/config/version.rb +35 -0
- data/test/helper.rb +10 -0
- data/test/test_config.rb +19 -0
- data/test/test_league_utils.rb +90 -0
- data/test/test_season_utils.rb +29 -0
- metadata +189 -0
@@ -0,0 +1,118 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module SportDb
|
4
|
+
module Import
|
5
|
+
|
6
|
+
|
7
|
+
class LeagueConfig ## use LeagueInfo or LeagueMap or LeagueHash or similar
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
|
11
|
+
## just use leagues without latest for latest - why? why not?
|
12
|
+
@leagues_latest = {
|
13
|
+
'es' => { '1' => 'liga', # spanish liga 1
|
14
|
+
'2' => 'liga2', # spanish liga 2
|
15
|
+
},
|
16
|
+
'it' => { '1' => 'seriea', # italian serie a
|
17
|
+
'2' => 'serieb', # italian serie b
|
18
|
+
},
|
19
|
+
'de' => { '1' => 'bundesliga', # german bundesliga
|
20
|
+
'2' => 'bundesliga2', # german 2. bundesliga
|
21
|
+
},
|
22
|
+
'nl' => { '1' => 'eredivisie' }, # dutch eredivisie
|
23
|
+
'be' => { '1' => 'proleague' }, # belgian pro league
|
24
|
+
'pt' => { '1' => 'liga' }, # portugese Primeira Liga
|
25
|
+
'tr' => { '1' => 'superlig' }, # turkish Süper Lig
|
26
|
+
|
27
|
+
# note: eng now read from txt
|
28
|
+
# 'eng' => { '1' => 'premierleague', # english premier league
|
29
|
+
# '2' => 'championship', # english championship league
|
30
|
+
# '3' => 'league1', # english league 1
|
31
|
+
# },
|
32
|
+
}
|
33
|
+
|
34
|
+
## change history to past or changes/changelog something - why? why not?
|
35
|
+
@leagues_history = {
|
36
|
+
|
37
|
+
# note: eng now read from txt
|
38
|
+
# 'eng' => {
|
39
|
+
# ## until (including) 2003-04 season
|
40
|
+
# '2003-04' => { '1' => 'premierleague', # english premier league
|
41
|
+
# '2' => 'division1', # english division 1
|
42
|
+
# },
|
43
|
+
# ## until (including) 1991-92} season
|
44
|
+
# '1991-92' => { '1' => 'division1', # english division 1
|
45
|
+
# '2' => 'division2', # english division 2
|
46
|
+
# }
|
47
|
+
# }
|
48
|
+
}
|
49
|
+
|
50
|
+
pp @leagues_latest
|
51
|
+
pp @leagues_history
|
52
|
+
|
53
|
+
%w(eng sco fr gr).each do |country|
|
54
|
+
hash = LeagueReader.from_file( "#{Boot.data_dir}/leagues/#{country}.txt" )
|
55
|
+
pp hash
|
56
|
+
|
57
|
+
hash.each do |season,league_hash|
|
58
|
+
if season == '*' ## assume latest / default season
|
59
|
+
@leagues_latest[ country ] = league_hash
|
60
|
+
else
|
61
|
+
@leagues_history[ country ] ||= {}
|
62
|
+
@leagues_history[ country ][ season ] = league_hash
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
pp @leagues_latest
|
68
|
+
pp @leagues_history
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
def basename( league, country:, season: )
|
74
|
+
## todo/check: rename league: to key: - why? why not?
|
75
|
+
|
76
|
+
if country.include?( '-' ) ## assume package name e.g. eng-england etc.
|
77
|
+
## cut off country code from package name
|
78
|
+
cc = country.split( '-' )[0] # use first part
|
79
|
+
else
|
80
|
+
cc = country
|
81
|
+
end
|
82
|
+
|
83
|
+
if season
|
84
|
+
puts " checking season >#{season}<"
|
85
|
+
## check history if season is provided / supplied / known
|
86
|
+
history = @leagues_history[ cc ]
|
87
|
+
if history
|
88
|
+
season_start_year = SeasonUtils.start_year( season ).to_i
|
89
|
+
##
|
90
|
+
## todo: sorty season keys - why? why not? -- assume reverse chronological order for now
|
91
|
+
history.keys.reverse.each do |key|
|
92
|
+
history_season_start_year = SeasonUtils.start_year( key ).to_i
|
93
|
+
puts " #{season_start_year} <= #{history_season_start_year} - #{season_start_year <= history_season_start_year}"
|
94
|
+
if season_start_year <= history_season_start_year
|
95
|
+
result = history[ key ][ league ]
|
96
|
+
if result
|
97
|
+
return "#{league}-#{result}"
|
98
|
+
else
|
99
|
+
return nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
latest = @leagues_latest[ cc ]
|
107
|
+
if latest
|
108
|
+
result = latest[ league ]
|
109
|
+
return "#{league}-#{result}" if result
|
110
|
+
end
|
111
|
+
|
112
|
+
nil
|
113
|
+
end # method basename
|
114
|
+
end # class LeagueConfig
|
115
|
+
|
116
|
+
|
117
|
+
end ## module Import
|
118
|
+
end ## module SportDb
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
|
4
|
+
module SportDb
|
5
|
+
module Import
|
6
|
+
|
7
|
+
class LeagueReader
|
8
|
+
|
9
|
+
def self.from_file( path ) ## use - rename to read_file - why? why not?
|
10
|
+
txt = File.open( path, 'r:utf-8' ).read
|
11
|
+
read( txt )
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
SEASON_REGEX = /\[
|
17
|
+
(?<season>
|
18
|
+
\d{4}
|
19
|
+
(-\d{2,4})?
|
20
|
+
)
|
21
|
+
\]/x
|
22
|
+
|
23
|
+
def self.read( txt )
|
24
|
+
hash = {}
|
25
|
+
season = '*' ## use '*' for default/latest season
|
26
|
+
|
27
|
+
txt.each_line do |line|
|
28
|
+
line = line.strip
|
29
|
+
|
30
|
+
next if line.empty?
|
31
|
+
next if line.start_with?( '#' ) ## skip comments too
|
32
|
+
|
33
|
+
## strip inline comments too
|
34
|
+
line = line.sub( /#.*/, '' ).strip
|
35
|
+
|
36
|
+
pp line
|
37
|
+
|
38
|
+
|
39
|
+
if (m=line.match( SEASON_REGEX ))
|
40
|
+
season = m[:season]
|
41
|
+
else
|
42
|
+
key_line, values_line = line.split( '=>' )
|
43
|
+
values = values_line.split( ',' )
|
44
|
+
|
45
|
+
## remove leading and trailing spaces
|
46
|
+
key_line = key_line.strip
|
47
|
+
values = values.map { |value| value.strip }
|
48
|
+
pp values
|
49
|
+
|
50
|
+
league_key = key_line
|
51
|
+
league_basename = values[0]
|
52
|
+
|
53
|
+
hash[season] ||= {}
|
54
|
+
hash[season][league_key] = league_basename
|
55
|
+
end
|
56
|
+
end
|
57
|
+
hash
|
58
|
+
end # method read
|
59
|
+
|
60
|
+
end ## class LeagueReader
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
end ## module Import
|
65
|
+
end ## module SportDb
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module SportDb
|
4
|
+
module Struct
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
class Team
|
9
|
+
attr_accessor :name,
|
10
|
+
:alt_names,
|
11
|
+
:city,
|
12
|
+
:country
|
13
|
+
|
14
|
+
|
15
|
+
## add alias/compat - why? why not
|
16
|
+
def title() @name; end
|
17
|
+
def names()
|
18
|
+
ary = [@name]
|
19
|
+
ary += @alt_names if @alt_names
|
20
|
+
ary
|
21
|
+
end ## all names
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
## do nothing for now (use from_csv to setup data)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.create( **kwargs )
|
30
|
+
self.new.update( kwargs )
|
31
|
+
end
|
32
|
+
|
33
|
+
def update( **kwargs )
|
34
|
+
@name = kwargs[:name]
|
35
|
+
@alt_names = kwargs[:alt_names]
|
36
|
+
@city = kwargs[:city] ## use city struct - why? why not?
|
37
|
+
## todo: add country too
|
38
|
+
|
39
|
+
self ## note - MUST return self for chaining
|
40
|
+
end
|
41
|
+
end # class Team
|
42
|
+
|
43
|
+
|
44
|
+
end # module Struct
|
45
|
+
end # module SportDb
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
|
4
|
+
module SportDb
|
5
|
+
module Import
|
6
|
+
|
7
|
+
|
8
|
+
class TeamReader
|
9
|
+
|
10
|
+
|
11
|
+
def self.from_file( path ) ## use - rename to read_file - why? why not?
|
12
|
+
txt = File.open( path, 'r:utf-8' ).read
|
13
|
+
read( txt )
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
def self.read( txt ) ## rename to parse - why? why not? and use read for file read?
|
18
|
+
recs = []
|
19
|
+
txt.each_line do |line|
|
20
|
+
line = line.strip
|
21
|
+
|
22
|
+
next if line.empty?
|
23
|
+
next if line.start_with?( '#' ) ## skip comments too
|
24
|
+
|
25
|
+
## strip inline comments too
|
26
|
+
## e.g Eupen => KAS Eupen, ## [de]
|
27
|
+
## => Eupen => KAS Eupen,
|
28
|
+
line = line.sub( /#.*/, '' ).strip
|
29
|
+
|
30
|
+
pp line
|
31
|
+
names_line, team_line = line.split( '=>' )
|
32
|
+
|
33
|
+
names = names_line.split( /[|,]/ ) # team names - allow comma(,) or pipe(|)
|
34
|
+
team = team_line.split( ',' ) # (canoncial) team name, team_city
|
35
|
+
|
36
|
+
## remove leading and trailing spaces
|
37
|
+
names = names.map { |name| name.strip }
|
38
|
+
team = team.map { |team| team.strip }
|
39
|
+
pp names
|
40
|
+
pp team
|
41
|
+
|
42
|
+
canonical_name = team[0]
|
43
|
+
city = team[1]
|
44
|
+
|
45
|
+
## squish (white)spaces
|
46
|
+
# e.g. New York FC (2011-) => New York FC (2011-)
|
47
|
+
# e.g. León › Guanajuato => León › Guanajuato
|
48
|
+
canonical_name = canonical_name.gsub( /[ \t]+/, ' ' )
|
49
|
+
city = city.gsub( /[ \t]+/, ' ' ) if city
|
50
|
+
|
51
|
+
## note:
|
52
|
+
## check/todo!!!!!!!!!!!!!!!!!-
|
53
|
+
## strip year if to present e.g. (2011-)
|
54
|
+
##
|
55
|
+
## do NOT strip for defunct / historic clubs e.g.
|
56
|
+
## (1899-1910)
|
57
|
+
## or (-1914) or (-2011) etc.
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
###
|
62
|
+
## todo: move year out of canonical team name - why? why not?
|
63
|
+
##
|
64
|
+
|
65
|
+
## check if canonical name include (2011-) or similar in name
|
66
|
+
## if yes, remove (2011-) and add to (alt) names
|
67
|
+
## e.g. New York FC (2011) => New York FC
|
68
|
+
if canonical_name =~ /\(.+?\)/ ## note: use non-greedy (?) match
|
69
|
+
name = canonical_name.gsub( /\(.+?\)/, '' ).strip
|
70
|
+
names << name
|
71
|
+
end
|
72
|
+
|
73
|
+
### todo/fix:
|
74
|
+
## auto-add alt name with dots stripped - why? why not?
|
75
|
+
## e.g. D.C. United => DC United
|
76
|
+
## e.g. Liverpool F.C. => Liverpool FC
|
77
|
+
## e.g. St. Albin => St Albin etc.
|
78
|
+
## e.g. 1. FC Köln => 1 FC Köln -- make special case for 1. - why? why not?
|
79
|
+
|
80
|
+
##
|
81
|
+
## todo/fix: unify mapping entries
|
82
|
+
## always lowercase !!!! (case insensitive)
|
83
|
+
## always strip (2011-) !!!
|
84
|
+
## always strip dots (e.g. St., F.C, etc.)
|
85
|
+
|
86
|
+
|
87
|
+
names = names.uniq ## remove duplicates - todo/fix: warn about duplicates - why? why not?
|
88
|
+
|
89
|
+
## note: remove from alt_names if canonical name (mapping 1:1)
|
90
|
+
## or if empty
|
91
|
+
alt_names = names.select {|name| (name.empty? || name == canonical_name) ? false : true }
|
92
|
+
|
93
|
+
## todo: add country (code) too!!!
|
94
|
+
rec = SportDb::Struct::Team.create(
|
95
|
+
name: canonical_name,
|
96
|
+
city: city, ## note: team_city is optional for now (might be nil!!!)
|
97
|
+
alt_names: alt_names
|
98
|
+
)
|
99
|
+
## pp rec
|
100
|
+
recs << rec
|
101
|
+
end
|
102
|
+
recs
|
103
|
+
end # method read
|
104
|
+
end # class TeamReader
|
105
|
+
|
106
|
+
|
107
|
+
end ## module Import
|
108
|
+
end ## module SportDb
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
|
4
|
+
module LeagueHelper
|
5
|
+
def basename( league, country:, season: nil )
|
6
|
+
## e.g. eng-england, 2011-12, 1 returns 1-premierleague
|
7
|
+
##
|
8
|
+
## allow country code or (repo) package name
|
9
|
+
## e.g. eng-england or eng
|
10
|
+
## de-deutschland or de etc.
|
11
|
+
|
12
|
+
leagues = SportDb::Import.config.leagues
|
13
|
+
|
14
|
+
result = leagues.basename( league, country: country, season: season )
|
15
|
+
|
16
|
+
##
|
17
|
+
# note: if no mapping / nothing found return league e.g. 1, 2, 3, 3a, 3b, cup(?), etc.
|
18
|
+
result ? result : league
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module LeagueUtils
|
23
|
+
extend LeagueHelper
|
24
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
|
4
|
+
module SeasonHelper ## use Helpers why? why not?
|
5
|
+
def prev( season )
|
6
|
+
## todo: add 1964-1965 format too!!!
|
7
|
+
if season =~ /^(\d{4})-(\d{2})$/ ## season format is 1964-65
|
8
|
+
fst = $1.to_i - 1
|
9
|
+
snd = (100 + $2.to_i - 1) % 100 ## note: add 100 to turn 00 => 99
|
10
|
+
"%4d-%02d" % [fst,snd]
|
11
|
+
elsif season =~ /^(\d{4})$/
|
12
|
+
fst = $1.to_i - 1
|
13
|
+
"%4d" % [fst]
|
14
|
+
else
|
15
|
+
puts "*** !!!! wrong season format >>#{season}<<; exit; sorry"
|
16
|
+
exit 1
|
17
|
+
end
|
18
|
+
end # method prev
|
19
|
+
|
20
|
+
|
21
|
+
def key( basename )
|
22
|
+
if basename =~ /^(\d{4})[\-\/](\d{4})$/ ## e.g. 2011-2012 or 2011/2012 => 2011/12
|
23
|
+
"%4d/%02d" % [$1.to_i, $2.to_i % 100]
|
24
|
+
elsif basename =~ /^(\d{4})[\-\/](\d{2})$/ ## e.g. 2011-12 or 2011/12 => 2011/12
|
25
|
+
"#{$1}/#{$2}"
|
26
|
+
elsif basename =~ /^(\d{4})$/
|
27
|
+
$1
|
28
|
+
else
|
29
|
+
puts "*** !!!! wrong season format >>#{basename}<<; exit; sorry"
|
30
|
+
exit 1
|
31
|
+
end
|
32
|
+
end # method key
|
33
|
+
|
34
|
+
|
35
|
+
def directory( season, format: nil )
|
36
|
+
## todo: find better names for formats - why? why not?:
|
37
|
+
## long | archive | decade(?) => 1980s/1988-89, 2010s/2017-18, ...
|
38
|
+
## short | std(?) => 1988-89, 2017-18, ...
|
39
|
+
|
40
|
+
## convert season name to "standard" season name for directory
|
41
|
+
|
42
|
+
## todo/fix: move to parse / validate season (for (re)use)!!!! - why? why not?
|
43
|
+
if season =~ /^(\d{4})[\-\/](\d{4})$/ ## e.g. 2011-2012 or 2011/2012 => 2011-12
|
44
|
+
years = [$1.to_i, $2.to_i]
|
45
|
+
elsif season =~ /^(\d{4})[\-\/](\d{2})$/ ## e.g. 2011-12 or 2011/12 => 2011-12
|
46
|
+
years = [$1.to_i, $1.to_i+1]
|
47
|
+
## note: check that season end year is (always) season start year + 1
|
48
|
+
if ($1.to_i+1) % 100 != $2.to_i
|
49
|
+
puts "*** !!!! wrong season format >>#{season}<<; season end year MUST (always) equal season start year + 1; exit; sorry"
|
50
|
+
exit 1
|
51
|
+
end
|
52
|
+
elsif season =~ /^(\d{4})$/
|
53
|
+
years = [$1.to_i]
|
54
|
+
else
|
55
|
+
puts "*** !!!! wrong season format >>#{season}<<; exit; sorry"
|
56
|
+
exit 1
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
if ['l', 'long', 'archive' ].include?( format.to_s ) ## note: allow passing in of symbol to e.g. 'long' or :long
|
61
|
+
if years.size == 2
|
62
|
+
"%3d0s/%4d-%02d" % [years[0] / 10, years[0], years[1] % 100] ## e.g. 2000s/2001-02
|
63
|
+
else ## assume size 1 (single year season)
|
64
|
+
"%3d0s/%4d" % [years[0] / 10, years[0]]
|
65
|
+
end
|
66
|
+
else ## default 'short' format / fallback
|
67
|
+
if years.size == 2
|
68
|
+
"%4d-%02d" % [years[0], years[1] % 100] ## e.g. 2001-02
|
69
|
+
else ## assume size 1 (single year season)
|
70
|
+
"%4d" % years[0]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end # method directory
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
def start_year( season ) ## get start year
|
78
|
+
## convert season name to "standard" season name for directory
|
79
|
+
|
80
|
+
## todo/check: just return year from first for chars - keep it simple - why? why not?
|
81
|
+
if season =~ /^(\d{4})[\-\/](\d{4})$/ ## e.g. 2011-2010 or 2011/2011 => 2011-10
|
82
|
+
$1
|
83
|
+
elsif season =~ /^(\d{4})[\-\/](\d{2})$/
|
84
|
+
$1
|
85
|
+
elsif season =~ /^(\d{4})$/
|
86
|
+
$1
|
87
|
+
else
|
88
|
+
puts "*** !!!! wrong season format >>#{season}<<; exit; sorry"
|
89
|
+
exit 1
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def end_year( season ) ## get end year
|
94
|
+
## convert season name to "standard" season name for directory
|
95
|
+
if season =~ /^(\d{4})[\-\/](\d{4})$/ ## e.g. 2011-2010 or 2011/2011 => 2011-10
|
96
|
+
$2
|
97
|
+
elsif season =~ /^(\d{4})[\-\/](\d{2})$/
|
98
|
+
## note: assume second year is always +1
|
99
|
+
## todo/fix: add assert/check - why? why not?
|
100
|
+
## eg. 1999-00 => 2000 or 1899-00 => 1900
|
101
|
+
($1.to_i+1).to_s
|
102
|
+
elsif season =~ /^(\d{4})$/
|
103
|
+
$1
|
104
|
+
else
|
105
|
+
puts "*** !!!! wrong season format >>#{season}<<; exit; sorry"
|
106
|
+
exit 1
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end # module SeasonHelper
|
110
|
+
|
111
|
+
|
112
|
+
module SeasonUtils
|
113
|
+
extend SeasonHelper
|
114
|
+
## lets you use SeasonHelper as "globals" eg.
|
115
|
+
## SeasonUtils.prev( season ) etc.
|
116
|
+
end # SeasonUtils
|