sportdb-formats 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,372 +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 Search ## base search service - use/keep - why? why not?
10
- def initialize( service ) @service = service; end
11
- end # class Search
12
-
13
-
14
- class PlayerSearch < Search
15
- ###################
16
- ## core required delegates - use delegate generator - why? why not?
17
- def match_by( name:, country: nil, year: nil )
18
- @service.match_by( name: name,
19
- country: country,
20
- year: year )
21
- end
22
-
23
- ###############
24
- ### more deriv support functions / helpers
25
- def match( name ) match_by( name: name ); end
26
- ## add more here - why? why not?
27
- end # class PlayerSearch
28
-
29
-
30
- class LeagueSearch < Search
31
-
32
- ###################
33
- ## core required delegates - use delegate generator - why? why not?
34
- def match_by( name: nil, code: nil, country: nil )
35
- ## todo/fix upstream - remove "generic" match_by() - why? why not?
36
- ###
37
- if code && name.nil?
38
- @service.match_by_code( code, country: country )
39
- elsif name && code.nil?
40
- @service.match_by_name( name, country: country )
41
- else
42
- raise ArgumentError, "LeagueSearch#match_by - one (and only one arg) required - code: or name:"
43
- end
44
- ## @service.match_by( name: name,
45
- ## country: country )
46
- end
47
-
48
- ## all-in-one query (name or code)
49
- def match( q, country: nil )
50
- @service.match_by_name_or_code( q, country: country )
51
- end
52
-
53
-
54
- ###############
55
- ### more deriv support functions / helpers
56
- def find!( q )
57
- league = find( q )
58
- if league.nil?
59
- puts "** !!! ERROR - no league match found for >#{q}<, add to leagues table; sorry"
60
- exit 1
61
- end
62
- league
63
- end
64
-
65
- def find( q )
66
- league = nil
67
- recs = match( q )
68
- # pp m
69
-
70
- if recs.empty?
71
- ## fall through/do nothing
72
- elsif recs.size > 1
73
- puts "** !!! ERROR - ambigious league query; too many leagues (#{recs.size}) found:"
74
- pp recs
75
- exit 1
76
- else
77
- league = recs[0]
78
- end
79
-
80
- league
81
- end
82
- end # class LeagueSearch
83
-
84
-
85
-
86
- class GroundSearch < Search
87
- ###################
88
- ## core required delegates - use delegate generator - why? why not?
89
- def match_by( name:, country: nil, city: nil )
90
- @service.match_by( name: name,
91
- country: country,
92
- city: city )
93
- end
94
-
95
- ###############
96
- ### more deriv support functions / helpers
97
- def match( name ) match_by( name: name ); end
98
- ## add more here - why? why not?
99
- end # class GroundSearch
100
-
101
-
102
-
103
- class NationalTeamSearch < Search
104
- ###################
105
- ## core required delegates - use delegate generator - why? why not?
106
-
107
- ## changle core api to match( q ) only - why? why not?
108
- ## and make find and find! derivs???
109
- def find( q ) @service.find( q ); end
110
- def find!( q ) @service.find!( q ); end
111
- end # class NationalTeamSearch
112
-
113
-
114
- class ClubSearch < Search
115
- ###################
116
- ## core required delegates - use delegate generator - why? why not?
117
-
118
- ## add mods here - why? why not?
119
-
120
- def match_by( name:, country: nil,
121
- league: nil,
122
- mods: nil )
123
- ## for now assume "global" mods - checks only for name
124
- ##
125
- if mods && mods[ name ]
126
- club = mods[ name ]
127
- return [club] # note: wrap (single record) in array
128
- end
129
-
130
- ## note: add "auto-magic" country calculation via league record
131
- ## if league is a national league for football clubs
132
- if league
133
- raise ArgumentError, "match_by - league AND country NOT supported; sorry" if country
134
- ### find countries via league
135
- ### support league.intl? too - why? why not?
136
- ### or only nationa league
137
- raise ArgumentError, "match_by - league - only national club leagues supported (not int'l or national teams for now); sorry" unless league.national? && league.clubs?
138
-
139
- ### calc countries
140
- ### uses "global" func in sports-catalogs for now
141
- ## move code here - why? why not?
142
- country = find_countries_for_league( league )
143
- @service.match_by( name: name,
144
- country: country )
145
- else
146
- @service.match_by( name: name,
147
- country: country )
148
- end
149
- end
150
-
151
-
152
- ## todo/fix/check: use rename to find_canon or find_canonical() or something??
153
- ## remove (getting used?) - why? why not?
154
- # def []( name ) ## lookup by canoncial name only; todo/fix: add find alias why? why not?
155
- # puts "WARN!! do not use ClubIndex#[] for lookup >#{name}< - will get removed!!!"
156
- # @clubs[ name ]
157
- # end
158
-
159
-
160
- ###############
161
- ### more deriv support functions / helpers
162
- def match( name ) match_by( name: name ); end
163
-
164
- ##########
165
- # "legacy" finders - return zero or one club
166
- ## (if more than one match, exit/raise error/exception)
167
- def find( name ) find_by( name: name ); end
168
- def find!( name ) find_by!( name: name ); end
169
-
170
- ## find - always returns a single record / match or nil
171
- ## if there is more than one match than find aborts / fails
172
- def find_by!( name:, country: nil,
173
- league: nil ) ## todo/fix: add international or league flag?
174
- club = find_by( name: name,
175
- country: country,
176
- league: league )
177
-
178
- if club.nil?
179
- puts "** !!! ERROR - no match for club >#{name}<"
180
- exit 1
181
- end
182
-
183
- club
184
- end
185
-
186
-
187
- def find_by( name:, country: nil,
188
- league: nil ) ## todo/fix: add international or league flag?
189
- ## note: allow passing in of country key too (auto-counvert)
190
- ## and country struct too
191
- ## - country assumes / allows the country key or fifa code for now
192
- recs = match_by( name: name,
193
- country: country,
194
- league: league )
195
-
196
- club = nil
197
- if recs.empty?
198
- ## puts "** !!! WARN !!! no match for club >#{name}<"
199
- elsif recs.size > 1
200
- puts "** !!! ERROR - too many matches (#{recs.size}) for club >#{name}<:"
201
- pp recs
202
- exit 1
203
- else # bingo; match - assume size == 1
204
- club = recs[0]
205
- end
206
-
207
- club
208
- end
209
-
210
-
211
- #######
212
- # more support methods
213
- def build_mods( mods )
214
- ## e.g.
215
- ## { 'Arsenal | Arsenal FC' => 'Arsenal, ENG',
216
- ## 'Liverpool | Liverpool FC' => 'Liverpool, ENG',
217
- ## 'Barcelona' => 'Barcelona, ESP',
218
- ## 'Valencia' => 'Valencia, ESP' }
219
-
220
- mods.reduce({}) do |h,(club_names, club_line)|
221
-
222
- values = club_line.split( ',' )
223
- values = values.map { |value| value.strip } ## strip all spaces
224
-
225
- ## todo/fix: make sure country is present !!!!
226
- club_name, country_name = values
227
- club = find_by!( name: club_name, country: country_name )
228
-
229
- values = club_names.split( '|' )
230
- values = values.map { |value| value.strip } ## strip all spaces
231
-
232
- values.each do |club_name|
233
- h[club_name] = club
234
- end
235
- h
236
- end
237
- end
238
- end # class ClubSearch
239
-
240
-
241
-
242
- ## todo/check - change to EventInfoSearch - why? why not?
243
- class EventSearch < Search
244
- ##
245
- ## todo - eventinfo search still open / up for change
246
-
247
- ###################
248
- ## core required delegates - use delegate generator - why? why not?
249
- def seasons( league )
250
- @service.seasons( league )
251
- end
252
- def find_by( league:, season: )
253
- @service.find_by( league: league,
254
- season: season )
255
- end
256
- end # class EventSearch
257
-
258
-
259
- ####
260
- ## virtual table for season lookup
261
- ## note - use EventSeaon to avoid name conflict with (global) Season class
262
- ## find a better name SeasonInfo or SeasonFinder or SeasonStore
263
- ## or SeasonQ or ??
264
- class EventSeasonSearch
265
- def initialize( events: )
266
- @events = events
267
- end
268
-
269
- ###############
270
- ## todo/fix: find a better algo to guess season for date!!!
271
- ##
272
- def find_by( date:, league: )
273
- date = Date.strptime( date, '%Y-%m-%d' ) if date.is_a?( String )
274
-
275
- infos = @events.seasons( league )
276
-
277
- infos.each do |info|
278
- return info.season if info.include?( date )
279
- end
280
- nil
281
- end
282
- end # class EventSeasonSearch
283
-
284
-
285
- ######
286
- ### add virtual team search ( clubs + national teams)
287
- ## note: no record base!!!!!
288
- class TeamSearch
289
- ## note: "virtual" index lets you search clubs and/or national_teams (don't care)
290
-
291
- def initialize( clubs:, national_teams: )
292
- @clubs = clubs
293
- @national_teams = national_teams
294
- end
295
-
296
- ## todo/check: rename to/use map_by! for array version - why? why not?
297
- def find_by!( name:, league:, mods: nil )
298
- if name.is_a?( Array )
299
- recs = []
300
- name.each do |q|
301
- recs << _find_by!( name: q, league: league, mods: mods )
302
- end
303
- recs
304
- else ## assume single name
305
- _find_by!( name: name, league: league, mods: mods )
306
- end
307
- end
308
-
309
-
310
- def _find_by!( name:, league:, mods: nil )
311
- if mods && mods[ league.key ] && mods[ league.key ][ name ]
312
- mods[ league.key ][ name ]
313
- else
314
- if league.clubs?
315
- if league.intl? ## todo/fix: add intl? to ActiveRecord league!!!
316
- @clubs.find!( name )
317
- else ## assume clubs in domestic/national league tournament
318
- ## note - search by league countries (may incl. more than one country
319
- ## e.g. us incl. ca, fr incl. mc, ch incl. li, etc.
320
- @clubs.find_by!( name: name, league: league )
321
- end
322
- else ## assume national teams (not clubs)
323
- @national_teams.find!( name )
324
- end
325
- end
326
- end # method _find_by!
327
- end # class TeamSearch
328
-
329
-
330
-
331
- def initialize( leagues:,
332
- national_teams:,
333
- clubs:,
334
- grounds:,
335
- events:,
336
- players:
337
- )
338
- @leagues = LeagueSearch.new( leagues )
339
- @national_teams = NationalTeamSearch.new( national_teams )
340
- @clubs = ClubSearch.new( clubs )
341
- @events = EventSearch.new( events )
342
-
343
- @grounds = GroundSearch.new( grounds )
344
-
345
- @players = PlayerSearch.new( players )
346
-
347
- ## virtual deriv ("composite") search services
348
- @teams = TeamSearch.new( clubs: @clubs,
349
- national_teams: @national_teams )
350
- @event_seasons = EventSeasonSearch.new( events: @events )
351
-
352
- end
353
-
354
- def countries
355
- puts
356
- puts "[WARN] do NOT use catalog.countries, deprecated!!!"
357
- puts " please, switch to new world.countries search service"
358
- puts
359
- exit 1
360
- end
361
-
362
- def leagues() @leagues; end
363
- def national_teams() @national_teams; end
364
- def clubs() @clubs; end
365
- def events() @events; end
366
- def grounds() @grounds; end
367
-
368
- def players() @players; end
369
-
370
- def teams() @teams; end ## note - virtual table
371
- def seasons() @event_seasons; end ## note - virtual table
372
- end # class SportSearch
@@ -1,116 +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
- class Country
15
- def self._search #### use service/api or such - why? why not?
16
- SportDb::Import.world.countries
17
- end
18
- def self.find_by( code: nil, name: nil )
19
- _search.find_by( code: code, name: name )
20
- end
21
-
22
- def self.find( q ) ## find by code (first) or name (second)
23
- _search.find( q )
24
- end
25
-
26
- def self.parse_heading( line )
27
- ## fix - move parse code here from search - why? why not?
28
- _search.parse( line )
29
- end
30
-
31
- ## add alternate names/aliases
32
- class << self
33
- alias_method :[], :find ### keep shortcut - why? why not?
34
- alias_method :heading, :parse_heading
35
- end
36
-
37
-
38
- # open question - what name to use build or parse_line or ?
39
- # or parse_recs for CountryReader?
40
- # remove CountryReader helper methods - why? why not?
41
- # use parse_heading/heading for now !!!
42
- #
43
- # def self.parse( line ) or build( line ) ??
44
- # SportDb::Import.world.countries.parse( line )
45
- # end
46
- #
47
- # !!!! note - conflict with
48
- # def self.read( path ) CountryReader.read( path ); end
49
- # def self.parse( txt ) CountryReader.parse( txt ); end
50
- #
51
- end # class Country
52
-
53
-
54
- ###
55
- ## todo/fix - add find_by( code: ), find_by( name: )
56
- ## split - why? why not?
57
-
58
-
59
- class League
60
- def self._search #### use service/api or such - why? why not?
61
- SportDb::Import.catalog.leagues
62
- end
63
- def self.match_by( name: nil, code: nil,
64
- country: nil )
65
- _search.match_by( name: name, code: code,
66
- country: country )
67
- end
68
- def self.match( q ) _search.match( q ); end
69
-
70
- def self.find!( q ) _search.find!( q ); end
71
- def self.find( q ) _search_find( q ); end
72
- end # class League
73
-
74
-
75
- class NationalTeam
76
- def self._search #### use service/api or such - why? why not?
77
- SportDb::Import.catalog.national_teams
78
- end
79
-
80
- def self.find( q ) _search.find( q ); end
81
- def self.find!( q ) _search_find!( q ); end
82
- end # class NationalTeam
83
-
84
-
85
- class Club
86
- def self._search #### use service/api or such - why? why not?
87
- SportDb::Import.catalog.clubs
88
- end
89
-
90
- def self.match_by( name:, country: nil,
91
- league: nil,
92
- mods: nil )
93
- _search.match_by( name: name, country: country,
94
- league: league, mods: mods )
95
- end
96
- def self.match( name ) match_by( name: name ); end
97
-
98
- def self.find( name ) _search.find_by( name: name ); end
99
- def self.find!( name ) _search.find_by!( name: name ); end
100
-
101
- def self.find_by!( name:, country: nil,
102
- league: nil )
103
- _search.find_by!( name: name, country: country,
104
- league: league )
105
- end
106
- def self.find_by( name:, country: nil,
107
- league: nil )
108
- _search.find_by( name: name, country: country,
109
- league: league )
110
- end
111
-
112
- def self.build_mods( mods )
113
- _search_build_mods( mods )
114
- end
115
- end # class Club
116
- end # module Sports
@@ -1,157 +0,0 @@
1
- ###
2
- # world search service api for countries and more
3
- #
4
- # core api is:
5
- # - world.countries.find_by_code
6
- # - .find_by_name
7
-
8
-
9
- class WorldSearch
10
-
11
- class CitySearch
12
- def initialize( service ) @service = service; end
13
-
14
- ###################
15
- ## core required delegates - use delegate generator - why? why not?
16
- def match_by( name: )
17
- @service.match_by( name: name )
18
- end
19
- end # class CitySearch
20
-
21
-
22
- class CountrySearch
23
- def initialize( service ) @service = service; end
24
-
25
- ###################
26
- ## core required delegates - use delegate generator - why? why not?
27
- def find_by_code( code )
28
- puts "!! DEPRECATED - use CountrySearch#find_by( code: )"
29
- @service.find_by_code( code )
30
- end
31
- def find_by_name( name )
32
- puts "!! DEPRECATED - use CountrySearch#find_by( name: )"
33
- @service.find_by_name( name )
34
- end
35
-
36
- def find_by( code: nil, name: nil )
37
- ## todo/fix upstream - change to find_by( code:, name:, ) too
38
- if code && name.nil?
39
- @service.find_by_code( code )
40
- elsif name && code.nil?
41
- @service.find_by_name( name )
42
- else
43
- raise ArgumentError, "CountrySearch#find_by - one (and only one arg) required - code: or name:"
44
- end
45
- end
46
-
47
- def find( q )
48
- @service.find_by_name_or_code( q )
49
- end
50
- alias_method :[], :find ### keep shortcut - why? why not?
51
-
52
-
53
- ###############
54
- ### more deriv support functions / helpers
55
-
56
- ###
57
- ## split/parse country line
58
- ##
59
- ## split on bullet e.g.
60
- ## split into name and code with regex - make code optional
61
- ##
62
- ## Examples:
63
- ## Österreich • Austria (at)
64
- ## Österreich • Austria
65
- ## Austria
66
- ## Deutschland (de) • Germany
67
- ##
68
- ## todo/check: support more formats - why? why not?
69
- ## e.g. Austria, AUT (e.g. with comma - why? why not?)
70
- def parse( line )
71
- values = line.split( '•' ) ## use/support multi-lingual separator
72
- country = nil
73
- values.each do |value|
74
- value = value.strip
75
- ## check for trailing country code e.g. (at), (eng), etc
76
- ## allow code 1 to 5 for now - northern cyprus(fifa) with 5 letters?.
77
- ## add/allow gb-eng, gb-wal (official iso2!!), in the future too - why? why not?
78
- if value =~ /[ ]+\((?<code>[A-Za-z]{1,5})\)$/ ## e.g. Austria (at)
79
- code = $~[:code]
80
- name = value[0...(value.size-code.size-2)].strip ## note: add -2 for brackets
81
- candidates = [ find_by( code: code ), find_by( name: name ) ]
82
- if candidates[0].nil?
83
- puts "** !!! ERROR Country.parse_heading - unknown code >#{code}< in line: #{line}"
84
- pp line
85
- exit 1
86
- end
87
- if candidates[1].nil?
88
- puts "** !!! ERROR Country.parse_heading - unknown name >#{code}< in line: #{line}"
89
- pp line
90
- exit 1
91
- end
92
- if candidates[0] != candidates[1]
93
- puts "** !!! ERROR Country.parse_heading - name and code do NOT match the same country:"
94
- pp line
95
- pp candidates
96
- exit 1
97
- end
98
- if country && country != candidates[0]
99
- puts "** !!! ERROR Country.parse_heading - names do NOT match the same country:"
100
- pp line
101
- pp country
102
- pp candidates
103
- exit 1
104
- end
105
- country = candidates[0]
106
- else
107
- ## just assume value is name or code
108
- candidate = find( value )
109
- if candidate.nil?
110
- puts "** !!! ERROR Country.parse_heading - unknown name or code >#{value}< in line: #{line}"
111
- pp line
112
- exit 1
113
- end
114
- if country && country != candidate
115
- puts "** !!! ERROR Country.parse_heading - names do NOT match the same country:"
116
- pp line
117
- pp country
118
- pp candidate
119
- exit 1
120
- end
121
- country = candidate
122
- end
123
- end
124
- country
125
- end # method parse
126
- end # class CountrySearch
127
-
128
-
129
- def initialize( countries:, cities: )
130
- ## change service to country_service or such - why? why not?
131
- ## add city_service and such later
132
- @countries = CountrySearch.new( countries )
133
- @cities = CitySearch.new( cities )
134
- end
135
-
136
- ####
137
- # note: for now setup only for countries
138
- def countries() @countries; end
139
- def cities() @cities; end
140
- end # class WorldSearch
141
-
142
-
143
-
144
-
145
-
146
- class DummyCountrySearch
147
- def find_by_code( code )
148
- puts "[WARN] no world search configured; cannot find country by code"
149
- nil
150
- end
151
- def find_by_name( name )
152
- puts "[WARN] no world search configured; cannot find country by name"
153
- nil
154
- end
155
- end # class DummyCountrySearch
156
-
157
-