sportdb-config 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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