sportdb-search 0.1.1 → 0.2.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 +4 -4
- data/CHANGELOG.md +1 -1
- data/Manifest.txt +8 -3
- data/bin/fbq +128 -0
- data/lib/sportdb/search/sport-clubs.rb +132 -0
- data/lib/sportdb/search/sport-events.rb +50 -0
- data/lib/sportdb/search/sport-history.rb +16 -0
- data/lib/sportdb/search/sport-leagues.rb +56 -0
- data/lib/sportdb/search/sport-more.rb +40 -0
- data/lib/sportdb/search/sport-teams.rb +98 -0
- data/lib/sportdb/search/version.rb +2 -2
- data/lib/sportdb/search/{structs_world.rb → world.rb} +4 -7
- data/lib/sportdb/search.rb +14 -125
- metadata +12 -6
- data/lib/sportdb/search/sport.rb +0 -384
- data/lib/sportdb/search/structs.rb +0 -118
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c135a538a3ebe251b9506a6a31e0dcad7b3a456ed863a1a56ae3235a00129fd5
|
|
4
|
+
data.tar.gz: 145edb5ec66df797b8361f82da6c493417354ab408e19fa1a74fbb6f39d87d1f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8e6604db8b3fb94a5fd1aa6656bb074ea6486765c0018eab262af941ec294323a3dd496d3782c8a735ce36b25650ef56e39bf7b536c8f059159a82c3d54e4ad6
|
|
7
|
+
data.tar.gz: 4dddf10fd601263a12f4ea7845e61261e6983a8d9c8f7420bc927d2149081c1420bd7e2793ab1a8e50a8b3aab18a9d21f411c135caab09ce1c72d0a9035c8270
|
data/CHANGELOG.md
CHANGED
data/Manifest.txt
CHANGED
|
@@ -2,8 +2,13 @@ CHANGELOG.md
|
|
|
2
2
|
Manifest.txt
|
|
3
3
|
README.md
|
|
4
4
|
Rakefile
|
|
5
|
+
bin/fbq
|
|
5
6
|
lib/sportdb/search.rb
|
|
6
|
-
lib/sportdb/search/sport.rb
|
|
7
|
-
lib/sportdb/search/
|
|
8
|
-
lib/sportdb/search/
|
|
7
|
+
lib/sportdb/search/sport-clubs.rb
|
|
8
|
+
lib/sportdb/search/sport-events.rb
|
|
9
|
+
lib/sportdb/search/sport-history.rb
|
|
10
|
+
lib/sportdb/search/sport-leagues.rb
|
|
11
|
+
lib/sportdb/search/sport-more.rb
|
|
12
|
+
lib/sportdb/search/sport-teams.rb
|
|
9
13
|
lib/sportdb/search/version.rb
|
|
14
|
+
lib/sportdb/search/world.rb
|
data/bin/fbq
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
## tip: to test run:
|
|
4
|
+
## ruby -I ./lib bin/fbq
|
|
5
|
+
|
|
6
|
+
## our own code
|
|
7
|
+
require 'sportdb/search'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
require 'optparse'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## local hack
|
|
16
|
+
## if exists up-to-date catalog db (use local version NOT built-in)
|
|
17
|
+
catalog_path = '../catalog/catalog.db'
|
|
18
|
+
if File.exist?( catalog_path )
|
|
19
|
+
SportDb::Import.config.catalog_path = catalog_path
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
args = ARGV
|
|
24
|
+
opts = { debug: false,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
parser = OptionParser.new do |parser|
|
|
28
|
+
parser.banner = "Usage: #{$PROGRAM_NAME} [options] QUERY"
|
|
29
|
+
|
|
30
|
+
##
|
|
31
|
+
## check if git has a offline option?? (use same)
|
|
32
|
+
## check for other tools - why? why not?
|
|
33
|
+
# parser.on( "-q", "--quiet",
|
|
34
|
+
# "less debug output/messages - default is (#{!opts[:debug]})" ) do |debug|
|
|
35
|
+
# opts[:debug] = false
|
|
36
|
+
# end
|
|
37
|
+
parser.on( "--verbose", "--debug",
|
|
38
|
+
"turn on verbose / debug output (default: #{opts[:debug]})" ) do |debug|
|
|
39
|
+
opts[:debug] = true
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
parser.parse!( args )
|
|
43
|
+
|
|
44
|
+
puts "OPTS:"
|
|
45
|
+
p opts
|
|
46
|
+
puts "ARGV:"
|
|
47
|
+
p args
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
## add convenience shortcuts
|
|
51
|
+
Club = Sports::Club
|
|
52
|
+
NationalTeam = Sports::NationalTeam
|
|
53
|
+
League = Sports::League
|
|
54
|
+
Ground = Sports::Ground
|
|
55
|
+
|
|
56
|
+
City = Sports::City
|
|
57
|
+
Country = Sports::Country
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
queries = args
|
|
61
|
+
queries.each_with_index do |query,i|
|
|
62
|
+
puts "==> [#{i+1}/#{queries.size}] >>> #{query} <<< ..."
|
|
63
|
+
|
|
64
|
+
## check for clubs
|
|
65
|
+
m = Club.match_by( name: query )
|
|
66
|
+
if m.size > 0
|
|
67
|
+
puts " #{m.size} CLUB match(es):"
|
|
68
|
+
print " "
|
|
69
|
+
print m.pretty_inspect
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
## check for leagues
|
|
73
|
+
m = League.match_by( code: query )
|
|
74
|
+
if m.size > 0
|
|
75
|
+
puts " #{m.size} LEAGUE (by code) match(es):"
|
|
76
|
+
print " "
|
|
77
|
+
print m.pretty_inspect
|
|
78
|
+
end
|
|
79
|
+
m = League.match_by( name: query )
|
|
80
|
+
if m.size > 0
|
|
81
|
+
puts " #{m.size} LEAGUE (by name) match(es):"
|
|
82
|
+
print " "
|
|
83
|
+
print m.pretty_inspect
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
## check for grounds/stadiums
|
|
87
|
+
m = Ground.match_by( name: query )
|
|
88
|
+
if m.size > 0
|
|
89
|
+
puts " #{m.size} GROUND match(es):"
|
|
90
|
+
print " "
|
|
91
|
+
print m.pretty_inspect
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
### check for national team
|
|
96
|
+
rec = NationalTeam.find( query )
|
|
97
|
+
if rec
|
|
98
|
+
puts " 1 NATIONAL_TEAM match / found:"
|
|
99
|
+
print " "
|
|
100
|
+
print rec.pretty_inspect
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
####
|
|
104
|
+
# check geos
|
|
105
|
+
# note - country for now must be unique match (thus, find)
|
|
106
|
+
rec = Country.find_by( code: query )
|
|
107
|
+
if rec
|
|
108
|
+
puts " 1 COUNTRY (by code) match / found:"
|
|
109
|
+
print " "
|
|
110
|
+
print rec.pretty_inspect
|
|
111
|
+
end
|
|
112
|
+
rec = Country.find_by( name: query )
|
|
113
|
+
if rec
|
|
114
|
+
puts " 1 COUNTRY (by name) match / found:"
|
|
115
|
+
print " "
|
|
116
|
+
print rec.pretty_inspect
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
m = City.match_by( name: query )
|
|
120
|
+
if m.size > 0
|
|
121
|
+
puts " #{m.size} CITY match(es):"
|
|
122
|
+
print " "
|
|
123
|
+
print m.pretty_inspect
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
puts "bye"
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
|
|
2
|
+
module Sports
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Club
|
|
6
|
+
def self._search() CatalogDb::Metal::Club; end
|
|
7
|
+
|
|
8
|
+
###################
|
|
9
|
+
## core required delegates - use delegate generator - why? why not?
|
|
10
|
+
|
|
11
|
+
## add mods here - why? why not?
|
|
12
|
+
def self.match_by( name:, country: nil,
|
|
13
|
+
league: nil,
|
|
14
|
+
mods: nil )
|
|
15
|
+
## for now assume "global" mods - checks only for name
|
|
16
|
+
##
|
|
17
|
+
if mods && mods[ name ]
|
|
18
|
+
club = mods[ name ]
|
|
19
|
+
return [club] # note: wrap (single record) in array
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
## note: add "auto-magic" country calculation via league record
|
|
23
|
+
## if league is a national league for football clubs
|
|
24
|
+
if league
|
|
25
|
+
raise ArgumentError, "match_by - league AND country NOT supported; sorry" if country
|
|
26
|
+
### find countries via league
|
|
27
|
+
### support league.intl? too - why? why not?
|
|
28
|
+
### or only nationa league
|
|
29
|
+
raise ArgumentError, "match_by - league - only national club leagues supported (not int'l or national teams for now); sorry" unless league.national? && league.clubs?
|
|
30
|
+
|
|
31
|
+
### calc countries
|
|
32
|
+
### uses "global" func in sports-catalogs for now
|
|
33
|
+
## move code here - why? why not?
|
|
34
|
+
country = find_countries_for_league( league )
|
|
35
|
+
_search.match_by( name: name,
|
|
36
|
+
country: country )
|
|
37
|
+
else
|
|
38
|
+
_search.match_by( name: name,
|
|
39
|
+
country: country )
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
## todo/fix/check: use rename to find_canon or find_canonical() or something??
|
|
45
|
+
## remove (getting used?) - why? why not?
|
|
46
|
+
# def []( name ) ## lookup by canoncial name only; todo/fix: add find alias why? why not?
|
|
47
|
+
# puts "WARN!! do not use ClubIndex#[] for lookup >#{name}< - will get removed!!!"
|
|
48
|
+
# @clubs[ name ]
|
|
49
|
+
# end
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
###############
|
|
53
|
+
### more deriv support functions / helpers
|
|
54
|
+
def self.match( name ) match_by( name: name ); end
|
|
55
|
+
|
|
56
|
+
##########
|
|
57
|
+
# "legacy" finders - return zero or one club
|
|
58
|
+
## (if more than one match, exit/raise error/exception)
|
|
59
|
+
def self.find( name ) find_by( name: name ); end
|
|
60
|
+
def self.find!( name ) find_by!( name: name ); end
|
|
61
|
+
|
|
62
|
+
## find - always returns a single record / match or nil
|
|
63
|
+
## if there is more than one match than find aborts / fails
|
|
64
|
+
def self.find_by!( name:, country: nil,
|
|
65
|
+
league: nil ) ## todo/fix: add international or league flag?
|
|
66
|
+
club = find_by( name: name,
|
|
67
|
+
country: country,
|
|
68
|
+
league: league )
|
|
69
|
+
|
|
70
|
+
if club.nil?
|
|
71
|
+
puts "** !!! ERROR - no match for club >#{name}<"
|
|
72
|
+
exit 1
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
club
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def self.find_by( name:, country: nil,
|
|
80
|
+
league: nil ) ## todo/fix: add international or league flag?
|
|
81
|
+
## note: allow passing in of country key too (auto-counvert)
|
|
82
|
+
## and country struct too
|
|
83
|
+
## - country assumes / allows the country key or fifa code for now
|
|
84
|
+
recs = match_by( name: name,
|
|
85
|
+
country: country,
|
|
86
|
+
league: league )
|
|
87
|
+
|
|
88
|
+
club = nil
|
|
89
|
+
if recs.empty?
|
|
90
|
+
## puts "** !!! WARN !!! no match for club >#{name}<"
|
|
91
|
+
elsif recs.size > 1
|
|
92
|
+
puts "** !!! ERROR - too many matches (#{recs.size}) for club >#{name}<:"
|
|
93
|
+
pp recs
|
|
94
|
+
exit 1
|
|
95
|
+
else # bingo; match - assume size == 1
|
|
96
|
+
club = recs[0]
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
club
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
#######
|
|
104
|
+
# more support methods
|
|
105
|
+
def self.build_mods( mods )
|
|
106
|
+
## e.g.
|
|
107
|
+
## { 'Arsenal | Arsenal FC' => 'Arsenal, ENG',
|
|
108
|
+
## 'Liverpool | Liverpool FC' => 'Liverpool, ENG',
|
|
109
|
+
## 'Barcelona' => 'Barcelona, ESP',
|
|
110
|
+
## 'Valencia' => 'Valencia, ESP' }
|
|
111
|
+
|
|
112
|
+
mods.reduce({}) do |h,(club_names, club_line)|
|
|
113
|
+
|
|
114
|
+
values = club_line.split( ',' )
|
|
115
|
+
values = values.map { |value| value.strip } ## strip all spaces
|
|
116
|
+
|
|
117
|
+
## todo/fix: make sure country is present !!!!
|
|
118
|
+
club_name, country_name = values
|
|
119
|
+
club = find_by!( name: club_name, country: country_name )
|
|
120
|
+
|
|
121
|
+
values = club_names.split( '|' )
|
|
122
|
+
values = values.map { |value| value.strip } ## strip all spaces
|
|
123
|
+
|
|
124
|
+
values.each do |club_name|
|
|
125
|
+
h[club_name] = club
|
|
126
|
+
end
|
|
127
|
+
h
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end # class Club
|
|
131
|
+
|
|
132
|
+
end # module Sports
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module Sports
|
|
2
|
+
|
|
3
|
+
class EventInfo
|
|
4
|
+
def self._search() CatalogDb::Metal::EventInfo; end
|
|
5
|
+
|
|
6
|
+
def self.find_by( league:, season: )
|
|
7
|
+
_search.find_by( league: league,
|
|
8
|
+
season: season )
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.seasons( league )
|
|
12
|
+
_search.seasons( league )
|
|
13
|
+
end
|
|
14
|
+
end # class EventInfo
|
|
15
|
+
|
|
16
|
+
end # module Sports
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
__END__
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
####
|
|
23
|
+
## virtual table for season lookup
|
|
24
|
+
## note - use EventSeaon to avoid name conflict with (global) Season class
|
|
25
|
+
## find a better name SeasonInfo or SeasonFinder or SeasonStore
|
|
26
|
+
## or SeasonQ or ??
|
|
27
|
+
class EventSeasonSearch
|
|
28
|
+
def initialize( events: )
|
|
29
|
+
@events = events
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
###############
|
|
33
|
+
## todo/fix: find a better algo to guess season for date!!!
|
|
34
|
+
##
|
|
35
|
+
def find_by( date:, league: )
|
|
36
|
+
date = Date.strptime( date, '%Y-%m-%d' ) if date.is_a?( String )
|
|
37
|
+
|
|
38
|
+
infos = @events.seasons( league )
|
|
39
|
+
|
|
40
|
+
infos.each do |info|
|
|
41
|
+
return info.season if info.include?( date )
|
|
42
|
+
end
|
|
43
|
+
nil
|
|
44
|
+
end
|
|
45
|
+
end # class EventSeasonSearch
|
|
46
|
+
end # class SportSearch
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
###
|
|
2
|
+
# more to be done - is a dummy for now !!!!!
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
module Sports
|
|
6
|
+
class Team
|
|
7
|
+
## add convenience lookup helper / method for name by season for now
|
|
8
|
+
## use clubs history - for now kept separate from struct - why? why not?
|
|
9
|
+
def name_by_season( season )
|
|
10
|
+
## note: returns / fallback to "regular" name if no records found in history
|
|
11
|
+
club_history = SportDb::Import.catalog.clubs_history
|
|
12
|
+
club_history.find_name_by( name: name, season: season ) || name
|
|
13
|
+
end
|
|
14
|
+
end # class Team
|
|
15
|
+
end # module Sports
|
|
16
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
|
|
2
|
+
module Sports
|
|
3
|
+
|
|
4
|
+
class League
|
|
5
|
+
def self._search() CatalogDb::Metal::League; end
|
|
6
|
+
|
|
7
|
+
###################
|
|
8
|
+
## core required delegates - use delegate generator - why? why not?
|
|
9
|
+
def self.match_by( name: nil, code: nil, country: nil )
|
|
10
|
+
## todo/fix upstream - remove "generic" match_by() - why? why not?
|
|
11
|
+
###
|
|
12
|
+
if code && name.nil?
|
|
13
|
+
_search.match_by_code( code, country: country )
|
|
14
|
+
elsif name && code.nil?
|
|
15
|
+
_search.match_by_name( name, country: country )
|
|
16
|
+
else
|
|
17
|
+
raise ArgumentError, "LeagueSearch#match_by - one (and only one arg) required - code: or name:"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## all-in-one query (name or code)
|
|
23
|
+
def self.match( q, country: nil )
|
|
24
|
+
_search.match_by_name_or_code( q, country: country )
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
###############
|
|
28
|
+
### more deriv support functions / helpers
|
|
29
|
+
def self.find!( q )
|
|
30
|
+
league = find( q )
|
|
31
|
+
if league.nil?
|
|
32
|
+
puts "** !!! ERROR - no league match found for >#{q}<, add to leagues table; sorry"
|
|
33
|
+
exit 1
|
|
34
|
+
end
|
|
35
|
+
league
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.find( q )
|
|
39
|
+
league = nil
|
|
40
|
+
recs = match( q )
|
|
41
|
+
# pp m
|
|
42
|
+
|
|
43
|
+
if recs.empty?
|
|
44
|
+
## fall through/do nothing
|
|
45
|
+
elsif recs.size > 1
|
|
46
|
+
puts "** !!! ERROR - too many matches (#{recs.size}) for league #{q}:"
|
|
47
|
+
pp recs
|
|
48
|
+
exit 1
|
|
49
|
+
else
|
|
50
|
+
league = recs[0]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
league
|
|
54
|
+
end
|
|
55
|
+
end # class League
|
|
56
|
+
end # module Sports
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
|
|
2
|
+
module Sports
|
|
3
|
+
|
|
4
|
+
class Ground
|
|
5
|
+
def self._search() CatalogDb::Metal::Ground; end
|
|
6
|
+
|
|
7
|
+
###################
|
|
8
|
+
## core required delegates - use delegate generator - why? why not?
|
|
9
|
+
def self.match_by( name:, country: nil, city: nil )
|
|
10
|
+
_search.match_by( name: name,
|
|
11
|
+
country: country,
|
|
12
|
+
city: city )
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
###############
|
|
16
|
+
### more deriv support functions / helpers
|
|
17
|
+
def self.match( name ) match_by( name: name ); end
|
|
18
|
+
## add more here - why? why not?
|
|
19
|
+
end # class Ground
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Player
|
|
24
|
+
def self._search() CatalogDb::Metal::Player; end
|
|
25
|
+
|
|
26
|
+
###################
|
|
27
|
+
## core required delegates - use delegate generator - why? why not?
|
|
28
|
+
def self.match_by( name:, country: nil, year: nil )
|
|
29
|
+
_search.match_by( name: name,
|
|
30
|
+
country: country,
|
|
31
|
+
year: year )
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
###############
|
|
35
|
+
### more deriv support functions / helpers
|
|
36
|
+
def self.match( name ) match_by( name: name ); end
|
|
37
|
+
## add more here - why? why not?
|
|
38
|
+
end # class Player
|
|
39
|
+
|
|
40
|
+
end # module Sports
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
|
|
2
|
+
module Sports
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class NationalTeam
|
|
6
|
+
def self._search() CatalogDb::Metal::NationalTeam; end
|
|
7
|
+
|
|
8
|
+
###################
|
|
9
|
+
## core required delegates - use delegate generator - why? why not?
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### todo/fix
|
|
13
|
+
### upstream only support/require find !!!!!!!
|
|
14
|
+
|
|
15
|
+
## change core api to match( q ) only - why? why not?
|
|
16
|
+
## and make find and find! derivs???
|
|
17
|
+
def self.find( q ) _search.find( q ); end
|
|
18
|
+
def self.find!( q ) _search.find!( q ); end
|
|
19
|
+
end # class NationalTeam
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class Team
|
|
23
|
+
## note: "virtual" index lets you search clubs and/or national_teams (don't care)
|
|
24
|
+
|
|
25
|
+
## todo/check: rename to/use map_by! for array version - why? why not?
|
|
26
|
+
def self.find_by!( name:, league:, mods: nil )
|
|
27
|
+
if name.is_a?( Array )
|
|
28
|
+
recs = []
|
|
29
|
+
name.each do |q|
|
|
30
|
+
recs << _find_by!( name: q, league: league, mods: mods )
|
|
31
|
+
end
|
|
32
|
+
recs
|
|
33
|
+
else ## assume single name
|
|
34
|
+
_find_by!( name: name, league: league, mods: mods )
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
CLUB_NAME_RE = %r{^
|
|
40
|
+
(?<name>[^()]+?) ## non-greedy
|
|
41
|
+
(?:
|
|
42
|
+
\s+
|
|
43
|
+
\(
|
|
44
|
+
(?<code>[A-Z][A-Za-z]{2,3}) ## optional (country) code; support single code e.g. (A) - why? why not?
|
|
45
|
+
\)
|
|
46
|
+
)?
|
|
47
|
+
$}x ## note - allow (URU) and (Uru) - why? why not
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
###
|
|
51
|
+
# note: missing teams will get
|
|
52
|
+
## auto-created if possible
|
|
53
|
+
## only ambigious results (too many matches) raise expection!!!
|
|
54
|
+
def self._find_by!( name:, league:, mods: nil )
|
|
55
|
+
if mods && mods[ league.key ] && mods[ league.key ][ name ]
|
|
56
|
+
mods[ league.key ][ name ]
|
|
57
|
+
else
|
|
58
|
+
if league.clubs?
|
|
59
|
+
if league.intl? ## todo/fix: add intl? to ActiveRecord league!!!
|
|
60
|
+
###
|
|
61
|
+
## get country code from name
|
|
62
|
+
## e.g. Liverpool FC (ENG) or
|
|
63
|
+
## Liverpool FC (URU) etc.
|
|
64
|
+
|
|
65
|
+
## check for country code
|
|
66
|
+
if m=CLUB_NAME_RE.match( name )
|
|
67
|
+
if m[:code]
|
|
68
|
+
Club.find_by!( name: m[:name],
|
|
69
|
+
country: m[:code] )
|
|
70
|
+
else
|
|
71
|
+
Club.find!( name )
|
|
72
|
+
end
|
|
73
|
+
else
|
|
74
|
+
puts "!! PARSE ERROR - invalid club name; cannot match with CLUB_NAME_RE >#{team}<"
|
|
75
|
+
exit 1
|
|
76
|
+
end
|
|
77
|
+
else ## assume clubs in domestic/national league tournament
|
|
78
|
+
## note - search by league countries (may incl. more than one country
|
|
79
|
+
## e.g. us incl. ca, fr incl. mc, ch incl. li, etc.
|
|
80
|
+
rec = Club.find_by( name: name, league: league )
|
|
81
|
+
if rec.nil?
|
|
82
|
+
puts "auto-create (missing) club #{name}"
|
|
83
|
+
## todo/fix: add auto flag!!!!
|
|
84
|
+
### like in rounds!!!
|
|
85
|
+
## to track auto-created clubs
|
|
86
|
+
rec = Club.new( name: name )
|
|
87
|
+
rec.country = league.country ## fix: country kwarg not yet supported!!
|
|
88
|
+
pp rec
|
|
89
|
+
end
|
|
90
|
+
rec
|
|
91
|
+
end
|
|
92
|
+
else ## assume national teams (not clubs)
|
|
93
|
+
NationalTeam.find!( name )
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end # method _find_by!
|
|
97
|
+
end # class Team
|
|
98
|
+
end # module Sports
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
module Sports
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
class City
|
|
4
|
-
def self._search
|
|
5
|
-
SportDb::Import.world.cities
|
|
6
|
-
end
|
|
5
|
+
def self._search() CatalogDb::Metal::City; end
|
|
7
6
|
|
|
8
7
|
def self.match_by( name: )
|
|
9
8
|
_search.match_by( name: name )
|
|
@@ -12,9 +11,7 @@ end # class City
|
|
|
12
11
|
|
|
13
12
|
|
|
14
13
|
class Country
|
|
15
|
-
def self._search
|
|
16
|
-
SportDb::Import.world.countries
|
|
17
|
-
end
|
|
14
|
+
def self._search() CatalogDb::Metal::Country; end
|
|
18
15
|
|
|
19
16
|
def self.find_by( code: nil, name: nil )
|
|
20
17
|
## todo/fix upstream - change to find_by( code:, name:, ) too - why? why not?
|
|
@@ -23,7 +20,7 @@ class Country
|
|
|
23
20
|
elsif name && code.nil?
|
|
24
21
|
_search.find_by_name( name )
|
|
25
22
|
else
|
|
26
|
-
raise ArgumentError, "
|
|
23
|
+
raise ArgumentError, "Country#find_by - one (and only one arg) required - code: or name:"
|
|
27
24
|
end
|
|
28
25
|
end
|
|
29
26
|
|
data/lib/sportdb/search.rb
CHANGED
|
@@ -3,110 +3,27 @@ require 'sportdb/catalogs'
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
## move to base?
|
|
7
|
-
### shared basics for search
|
|
8
|
-
class SportSearch
|
|
9
|
-
class Search ## base search service - use/keep - why? why not?
|
|
10
|
-
attr_reader :service
|
|
11
|
-
def initialize( service ) @service = service; end
|
|
12
|
-
end # class Search
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
6
|
## our own code
|
|
19
7
|
require_relative 'search/version'
|
|
20
|
-
require_relative 'search/sport'
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
########
|
|
24
|
-
### setup sport search apis
|
|
25
|
-
class SportSearch
|
|
26
|
-
def initialize( leagues:,
|
|
27
|
-
national_teams:,
|
|
28
|
-
clubs:,
|
|
29
|
-
grounds:,
|
|
30
|
-
events:,
|
|
31
|
-
players:
|
|
32
|
-
)
|
|
33
|
-
@leagues = LeagueSearch.new( leagues )
|
|
34
|
-
@national_teams = NationalTeamSearch.new( national_teams )
|
|
35
|
-
@clubs = ClubSearch.new( clubs )
|
|
36
|
-
@events = EventSearch.new( events )
|
|
37
|
-
|
|
38
|
-
@grounds = GroundSearch.new( grounds )
|
|
39
|
-
|
|
40
|
-
@players = PlayerSearch.new( players )
|
|
41
|
-
|
|
42
|
-
## virtual deriv ("composite") search services
|
|
43
|
-
@teams = TeamSearch.new( clubs: @clubs,
|
|
44
|
-
national_teams: @national_teams )
|
|
45
|
-
@event_seasons = EventSeasonSearch.new( events: @events )
|
|
46
8
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def players() @players; end
|
|
56
|
-
|
|
57
|
-
def teams() @teams; end ## note - virtual table
|
|
58
|
-
def seasons() @event_seasons; end ## note - virtual table
|
|
59
|
-
|
|
60
|
-
def countries
|
|
61
|
-
puts
|
|
62
|
-
puts "[WARN] do NOT use catalog.countries, deprecated!!!"
|
|
63
|
-
puts " please, switch to new world.countries search service"
|
|
64
|
-
puts
|
|
65
|
-
exit 1
|
|
66
|
-
end
|
|
67
|
-
end # class SportSearch
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
class WorldSearch
|
|
71
|
-
def initialize( countries:, cities: )
|
|
72
|
-
## change service to country_service or such - why? why not?
|
|
73
|
-
## add city_service and such later
|
|
74
|
-
|
|
75
|
-
@countries = countries
|
|
76
|
-
@cities = cities
|
|
77
|
-
end
|
|
9
|
+
###
|
|
10
|
+
## add/augment core classes with search services
|
|
11
|
+
require_relative 'search/world'
|
|
12
|
+
require_relative 'search/sport-leagues'
|
|
13
|
+
require_relative 'search/sport-clubs'
|
|
14
|
+
require_relative 'search/sport-teams'
|
|
15
|
+
require_relative 'search/sport-events'
|
|
16
|
+
require_relative 'search/sport-more'
|
|
78
17
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def countries() @countries; end
|
|
82
|
-
def cities() @cities; end
|
|
83
|
-
end # class WorldSearch
|
|
18
|
+
##
|
|
19
|
+
## require_relative 'search/sport-history' ## to be done
|
|
84
20
|
|
|
85
21
|
|
|
86
22
|
#######
|
|
87
23
|
## add configuration
|
|
88
|
-
|
|
89
24
|
module SportDb
|
|
90
25
|
module Import
|
|
91
26
|
class Configuration
|
|
92
|
-
def world
|
|
93
|
-
@world ||= WorldSearch.new(
|
|
94
|
-
countries: CatalogDb::Metal::Country,
|
|
95
|
-
cities: CatalogDb::Metal::City,
|
|
96
|
-
)
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def catalog
|
|
100
|
-
@catalog ||= SportSearch.new(
|
|
101
|
-
leagues: CatalogDb::Metal::League,
|
|
102
|
-
national_teams: CatalogDb::Metal::NationalTeam,
|
|
103
|
-
clubs: CatalogDb::Metal::Club,
|
|
104
|
-
grounds: CatalogDb::Metal::Ground,
|
|
105
|
-
events: CatalogDb::Metal::EventInfo,
|
|
106
|
-
players: CatalogDb::Metal::Player, # note - via players.db !!!
|
|
107
|
-
)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
27
|
###
|
|
111
28
|
# find a better name for setting - why? why not?
|
|
112
29
|
# how about catalogdb or ???
|
|
@@ -131,18 +48,12 @@ class Configuration
|
|
|
131
48
|
|
|
132
49
|
@players_path
|
|
133
50
|
end
|
|
134
|
-
|
|
135
|
-
|
|
136
51
|
end # class Configuration
|
|
137
52
|
|
|
138
|
-
##
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
## lets you use
|
|
143
|
-
## SportDb::Import.configure do |config|
|
|
144
|
-
## config.catalog_path = './catalog.db'
|
|
145
|
-
## end
|
|
53
|
+
## lets you use
|
|
54
|
+
## SportDb::Import.configure do |config|
|
|
55
|
+
## config.catalog_path = './catalog.db'
|
|
56
|
+
## end
|
|
146
57
|
def self.configure() yield( config ); end
|
|
147
58
|
def self.config() @config ||= Configuration.new; end
|
|
148
59
|
end # module Import
|
|
@@ -160,28 +71,6 @@ end # module Sports
|
|
|
160
71
|
|
|
161
72
|
|
|
162
73
|
|
|
163
|
-
|
|
164
|
-
###
|
|
165
|
-
## add/augment core classes with search services
|
|
166
|
-
require_relative 'search/structs'
|
|
167
|
-
require_relative 'search/structs_world'
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
module SportDb
|
|
172
|
-
module Import
|
|
173
|
-
class Team
|
|
174
|
-
## add convenience lookup helper / method for name by season for now
|
|
175
|
-
## use clubs history - for now kept separate from struct - why? why not?
|
|
176
|
-
def name_by_season( season )
|
|
177
|
-
## note: returns / fallback to "regular" name if no records found in history
|
|
178
|
-
SportDb::Import.catalog.clubs_history.find_name_by( name: name, season: season ) || name
|
|
179
|
-
end
|
|
180
|
-
end # class Team
|
|
181
|
-
end # module Import
|
|
182
|
-
end # module SportDb
|
|
183
|
-
|
|
184
|
-
|
|
185
74
|
###
|
|
186
75
|
## add default/built-in catalog here - why? why not?
|
|
187
76
|
## todo/fix - set catalog_path on demand
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sportdb-search
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
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-
|
|
11
|
+
date: 2024-10-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: sportdb-catalogs
|
|
@@ -60,7 +60,8 @@ dependencies:
|
|
|
60
60
|
version: '4.1'
|
|
61
61
|
description: sportdb-search - find national teams, clubs, leagues & more
|
|
62
62
|
email: gerald.bauer@gmail.com
|
|
63
|
-
executables:
|
|
63
|
+
executables:
|
|
64
|
+
- fbq
|
|
64
65
|
extensions: []
|
|
65
66
|
extra_rdoc_files:
|
|
66
67
|
- CHANGELOG.md
|
|
@@ -71,11 +72,16 @@ files:
|
|
|
71
72
|
- Manifest.txt
|
|
72
73
|
- README.md
|
|
73
74
|
- Rakefile
|
|
75
|
+
- bin/fbq
|
|
74
76
|
- lib/sportdb/search.rb
|
|
75
|
-
- lib/sportdb/search/sport.rb
|
|
76
|
-
- lib/sportdb/search/
|
|
77
|
-
- lib/sportdb/search/
|
|
77
|
+
- lib/sportdb/search/sport-clubs.rb
|
|
78
|
+
- lib/sportdb/search/sport-events.rb
|
|
79
|
+
- lib/sportdb/search/sport-history.rb
|
|
80
|
+
- lib/sportdb/search/sport-leagues.rb
|
|
81
|
+
- lib/sportdb/search/sport-more.rb
|
|
82
|
+
- lib/sportdb/search/sport-teams.rb
|
|
78
83
|
- lib/sportdb/search/version.rb
|
|
84
|
+
- lib/sportdb/search/world.rb
|
|
79
85
|
homepage: https://github.com/sportdb/sport.db
|
|
80
86
|
licenses:
|
|
81
87
|
- Public Domain
|
data/lib/sportdb/search/sport.rb
DELETED
|
@@ -1,384 +0,0 @@
|
|
|
1
|
-
###
|
|
2
|
-
# sport search service api for leagues, clubs and more
|
|
3
|
-
#
|
|
4
|
-
# core api is:
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class SportSearch
|
|
8
|
-
|
|
9
|
-
class PlayerSearch < Search
|
|
10
|
-
###################
|
|
11
|
-
## core required delegates - use delegate generator - why? why not?
|
|
12
|
-
def match_by( name:, country: nil, year: nil )
|
|
13
|
-
@service.match_by( name: name,
|
|
14
|
-
country: country,
|
|
15
|
-
year: year )
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
###############
|
|
19
|
-
### more deriv support functions / helpers
|
|
20
|
-
def match( name ) match_by( name: name ); end
|
|
21
|
-
## add more here - why? why not?
|
|
22
|
-
end # class PlayerSearch
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
class LeagueSearch < Search
|
|
26
|
-
|
|
27
|
-
###################
|
|
28
|
-
## core required delegates - use delegate generator - why? why not?
|
|
29
|
-
def match_by( name: nil, code: nil, country: nil )
|
|
30
|
-
## todo/fix upstream - remove "generic" match_by() - why? why not?
|
|
31
|
-
###
|
|
32
|
-
if code && name.nil?
|
|
33
|
-
@service.match_by_code( code, country: country )
|
|
34
|
-
elsif name && code.nil?
|
|
35
|
-
@service.match_by_name( name, country: country )
|
|
36
|
-
else
|
|
37
|
-
raise ArgumentError, "LeagueSearch#match_by - one (and only one arg) required - code: or name:"
|
|
38
|
-
end
|
|
39
|
-
## @service.match_by( name: name,
|
|
40
|
-
## country: country )
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
## all-in-one query (name or code)
|
|
44
|
-
def match( q, country: nil )
|
|
45
|
-
@service.match_by_name_or_code( q, country: country )
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
###############
|
|
50
|
-
### more deriv support functions / helpers
|
|
51
|
-
def find!( q )
|
|
52
|
-
league = find( q )
|
|
53
|
-
if league.nil?
|
|
54
|
-
puts "** !!! ERROR - no league match found for >#{q}<, add to leagues table; sorry"
|
|
55
|
-
exit 1
|
|
56
|
-
end
|
|
57
|
-
league
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def find( q )
|
|
61
|
-
league = nil
|
|
62
|
-
recs = match( q )
|
|
63
|
-
# pp m
|
|
64
|
-
|
|
65
|
-
if recs.empty?
|
|
66
|
-
## fall through/do nothing
|
|
67
|
-
elsif recs.size > 1
|
|
68
|
-
puts "** !!! ERROR - ambigious league query; too many leagues (#{recs.size}) found:"
|
|
69
|
-
pp recs
|
|
70
|
-
exit 1
|
|
71
|
-
else
|
|
72
|
-
league = recs[0]
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
league
|
|
76
|
-
end
|
|
77
|
-
end # class LeagueSearch
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
class GroundSearch < Search
|
|
82
|
-
###################
|
|
83
|
-
## core required delegates - use delegate generator - why? why not?
|
|
84
|
-
def match_by( name:, country: nil, city: nil )
|
|
85
|
-
@service.match_by( name: name,
|
|
86
|
-
country: country,
|
|
87
|
-
city: city )
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
###############
|
|
91
|
-
### more deriv support functions / helpers
|
|
92
|
-
def match( name ) match_by( name: name ); end
|
|
93
|
-
## add more here - why? why not?
|
|
94
|
-
end # class GroundSearch
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
class NationalTeamSearch < Search
|
|
99
|
-
###################
|
|
100
|
-
## core required delegates - use delegate generator - why? why not?
|
|
101
|
-
|
|
102
|
-
## changle core api to match( q ) only - why? why not?
|
|
103
|
-
## and make find and find! derivs???
|
|
104
|
-
def find( q ) @service.find( q ); end
|
|
105
|
-
def find!( q ) @service.find!( q ); end
|
|
106
|
-
end # class NationalTeamSearch
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
class ClubSearch < Search
|
|
110
|
-
###################
|
|
111
|
-
## core required delegates - use delegate generator - why? why not?
|
|
112
|
-
|
|
113
|
-
## add mods here - why? why not?
|
|
114
|
-
|
|
115
|
-
def match_by( name:, country: nil,
|
|
116
|
-
league: nil,
|
|
117
|
-
mods: nil )
|
|
118
|
-
## for now assume "global" mods - checks only for name
|
|
119
|
-
##
|
|
120
|
-
if mods && mods[ name ]
|
|
121
|
-
club = mods[ name ]
|
|
122
|
-
return [club] # note: wrap (single record) in array
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
## note: add "auto-magic" country calculation via league record
|
|
126
|
-
## if league is a national league for football clubs
|
|
127
|
-
if league
|
|
128
|
-
raise ArgumentError, "match_by - league AND country NOT supported; sorry" if country
|
|
129
|
-
### find countries via league
|
|
130
|
-
### support league.intl? too - why? why not?
|
|
131
|
-
### or only nationa league
|
|
132
|
-
raise ArgumentError, "match_by - league - only national club leagues supported (not int'l or national teams for now); sorry" unless league.national? && league.clubs?
|
|
133
|
-
|
|
134
|
-
### calc countries
|
|
135
|
-
### uses "global" func in sports-catalogs for now
|
|
136
|
-
## move code here - why? why not?
|
|
137
|
-
country = find_countries_for_league( league )
|
|
138
|
-
@service.match_by( name: name,
|
|
139
|
-
country: country )
|
|
140
|
-
else
|
|
141
|
-
@service.match_by( name: name,
|
|
142
|
-
country: country )
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
## todo/fix/check: use rename to find_canon or find_canonical() or something??
|
|
148
|
-
## remove (getting used?) - why? why not?
|
|
149
|
-
# def []( name ) ## lookup by canoncial name only; todo/fix: add find alias why? why not?
|
|
150
|
-
# puts "WARN!! do not use ClubIndex#[] for lookup >#{name}< - will get removed!!!"
|
|
151
|
-
# @clubs[ name ]
|
|
152
|
-
# end
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
###############
|
|
156
|
-
### more deriv support functions / helpers
|
|
157
|
-
def match( name ) match_by( name: name ); end
|
|
158
|
-
|
|
159
|
-
##########
|
|
160
|
-
# "legacy" finders - return zero or one club
|
|
161
|
-
## (if more than one match, exit/raise error/exception)
|
|
162
|
-
def find( name ) find_by( name: name ); end
|
|
163
|
-
def find!( name ) find_by!( name: name ); end
|
|
164
|
-
|
|
165
|
-
## find - always returns a single record / match or nil
|
|
166
|
-
## if there is more than one match than find aborts / fails
|
|
167
|
-
def find_by!( name:, country: nil,
|
|
168
|
-
league: nil ) ## todo/fix: add international or league flag?
|
|
169
|
-
club = find_by( name: name,
|
|
170
|
-
country: country,
|
|
171
|
-
league: league )
|
|
172
|
-
|
|
173
|
-
if club.nil?
|
|
174
|
-
puts "** !!! ERROR - no match for club >#{name}<"
|
|
175
|
-
exit 1
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
club
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
def find_by( name:, country: nil,
|
|
183
|
-
league: nil ) ## todo/fix: add international or league flag?
|
|
184
|
-
## note: allow passing in of country key too (auto-counvert)
|
|
185
|
-
## and country struct too
|
|
186
|
-
## - country assumes / allows the country key or fifa code for now
|
|
187
|
-
recs = match_by( name: name,
|
|
188
|
-
country: country,
|
|
189
|
-
league: league )
|
|
190
|
-
|
|
191
|
-
club = nil
|
|
192
|
-
if recs.empty?
|
|
193
|
-
## puts "** !!! WARN !!! no match for club >#{name}<"
|
|
194
|
-
elsif recs.size > 1
|
|
195
|
-
puts "** !!! ERROR - too many matches (#{recs.size}) for club >#{name}<:"
|
|
196
|
-
pp recs
|
|
197
|
-
exit 1
|
|
198
|
-
else # bingo; match - assume size == 1
|
|
199
|
-
club = recs[0]
|
|
200
|
-
end
|
|
201
|
-
|
|
202
|
-
club
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
#######
|
|
207
|
-
# more support methods
|
|
208
|
-
def build_mods( mods )
|
|
209
|
-
## e.g.
|
|
210
|
-
## { 'Arsenal | Arsenal FC' => 'Arsenal, ENG',
|
|
211
|
-
## 'Liverpool | Liverpool FC' => 'Liverpool, ENG',
|
|
212
|
-
## 'Barcelona' => 'Barcelona, ESP',
|
|
213
|
-
## 'Valencia' => 'Valencia, ESP' }
|
|
214
|
-
|
|
215
|
-
mods.reduce({}) do |h,(club_names, club_line)|
|
|
216
|
-
|
|
217
|
-
values = club_line.split( ',' )
|
|
218
|
-
values = values.map { |value| value.strip } ## strip all spaces
|
|
219
|
-
|
|
220
|
-
## todo/fix: make sure country is present !!!!
|
|
221
|
-
club_name, country_name = values
|
|
222
|
-
club = find_by!( name: club_name, country: country_name )
|
|
223
|
-
|
|
224
|
-
values = club_names.split( '|' )
|
|
225
|
-
values = values.map { |value| value.strip } ## strip all spaces
|
|
226
|
-
|
|
227
|
-
values.each do |club_name|
|
|
228
|
-
h[club_name] = club
|
|
229
|
-
end
|
|
230
|
-
h
|
|
231
|
-
end
|
|
232
|
-
end
|
|
233
|
-
end # class ClubSearch
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
## todo/check - change to EventInfoSearch - why? why not?
|
|
238
|
-
class EventSearch < Search
|
|
239
|
-
##
|
|
240
|
-
## todo - eventinfo search still open / up for change
|
|
241
|
-
|
|
242
|
-
###################
|
|
243
|
-
## core required delegates - use delegate generator - why? why not?
|
|
244
|
-
def seasons( league )
|
|
245
|
-
@service.seasons( league )
|
|
246
|
-
end
|
|
247
|
-
def find_by( league:, season: )
|
|
248
|
-
@service.find_by( league: league,
|
|
249
|
-
season: season )
|
|
250
|
-
end
|
|
251
|
-
end # class EventSearch
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
####
|
|
255
|
-
## virtual table for season lookup
|
|
256
|
-
## note - use EventSeaon to avoid name conflict with (global) Season class
|
|
257
|
-
## find a better name SeasonInfo or SeasonFinder or SeasonStore
|
|
258
|
-
## or SeasonQ or ??
|
|
259
|
-
class EventSeasonSearch
|
|
260
|
-
def initialize( events: )
|
|
261
|
-
@events = events
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
###############
|
|
265
|
-
## todo/fix: find a better algo to guess season for date!!!
|
|
266
|
-
##
|
|
267
|
-
def find_by( date:, league: )
|
|
268
|
-
date = Date.strptime( date, '%Y-%m-%d' ) if date.is_a?( String )
|
|
269
|
-
|
|
270
|
-
infos = @events.seasons( league )
|
|
271
|
-
|
|
272
|
-
infos.each do |info|
|
|
273
|
-
return info.season if info.include?( date )
|
|
274
|
-
end
|
|
275
|
-
nil
|
|
276
|
-
end
|
|
277
|
-
end # class EventSeasonSearch
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
######
|
|
281
|
-
### add virtual team search ( clubs + national teams)
|
|
282
|
-
## note: no record base!!!!!
|
|
283
|
-
class TeamSearch
|
|
284
|
-
## note: "virtual" index lets you search clubs and/or national_teams (don't care)
|
|
285
|
-
|
|
286
|
-
def initialize( clubs:, national_teams: )
|
|
287
|
-
@clubs = clubs
|
|
288
|
-
@national_teams = national_teams
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
## todo/check: rename to/use map_by! for array version - why? why not?
|
|
292
|
-
def find_by!( name:, league:, mods: nil )
|
|
293
|
-
if name.is_a?( Array )
|
|
294
|
-
recs = []
|
|
295
|
-
name.each do |q|
|
|
296
|
-
recs << _find_by!( name: q, league: league, mods: mods )
|
|
297
|
-
end
|
|
298
|
-
recs
|
|
299
|
-
else ## assume single name
|
|
300
|
-
_find_by!( name: name, league: league, mods: mods )
|
|
301
|
-
end
|
|
302
|
-
end
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
CLUB_NAME_RE = %r{^
|
|
307
|
-
(?<name>[^()]+?) ## non-greedy
|
|
308
|
-
(?:
|
|
309
|
-
\s+
|
|
310
|
-
\(
|
|
311
|
-
(?<code>[A-Z][A-Za-z]{2,3}) ## optional (country) code; support single code e.g. (A) - why? why not?
|
|
312
|
-
\)
|
|
313
|
-
)?
|
|
314
|
-
$}x ## note - allow (URU) and (Uru) - why? why not
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
###
|
|
318
|
-
# note: missing teams will get
|
|
319
|
-
## auto-created if possible
|
|
320
|
-
## only ambigious results (too many matches) raise expection!!!
|
|
321
|
-
def _find_by!( name:, league:, mods: nil )
|
|
322
|
-
if mods && mods[ league.key ] && mods[ league.key ][ name ]
|
|
323
|
-
mods[ league.key ][ name ]
|
|
324
|
-
else
|
|
325
|
-
if league.clubs?
|
|
326
|
-
if league.intl? ## todo/fix: add intl? to ActiveRecord league!!!
|
|
327
|
-
###
|
|
328
|
-
## get country code from name
|
|
329
|
-
## e.g. Liverpool FC (ENG) or
|
|
330
|
-
## Liverpool FC (URU) etc.
|
|
331
|
-
|
|
332
|
-
## check for country code
|
|
333
|
-
if m=CLUB_NAME_RE.match( name )
|
|
334
|
-
if m[:code]
|
|
335
|
-
@clubs.find_by!( name: m[:name],
|
|
336
|
-
country: m[:code] )
|
|
337
|
-
else
|
|
338
|
-
@clubs.find!( name )
|
|
339
|
-
end
|
|
340
|
-
else
|
|
341
|
-
puts "!! PARSE ERROR - invalid club name; cannot match with CLUB_NAME_RE >#{team}<"
|
|
342
|
-
exit 1
|
|
343
|
-
end
|
|
344
|
-
else ## assume clubs in domestic/national league tournament
|
|
345
|
-
## note - search by league countries (may incl. more than one country
|
|
346
|
-
## e.g. us incl. ca, fr incl. mc, ch incl. li, etc.
|
|
347
|
-
rec = @clubs.find_by( name: name, league: league )
|
|
348
|
-
if rec.nil?
|
|
349
|
-
puts "auto-create (missing) club #{name}"
|
|
350
|
-
## todo/fix: add auto flag!!!!
|
|
351
|
-
### like in rounds!!!
|
|
352
|
-
## to track auto-created clubs
|
|
353
|
-
rec = SportDb::Import::Club.new( name: name )
|
|
354
|
-
rec.country = league.country ## fix: country kwarg not yet supported!!
|
|
355
|
-
pp rec
|
|
356
|
-
end
|
|
357
|
-
rec
|
|
358
|
-
end
|
|
359
|
-
else ## assume national teams (not clubs)
|
|
360
|
-
@national_teams.find!( name )
|
|
361
|
-
end
|
|
362
|
-
end
|
|
363
|
-
end # method _find_by!
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
def _find_by_v0!( name:, league:, mods: nil )
|
|
367
|
-
if mods && mods[ league.key ] && mods[ league.key ][ name ]
|
|
368
|
-
mods[ league.key ][ name ]
|
|
369
|
-
else
|
|
370
|
-
if league.clubs?
|
|
371
|
-
if league.intl? ## todo/fix: add intl? to ActiveRecord league!!!
|
|
372
|
-
@clubs.find!( name )
|
|
373
|
-
else ## assume clubs in domestic/national league tournament
|
|
374
|
-
## note - search by league countries (may incl. more than one country
|
|
375
|
-
## e.g. us incl. ca, fr incl. mc, ch incl. li, etc.
|
|
376
|
-
@clubs.find_by!( name: name, league: league )
|
|
377
|
-
end
|
|
378
|
-
else ## assume national teams (not clubs)
|
|
379
|
-
@national_teams.find!( name )
|
|
380
|
-
end
|
|
381
|
-
end
|
|
382
|
-
end # method _find_by!
|
|
383
|
-
end # class TeamSearch
|
|
384
|
-
end # class SportSearch
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
###
|
|
2
|
-
# note - extend all structs for with search api
|
|
3
|
-
#
|
|
4
|
-
# todo - add more helpers!!!!
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# todo - fix - move all non-core search functionality/machinery
|
|
8
|
-
# over here - why? why not?
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
module Sports
|
|
13
|
-
###
|
|
14
|
-
## todo/fix - add find_by( code: ), find_by( name: )
|
|
15
|
-
## split - why? why not?
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class League
|
|
19
|
-
def self._search #### use service/api or such - why? why not?
|
|
20
|
-
SportDb::Import.catalog.leagues
|
|
21
|
-
end
|
|
22
|
-
def self.match_by( name: nil, code: nil,
|
|
23
|
-
country: nil )
|
|
24
|
-
_search.match_by( name: name, code: code,
|
|
25
|
-
country: country )
|
|
26
|
-
end
|
|
27
|
-
def self.match( q, country: nil )
|
|
28
|
-
_search.match( q, country: country )
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def self.find!( q ) _search.find!( q ); end
|
|
32
|
-
def self.find( q ) _search_find( q ); end
|
|
33
|
-
end # class League
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
class NationalTeam
|
|
37
|
-
def self._search #### use service/api or such - why? why not?
|
|
38
|
-
SportDb::Import.catalog.national_teams
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def self.find( q ) _search.find( q ); end
|
|
42
|
-
def self.find!( q ) _search_find!( q ); end
|
|
43
|
-
end # class NationalTeam
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class Club
|
|
48
|
-
def self._search #### use service/api or such - why? why not?
|
|
49
|
-
SportDb::Import.catalog.clubs
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def self.match_by( name:, country: nil,
|
|
53
|
-
league: nil,
|
|
54
|
-
mods: nil )
|
|
55
|
-
_search.match_by( name: name, country: country,
|
|
56
|
-
league: league, mods: mods )
|
|
57
|
-
end
|
|
58
|
-
def self.match( name ) match_by( name: name ); end
|
|
59
|
-
|
|
60
|
-
def self.find( name ) _search.find_by( name: name ); end
|
|
61
|
-
def self.find!( name ) _search.find_by!( name: name ); end
|
|
62
|
-
|
|
63
|
-
def self.find_by!( name:, country: nil,
|
|
64
|
-
league: nil )
|
|
65
|
-
_search.find_by!( name: name, country: country,
|
|
66
|
-
league: league )
|
|
67
|
-
end
|
|
68
|
-
def self.find_by( name:, country: nil,
|
|
69
|
-
league: nil )
|
|
70
|
-
_search.find_by( name: name, country: country,
|
|
71
|
-
league: league )
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def self.build_mods( mods )
|
|
75
|
-
_search.build_mods( mods )
|
|
76
|
-
end
|
|
77
|
-
end # class Club
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
class Team
|
|
81
|
-
def self._search
|
|
82
|
-
SportDb::Import.catalog.teams
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
## todo/check: rename to/use map_by! for array version - why? why not?
|
|
86
|
-
def self.find_by!( name:, league:, mods: nil )
|
|
87
|
-
_search.find_by!( name: name,
|
|
88
|
-
league: league,
|
|
89
|
-
mods: mods )
|
|
90
|
-
end
|
|
91
|
-
end # class Team
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
class EventInfo
|
|
95
|
-
def self._search
|
|
96
|
-
SportDb::Import.catalog.events
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def self.find_by( league:, season: )
|
|
100
|
-
_search.find_by( league: league,
|
|
101
|
-
season: season )
|
|
102
|
-
end
|
|
103
|
-
end # class EventInfo
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
class Ground
|
|
108
|
-
def self._search
|
|
109
|
-
SportDb::Import.catalog.grounds
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
def self.match_by( name:, country: nil, city: nil )
|
|
113
|
-
_search.match_by( name: name,
|
|
114
|
-
country: country,
|
|
115
|
-
city: city )
|
|
116
|
-
end
|
|
117
|
-
end # class Ground
|
|
118
|
-
end # module Sports
|