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.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/HISTORY.md +3 -0
  3. data/Manifest.txt +65 -0
  4. data/README.md +27 -0
  5. data/Rakefile +26 -0
  6. data/config/geos/eng.txt +162 -0
  7. data/config/leagues/eng.txt +40 -0
  8. data/config/leagues/fr.txt +9 -0
  9. data/config/leagues/gr.txt +7 -0
  10. data/config/leagues/sco.txt +19 -0
  11. data/config/teams/al.txt +6 -0
  12. data/config/teams/at.txt +26 -0
  13. data/config/teams/be.txt +58 -0
  14. data/config/teams/bg.txt +6 -0
  15. data/config/teams/by.txt +5 -0
  16. data/config/teams/ca.txt +4 -0
  17. data/config/teams/ch.txt +10 -0
  18. data/config/teams/cy.txt +7 -0
  19. data/config/teams/cz.txt +6 -0
  20. data/config/teams/de.txt +129 -0
  21. data/config/teams/dk.txt +6 -0
  22. data/config/teams/eng.txt +294 -0
  23. data/config/teams/es.txt +148 -0
  24. data/config/teams/fi.txt +6 -0
  25. data/config/teams/fr.txt +98 -0
  26. data/config/teams/ga.txt +5 -0
  27. data/config/teams/gr.txt +87 -0
  28. data/config/teams/hr.txt +9 -0
  29. data/config/teams/hu.txt +5 -0
  30. data/config/teams/ie.txt +5 -0
  31. data/config/teams/is.txt +6 -0
  32. data/config/teams/it.txt +99 -0
  33. data/config/teams/lu.txt +6 -0
  34. data/config/teams/mc.txt +4 -0
  35. data/config/teams/md.txt +4 -0
  36. data/config/teams/mt.txt +6 -0
  37. data/config/teams/mx.txt +30 -0
  38. data/config/teams/nir.txt +6 -0
  39. data/config/teams/nl.txt +45 -0
  40. data/config/teams/no.txt +7 -0
  41. data/config/teams/pl.txt +6 -0
  42. data/config/teams/pt.txt +53 -0
  43. data/config/teams/ro.txt +5 -0
  44. data/config/teams/rs.txt +6 -0
  45. data/config/teams/ru.txt +5 -0
  46. data/config/teams/sco.txt +73 -0
  47. data/config/teams/se.txt +6 -0
  48. data/config/teams/si.txt +5 -0
  49. data/config/teams/sk.txt +5 -0
  50. data/config/teams/tr.txt +39 -0
  51. data/config/teams/ua.txt +5 -0
  52. data/config/teams/us.txt +44 -0
  53. data/config/teams/wal.txt +16 -0
  54. data/lib/sportdb/config.rb +26 -0
  55. data/lib/sportdb/config/config.rb +77 -0
  56. data/lib/sportdb/config/league.rb +118 -0
  57. data/lib/sportdb/config/league_reader.rb +65 -0
  58. data/lib/sportdb/config/structs/team.rb +45 -0
  59. data/lib/sportdb/config/team_reader.rb +108 -0
  60. data/lib/sportdb/config/utils/league_utils.rb +24 -0
  61. data/lib/sportdb/config/utils/season_utils.rb +116 -0
  62. data/lib/sportdb/config/version.rb +35 -0
  63. data/test/helper.rb +10 -0
  64. data/test/test_config.rb +19 -0
  65. data/test/test_league_utils.rb +90 -0
  66. data/test/test_season_utils.rb +29 -0
  67. 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