sportdb-readers 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f26c8211ce5ab383f35775134f230cbc22d71112
4
+ data.tar.gz: 7bfb83d1e338e101578fdd4487e3fa35c7f13580
5
+ SHA512:
6
+ metadata.gz: cee60d57c7f687397f0daa0333cdd6eaeee924141215b57ecc89691d3ae6daf5b40bf6f4aca4d65cf713613732e2ccafd7c9cd0256564b58e3d516241b495a14
7
+ data.tar.gz: fc4dcbc250a5d56b31bdbe6f82b78073e45ec1df499554861cc623695deb752ce94fe1934fe4b69b47b2245e44a6baeafb07b2eb9de0f2134317cac1eccb15d6
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ### 0.0.1 / 2019-10-29
2
+
3
+ * Everything is new. First release.
data/Manifest.txt ADDED
@@ -0,0 +1,14 @@
1
+ CHANGELOG.md
2
+ Manifest.txt
3
+ README.md
4
+ Rakefile
5
+ lib/sportdb/readers.rb
6
+ lib/sportdb/readers/event_reader.rb
7
+ lib/sportdb/readers/match_parser.rb
8
+ lib/sportdb/readers/match_reader.rb
9
+ lib/sportdb/readers/outline_reader.rb
10
+ lib/sportdb/readers/sync.rb
11
+ lib/sportdb/readers/version.rb
12
+ test/helper.rb
13
+ test/test_match_parser.rb
14
+ test/test_reader.rb
data/README.md ADDED
@@ -0,0 +1,26 @@
1
+ # sportdb-readers - sport.db readers
2
+
3
+
4
+ * home :: [github.com/sportdb/sport.db](https://github.com/sportdb/sport.db)
5
+ * bugs :: [github.com/sportdb/sport.db/issues](https://github.com/sportdb/sport.db/issues)
6
+ * gem :: [rubygems.org/gems/sportdb-readers](https://rubygems.org/gems/sportdb-readers)
7
+ * rdoc :: [rubydoc.info/gems/sportdb-readers](http://rubydoc.info/gems/sportdb-readers)
8
+ * forum :: [opensport](http://groups.google.com/group/opensport)
9
+
10
+
11
+
12
+ ## Usage
13
+
14
+ To be done
15
+
16
+ ## License
17
+
18
+ The `sportdb-readers` scripts are dedicated to the public domain.
19
+ Use it as you please with no restrictions whatsoever.
20
+
21
+
22
+ ## Questions? Comments?
23
+
24
+ Send them along to the
25
+ [Open Sports & Friends Forum/Mailing List](http://groups.google.com/group/opensport).
26
+ Thanks!
data/Rakefile ADDED
@@ -0,0 +1,31 @@
1
+ require 'hoe'
2
+ require './lib/sportdb/readers/version.rb'
3
+
4
+ Hoe.spec 'sportdb-readers' do
5
+
6
+ self.version = SportDb::Readers::VERSION
7
+
8
+ self.summary = "sportdb-readers - sport.db readers"
9
+ self.description = summary
10
+
11
+ self.urls = ['https://github.com/sportdb/sport.db']
12
+
13
+ self.author = 'Gerald Bauer'
14
+ self.email = 'opensport@googlegroups.com'
15
+
16
+ # switch extension to .markdown for gihub formatting
17
+ self.readme_file = 'README.md'
18
+ self.history_file = 'CHANGELOG.md'
19
+
20
+ self.licenses = ['Public Domain']
21
+
22
+ self.extra_deps = [
23
+ ['sportdb-config', '>= 0.8.1'],
24
+ ['sportdb-models', '>= 1.18.0'],
25
+ ]
26
+
27
+ self.spec_extras = {
28
+ required_ruby_version: '>= 2.2.2'
29
+ }
30
+
31
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: UTF-8
2
+
3
+
4
+ require 'sportdb/config'
5
+ require 'sportdb/models' ## add sql database support
6
+
7
+
8
+
9
+ ###
10
+ # our own code
11
+ require 'sportdb/readers/version' # let version always go first
12
+ require 'sportdb/readers/sync'
13
+ require 'sportdb/readers/outline_reader'
14
+ require 'sportdb/readers/event_reader'
15
+ require 'sportdb/readers/match_parser'
16
+ require 'sportdb/readers/match_reader'
17
+
18
+
19
+
20
+
21
+
22
+ puts SportDb::Readers.banner # say hello
@@ -0,0 +1,104 @@
1
+ # encoding: utf-8
2
+
3
+ module SportDb
4
+
5
+
6
+ class EventReaderV2 ## todo/check: rename to EventsReaderV2 (use plural?) why? why not?
7
+
8
+ def self.read( path ) ## use - rename to read_file or from_file etc. - why? why not?
9
+ txt = File.open( path, 'r:utf-8' ).read
10
+ parse( txt )
11
+ end
12
+
13
+ def self.parse( txt )
14
+ recs = LeagueOutlineReader.parse( txt )
15
+ pp recs
16
+
17
+ ## pass 2 - check & map; replace inline (string with record)
18
+ recs.each do |rec|
19
+ league = rec[:league]
20
+ clubs = [] ## convert lines to clubs
21
+ rec[:lines].each do |line|
22
+
23
+ next if line =~ /^[ -]+$/ ## skip decorative lines with dash only (e.g. ---- or - - - -) etc.
24
+
25
+ scan = StringScanner.new( line )
26
+
27
+ if scan.check( /\d{1,2}[ ]+/ ) ## entry with standaning starts with ranking e.g. 1,2,3, etc.
28
+ puts " table entry >#{line}<"
29
+ rank = scan.scan( /\d{1,2}[ ]+/ ).strip # note: strip trailing spaces
30
+
31
+ ## note: uses look ahead scan until we hit at least two spaces
32
+ ## or the end of string (standing records for now optional)
33
+ name = scan.scan_until( /(?=\s{2})|$/ )
34
+ if scan.eos?
35
+ standing = nil
36
+ else
37
+ standing = scan.rest.strip # note: strip leading and trailing spaces
38
+ end
39
+ puts " rank: >#{rank}<, name: >#{name}<, standing: >#{standing}<"
40
+
41
+ ## note: rank and standing gets ignored (not used) for now
42
+ else
43
+ ## assume club is full line
44
+ name = line
45
+ end
46
+
47
+ clubs << find_club( name, league.country )
48
+ end
49
+
50
+ rec[:clubs] = clubs
51
+ rec.delete( :lines ) ## remove lines entry
52
+ end
53
+
54
+ ## pass 3 - import (insert/update) into db
55
+ recs.each do |rec|
56
+ league = Sync::League.find_or_create( rec[:league] )
57
+ season = Sync::Season.find_or_create( rec[:season] )
58
+
59
+ event = Sync::Event.find_or_create( league: league, season: season )
60
+
61
+ rec[:clubs].each do |club_rec|
62
+ club = Sync::Club.find_or_create( club_rec )
63
+ ## add teams to event
64
+ ## todo/fix: check if team is alreay included?
65
+ ## or clear/destroy_all first!!!
66
+ event.teams << club
67
+ end
68
+ end
69
+
70
+ recs
71
+ end # method read
72
+
73
+
74
+
75
+ def self.find_club( name, country ) ## todo/fix: add international or league flag?
76
+ club = nil
77
+ m = CLUBS.match_by( name: name, country: country )
78
+
79
+ if m.nil?
80
+ ## (re)try with second country - quick hacks for known leagues
81
+ ## todo/fix: add league flag to activate!!!
82
+ m = CLUBS.match_by( name: name, country: COUNTRIES['wal']) if country.key == 'eng'
83
+ m = CLUBS.match_by( name: name, country: COUNTRIES['nir']) if country.key == 'ie'
84
+ m = CLUBS.match_by( name: name, country: COUNTRIES['mc']) if country.key == 'fr'
85
+ m = CLUBS.match_by( name: name, country: COUNTRIES['li']) if country.key == 'ch'
86
+ m = CLUBS.match_by( name: name, country: COUNTRIES['ca']) if country.key == 'us'
87
+ end
88
+
89
+ if m.nil?
90
+ puts "** !!! ERROR !!! no match for club >#{name}<"
91
+ exit 1
92
+ elsif m.size > 1
93
+ puts "** !!! ERROR !!! too many matches (#{m.size}) for club >#{name}<:"
94
+ pp m
95
+ exit 1
96
+ else # bingo; match - assume size == 1
97
+ club = m[0]
98
+ end
99
+
100
+ club
101
+ end
102
+
103
+ end # class EventReaderV2
104
+ end # module SportDb
@@ -0,0 +1,466 @@
1
+ # encoding: utf-8
2
+
3
+ module SportDb
4
+
5
+ class MatchParserSimpleV2 ## simple match parser for club match schedules
6
+ include LogUtils::Logging
7
+
8
+ def initialize( lines, teams, start_at )
9
+ @lines = lines ## todo/check: change to text instead of array of lines - why? why not?
10
+ @mapper_teams = TeamMapper.new( teams )
11
+ @start_at = start_at
12
+
13
+ ## build lookup hash by (team) key
14
+ @teams = teams.reduce({}) { |h,team| h[team.key]=team; h }
15
+
16
+ ## debug_dump_teams( teams )
17
+ ## exit 1
18
+ end
19
+
20
+ def debug_dump_teams( teams )
21
+ puts "== #{teams.size} teams"
22
+ teams.each do |team|
23
+ print "#{team.key}, "
24
+ print "#{team.title}, "
25
+ print "#{team.synonyms.split('|').join(', ')}"
26
+ puts
27
+ end
28
+ end
29
+
30
+
31
+
32
+ Round = Struct.new( :pos, :title )
33
+ ##
34
+ ## todo: change db schema
35
+ ## make start and end date optional
36
+ ## change pos to num - why? why not?
37
+ ## make pos/num optional too
38
+ ##
39
+ ## sort round by scheduled/planed start date
40
+ Match = Struct.new( :date,
41
+ :team1, :team2, ## todo/fix: use team1_name, team2_name or similar - for compat with db activerecord version? why? why not?
42
+ :score1i, :score2i, ## half time (first (i) part)
43
+ :score1, :score2, ## full time
44
+ :round )
45
+
46
+ def parse
47
+ @last_date = nil
48
+ @last_round = nil
49
+ @rounds = {}
50
+ @matches = []
51
+
52
+
53
+ @lines.each do |line|
54
+ if is_round?( line )
55
+ parse_round_header( line )
56
+ elsif try_parse_game( line )
57
+ # do nothing here
58
+ elsif try_parse_date_header( line )
59
+ # do nothing here
60
+ else
61
+ logger.info "skipping line (no match found): >#{line}<"
62
+ end
63
+ end # lines.each
64
+
65
+ [@rounds.values, @matches]
66
+ end # method parse
67
+
68
+
69
+ def is_round?( line )
70
+ ## note: =~ return nil if not match found, and 0,1, etc for match
71
+ (line =~ SportDb.lang.regex_round) != nil
72
+ end
73
+
74
+
75
+ def find_round_pos!( line )
76
+ # pass #1) extract optional round pos from line
77
+ # e.g. (1) - must start line
78
+ regex_pos = /^[ \t]*\((\d{1,3})\)[ \t]+/
79
+
80
+ # pass #2) find free standing number e.g. Matchday 3 or Round 5 or 3. Spieltag etc.
81
+ # note: /\b(\d{1,3})\b/
82
+ # will match -12
83
+ # thus, use space required - will NOT match -2 e.g. Group-2 Play-off
84
+ # note: allow 1. Runde n
85
+ # 1^ Giornata
86
+ regex_num = /(?:^|\s)(\d{1,3})(?:[.\^\s]|$)/
87
+
88
+ if line =~ regex_pos
89
+ logger.debug " pos: >#{$1}<"
90
+
91
+ line.sub!( regex_pos, '[ROUND.POS] ' ) ## NB: add back trailing space that got swallowed w/ regex -> [ \t]+
92
+ return $1.to_i
93
+ elsif line =~ regex_num
94
+ ## assume number in title is pos (e.g. Jornada 3, 3 Runde etc.)
95
+ ## NB: do NOT remove pos from string (will get removed by round title)
96
+
97
+ num = $1.to_i # note: clone capture; keep a copy (another regex follows; will redefine $1)
98
+
99
+ #### fix:
100
+ # use/make keywords required
101
+ # e.g. Round of 16 -> should NOT match 16!
102
+ # Spiel um Platz 3 (or 5) etc -> should NOT match 3!
103
+ # Round 16 - ok
104
+ # thus, check for required keywords
105
+
106
+ ## quick hack for round of 16
107
+ # todo: mask match e.g. Round of xxx ... and try again - might include something
108
+ # reuse pattern for Group XX Replays for example
109
+ if line =~ /^\s*Round of \d{1,3}\b/
110
+ return nil
111
+ end
112
+
113
+ logger.debug " pos: >#{num}<"
114
+ return num
115
+ else
116
+ ## fix: add logger.warn no round pos found in line
117
+ return nil
118
+ end
119
+ end # method find_round_pos!
120
+
121
+ def find_round_header_title!( line )
122
+ # assume everything left is the round title
123
+ # extract all other items first (round title2, round pos, group title n pos, etc.)
124
+
125
+ ## todo/fix:
126
+ ## cleanup method
127
+ ## use buf.index( '//' ) to split string (see found_round_def)
128
+ ## why? simpler why not?
129
+ ## - do we currently allow groups if title2 present? add example if it works?
130
+
131
+ buf = line.dup
132
+ logger.debug " find_round_header_title! line-before: >>#{buf}<<"
133
+
134
+ buf.gsub!( /\[[^\]]+\]/, '' ) # e.g. remove [ROUND.POS], [ROUND.TITLE2], [GROUP.TITLE+POS] etc.
135
+ buf.strip! # remove leading and trailing whitespace
136
+
137
+ logger.debug " find_round_title! line-after: >>#{buf}<<"
138
+
139
+ ### bingo - assume what's left is the round title
140
+
141
+ logger.debug " title: >>#{buf}<<"
142
+ line.sub!( buf, '[ROUND.TITLE]' )
143
+
144
+ buf
145
+ end
146
+
147
+ def parse_round_header( line )
148
+ logger.debug "parsing round header line: >#{line}<"
149
+
150
+ ## todo/check/fix:
151
+ # make sure Round of 16 will not return pos 16 -- how? possible?
152
+ # add unit test too to verify
153
+ pos = find_round_pos!( line )
154
+
155
+ title = find_round_header_title!( line )
156
+
157
+ logger.debug " line: >#{line}<"
158
+
159
+
160
+ round = @rounds[ title ]
161
+ if round.nil?
162
+ round = Round.new( pos, title )
163
+ @rounds[ title ] = round
164
+ end
165
+ ## todo/check: if pos match (MUST always match for now)
166
+ @last_round = round
167
+
168
+
169
+ ## NB: dummy/placeholder start_at, end_at date
170
+ ## replace/patch after adding all games for round
171
+
172
+ =begin
173
+ round_attribs = {
174
+ title: title,
175
+ title2: title2,
176
+ knockout: knockout_flag
177
+ }
178
+
179
+ if pos > 999000
180
+ # no pos (e.g. will get autonumbered later) - try match by title for now
181
+ # e.g. lets us use title 'Group Replays', for example, multiple times
182
+ @round = Round.find_by_event_id_and_title( @event.id, title )
183
+ else
184
+ @round = Round.find_by_event_id_and_pos( @event.id, pos )
185
+ end
186
+
187
+ if @round.present?
188
+ logger.debug "update round #{@round.id}:"
189
+ else
190
+ logger.debug "create round:"
191
+ @round = Round.new
192
+
193
+ round_attribs = round_attribs.merge( {
194
+ event_id: @event.id,
195
+ pos: pos,
196
+ start_at: Date.parse('1911-11-11'),
197
+ end_at: Date.parse('1911-11-11')
198
+ })
199
+ end
200
+
201
+ logger.debug round_attribs.to_json
202
+
203
+ @round.update_attributes!( round_attribs )
204
+
205
+ @patch_round_ids_pos << @round.id if pos > 999000
206
+ ### store list of round ids for patching start_at/end_at at the end
207
+ @patch_round_ids_dates << @round.id # todo/fix/check: check if round has definition (do NOT patch if definition (not auto-added) present)
208
+ =end
209
+ end
210
+
211
+
212
+ def find_scores!( line, opts={} )
213
+ # note: always call after find_dates !!!
214
+ # scores match date-like patterns!! e.g. 10-11 or 10:00 etc.
215
+ # -- note: score might have two digits too
216
+
217
+ finder = ScoresFinder.new
218
+ finder.find!( line, opts )
219
+ end
220
+
221
+ def try_parse_game( line )
222
+ # note: clone line; for possible test do NOT modify in place for now
223
+ # note: returns true if parsed, false if no match
224
+ parse_game( line.dup )
225
+ end
226
+
227
+
228
+ def parse_game( line )
229
+ logger.debug "parsing game (fixture) line: >#{line}<"
230
+
231
+ @mapper_teams.map_teams!( line ) ### todo/fix: limit mapping to two(2) teams - why? why not? might avoid matching @ Barcelona ??
232
+ team_keys = @mapper_teams.find_teams!( line )
233
+ team1_key = team_keys[0]
234
+ team2_key = team_keys[1]
235
+
236
+ ## note: if we do NOT find two teams; return false - no match found
237
+ if team1_key.nil? || team2_key.nil?
238
+ logger.debug " no game match (two teams required) found for line: >#{line}<"
239
+ return false
240
+ end
241
+
242
+ ## pos = find_game_pos!( line )
243
+
244
+ date = find_date!( line, start_at: @start_at )
245
+
246
+ ###
247
+ # check if date found?
248
+ # NB: ruby falsey is nil & false only (not 0 or empty array etc.)
249
+ if date
250
+ ### check: use date_v2 if present? why? why not?
251
+ @last_date = date # keep a reference for later use
252
+ else
253
+ date = @last_date # no date found; (re)use last seen date
254
+ end
255
+
256
+
257
+ scores = find_scores!( line )
258
+
259
+ logger.debug " line: >#{line}<"
260
+
261
+
262
+ ## todo/check: scores are integers or strings?
263
+ @matches << Match.new( date,
264
+ @teams[ team1_key ],
265
+ @teams[ team2_key ],
266
+ scores[0], ## score1i - half time (first (i) part)
267
+ scores[1], ## score2i
268
+ scores[2], ## score1 - full time
269
+ scores[3], ## score2
270
+ @last_round )
271
+
272
+ ### todo: cache team lookups in hash?
273
+
274
+ =begin
275
+ team1 = Team.find_by_key!( team1_key )
276
+ team2 = Team.find_by_key!( team2_key )
277
+
278
+ @last_team1 = team1 # store for later use for goals etc.
279
+ @last_team2 = team2
280
+
281
+
282
+ if @round.nil?
283
+ ## no round header found; calculate round from date
284
+
285
+ ###
286
+ ## todo/fix: add some unit tests for round look up
287
+ # fix: use date_v2 if present!! (old/original date; otherwise use date)
288
+
289
+ #
290
+ # fix: check - what to do with hours e.g. start_at use 00:00 and for end_at use 23.59 ??
291
+ # -- for now - remove hours (e.g. use end_of_day and beginnig_of_day)
292
+
293
+ ##
294
+ # note: start_at and end_at are dates ONLY (note datetime)
295
+ # - do NOT pass in hours etc. in query
296
+ # again use --> date.end_of_day, date.beginning_of_day
297
+ # new: not working: date.to_date, date.to_date
298
+ # will not find round if start_at same as date !! (in theory hours do not matter)
299
+
300
+ ###
301
+ # hack:
302
+ # special case for sqlite3 (date compare not working reliable; use casts)
303
+ # fix: move to adapter_name to activerecord_utils as sqlite? or similar?
304
+
305
+ if ActiveRecord::Base.connection.adapter_name.downcase.starts_with?( 'sqlite' )
306
+ logger.debug( " [sqlite] using sqlite-specific query for date compare for rounds finder" )
307
+ round = Round.where( 'event_id = ? AND ( julianday(start_at) <= julianday(?)'+
308
+ 'AND julianday(end_at) >= julianday(?))',
309
+ @event.id, date.to_date, date.to_date).first
310
+ else # all other dbs (postgresql, mysql, etc.)
311
+ round = Round.where( 'event_id = ? AND (start_at <= ? AND end_at >= ?)',
312
+ @event.id, date.to_date, date.to_date).first
313
+ end
314
+
315
+ pp round
316
+ if round.nil?
317
+ logger.warn( " !!!! no round match found for date #{date}" )
318
+ pp Round.all
319
+
320
+ ###################################
321
+ # -- try auto-adding matchday
322
+ round = Round.new
323
+
324
+ round_attribs = {
325
+ event_id: @event.id,
326
+ title: "Matchday #{date.to_date}",
327
+ pos: 999001+@patch_round_ids_pos.length, # e.g. 999<count> - 999001,999002,etc.
328
+ start_at: date.to_date,
329
+ end_at: date.to_date
330
+ }
331
+
332
+ logger.info( " auto-add round >Matchday #{date.to_date}<" )
333
+ logger.debug round_attribs.to_json
334
+
335
+ round.update_attributes!( round_attribs )
336
+
337
+ @patch_round_ids_pos << round.id # todo/check - add just id or "full" record as now - why? why not?
338
+ end
339
+
340
+ # store pos for auto-number next round if missing
341
+ # - note: only if greater/bigger than last; use max
342
+ # - note: last_round_pos might be nil - thus set to 0
343
+ if round.pos > 999000
344
+ # note: do NOT update last_round_pos for to-be-patched rounds
345
+ else
346
+ @last_round_pos = [round.pos,@last_round_pos||0].max
347
+ end
348
+
349
+ ## note: will crash (round.pos) if round is nil
350
+ logger.debug( " using round #{round.pos} >#{round.title}< start_at: #{round.start_at}, end_at: #{round.end_at}" )
351
+ else
352
+ ## use round from last round header
353
+ round = @round
354
+ end
355
+
356
+
357
+ ### check if games exists
358
+ ## with this teams in this round if yes only update
359
+ game = Game.find_by_round_id_and_team1_id_and_team2_id(
360
+ round.id, team1.id, team2.id
361
+ )
362
+
363
+ game_attribs = {
364
+ score1i: scores[0],
365
+ score2i: scores[1],
366
+ score1: scores[2],
367
+ score2: scores[3],
368
+ score1et: scores[4],
369
+ score2et: scores[5],
370
+ score1p: scores[6],
371
+ score2p: scores[7],
372
+ play_at: date,
373
+ play_at_v2: date_v2,
374
+ postponed: postponed,
375
+ knockout: round.knockout, ## note: for now always use knockout flag from round - why? why not??
376
+ ground_id: ground.present? ? ground.id : nil,
377
+ group_id: @group.present? ? @group.id : nil
378
+ }
379
+
380
+ game_attribs[ :pos ] = pos if pos.present?
381
+
382
+ ####
383
+ # note: only update if any changes (or create if new record)
384
+ if game.present? &&
385
+ game.check_for_changes( game_attribs ) == false
386
+ logger.debug " skip update game #{game.id}; no changes found"
387
+ else
388
+ if game.present?
389
+ logger.debug "update game #{game.id}:"
390
+ else
391
+ logger.debug "create game:"
392
+ game = Game.new
393
+
394
+ more_game_attribs = {
395
+ round_id: round.id,
396
+ team1_id: team1.id,
397
+ team2_id: team2.id
398
+ }
399
+
400
+ ## NB: use round.games.count for pos
401
+ ## lets us add games out of order if later needed
402
+ more_game_attribs[ :pos ] = round.games.count+1 if pos.nil?
403
+
404
+ game_attribs = game_attribs.merge( more_game_attribs )
405
+ end
406
+
407
+ logger.debug game_attribs.to_json
408
+ game.update_attributes!( game_attribs )
409
+ end
410
+
411
+ @last_game = game # store for later reference (e.g. used for goals etc.)
412
+ =end
413
+
414
+ return true # game match found
415
+ end # method parse_game
416
+
417
+
418
+
419
+ def try_parse_date_header( line )
420
+ # note: clone line; for possible test do NOT modify in place for now
421
+ # note: returns true if parsed, false if no match
422
+ parse_date_header( line.dup )
423
+ end
424
+
425
+ def find_date!( line, opts={} )
426
+ ## NB: lets us pass in start_at/end_at date (for event)
427
+ # for auto-complete year
428
+
429
+ # extract date from line
430
+ # and return it
431
+ # NB: side effect - removes date from line string
432
+
433
+ finder = DateFinder.new
434
+ finder.find!( line, opts )
435
+ end
436
+
437
+ def parse_date_header( line )
438
+ # note: returns true if parsed, false if no match
439
+
440
+ # line with NO teams plus include date e.g.
441
+ # [Fri Jun/17] or
442
+ # Jun/17 or
443
+ # Jun/17: etc.
444
+
445
+ @mapper_teams.map_teams!( line )
446
+ team_keys = @mapper_teams.find_teams!( line )
447
+ team1_key = team_keys[0]
448
+ team2_key = team_keys[1]
449
+
450
+ date = find_date!( line, start_at: @start_at )
451
+
452
+ if date && team1_key.nil? && team2_key.nil?
453
+ logger.debug( "date header line found: >#{line}<")
454
+ logger.debug( " date: #{date}")
455
+
456
+ @last_date = date # keep a reference for later use
457
+ return true
458
+ else
459
+ return false
460
+ end
461
+ end
462
+
463
+
464
+
465
+ end # class MatchParserSimpleV2
466
+ end # module SportDb