sportdb-models 1.18.0 → 1.18.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,241 +0,0 @@
1
- # encoding: UTF-8
2
-
3
-
4
- module SportDb
5
-
6
-
7
- class CsvGameReader
8
-
9
- include LogUtils::Logging
10
-
11
- ## make models available by default with namespace
12
- # e.g. lets you use Usage instead of Model::Usage
13
- include Models
14
-
15
- ##
16
- ## todo: add from_file and from_zip too
17
-
18
- def self.from_string( event_key, text )
19
- ### fix - fix -fix:
20
- ## change event to event_or_event_key !!!!! - allow event_key as string passed in
21
- self.new( event_key, text )
22
- end
23
-
24
- def initialize( event_key, text )
25
- ### fix - fix -fix:
26
- ## change event to event_or_event_key !!!!! - allow event_key as string passed in
27
-
28
- ## todo/fix: how to add opts={} ???
29
- @event_key = event_key
30
- @text = text
31
- end
32
-
33
-
34
- def read
35
- ## note: assume active activerecord connection
36
- @event = Event.find_by!( key: @event_key )
37
-
38
- logger.debug "Event #{@event.key} >#{@event.title}<"
39
-
40
- @team_mapper = TextUtils::TitleMapper.new( @event.teams, 'team' )
41
-
42
- ## reset cached values
43
- @patch_round_ids = []
44
-
45
- @last_round = nil ## remove last round ?? - always required - why? why not?
46
- @last_date = nil ## remove last date ?? - always required - why? why not?
47
-
48
- parse_fixtures
49
- end # method load_fixtures
50
-
51
-
52
- def handle_round( round_pos_str )
53
-
54
- round_pos = round_pos_str.to_i
55
-
56
- round_attribs = { }
57
-
58
- round = Round.find_by( event_id: @event.id,
59
- pos: round_pos )
60
-
61
- if round.present?
62
- logger.debug "update round #{round.id}:"
63
- else
64
- logger.debug "create round:"
65
- round = Round.new
66
-
67
- round_attribs = round_attribs.merge( {
68
- event_id: @event.id,
69
- pos: round_pos,
70
- title: "Round #{round_pos}",
71
- title2: nil,
72
- knockout: false,
73
- start_at: Date.parse('1911-11-11'),
74
- end_at: Date.parse('1911-11-11')
75
- })
76
- end
77
-
78
- logger.debug round_attribs.to_json
79
-
80
- round.update_attributes!( round_attribs )
81
-
82
- ### store list of round ids for patching start_at/end_at at the end
83
- @patch_round_ids << round.id
84
- @last_round = round ## keep track of last seen round for matches that follow etc.
85
- end
86
-
87
- def handle_game( date_str, team1_str, team2_str, ft_str, ht_str )
88
-
89
- ## todo/fix: make more "efficient"
90
- ## - e.g. add new support method for mapping single team/reference - why? why not??
91
- line = "#{team1_str} - #{team2_str}"
92
- @team_mapper.map_titles!( line )
93
- team1_key = @team_mapper.find_key!( line )
94
- team2_key = @team_mapper.find_key!( line )
95
-
96
- ## note: if we do NOT find two teams; return false - no match found
97
- if team1_key.nil? || team2_key.nil?
98
- fail " no game match (two teams required) found for line: >#{line}<"
99
- end
100
-
101
- if date_str
102
- date = DateTime.strptime( date_str, '%Y-%m-%d' ) ## (always) use DateTime - why? why not??
103
- @last_date = date # keep a reference for later use
104
- else
105
- date = @last_date # no date found; (re)use last seen date
106
- end
107
-
108
- ##
109
- ## todo: support for awarded, abadoned, a.e.t, pen. etc. - why?? why not??
110
- ##
111
-
112
- if ht_str ## half time scores
113
- scoresi_str = ht_str.gsub(/ /, '').split('-') ## note: remove all (inline) spaces first
114
- score1i = scoresi_str[0].to_i
115
- score2i = scoresi_str[1].to_i
116
- else
117
- score1i = nil
118
- score2i = nil
119
- end
120
-
121
- if ft_str ## full time scores
122
- scores_str = ft_str.gsub(/ /, '').split('-') ## note: remove all (inline) spaces first
123
- score1 = scores_str[0].to_i
124
- score2 = scores_str[1].to_i
125
- else
126
- score1 = nil
127
- score2 = nil
128
- end
129
-
130
- ### todo: cache team lookups in hash? - why? why not??
131
- team1 = Team.find_by!( key: team1_key )
132
- team2 = Team.find_by!( key: team2_key )
133
-
134
- round = @last_round
135
-
136
- ### check if games exists
137
- ## with this teams in this round if yes only update
138
- game = Game.find_by( round_id: round.id,
139
- team1_id: team1.id,
140
- team2_id: team2.id )
141
-
142
- game_attribs = {
143
- score1: score1,
144
- score2: score2,
145
- score1i: score1i,
146
- score2i: score2i,
147
- play_at: date,
148
- play_at_v2: nil,
149
- postponed: false,
150
- knockout: false, ## round.knockout, ## note: for now always use knockout flag from round - why? why not??
151
- ground_id: nil,
152
- group_id: nil
153
- }
154
-
155
- if game.present?
156
- logger.debug "update game #{game.id}:"
157
- else
158
- logger.debug "create game:"
159
- game = Game.new
160
-
161
- ## Note: use round.games.count for pos
162
- ## lets us add games out of order if later needed
163
- more_game_attribs = {
164
- round_id: round.id,
165
- team1_id: team1.id,
166
- team2_id: team2.id,
167
- pos: round.games.count+1
168
- }
169
- game_attribs = game_attribs.merge( more_game_attribs )
170
- end
171
-
172
- logger.debug game_attribs.to_json
173
- game.update_attributes!( game_attribs )
174
-
175
- end # method handle_game
176
-
177
-
178
- def parse_fixtures
179
-
180
- CSV.parse( @text, headers: true ) do |row|
181
- puts row.inspect
182
-
183
- pp round = row['Round']
184
- pp date = row['Date']
185
- pp team1 = row['Team 1']
186
- pp team2 = row['Team 2']
187
- pp ft = row['FT']
188
- pp ht = row['HT']
189
-
190
- ## find round by pos
191
- if round
192
- handle_round( round )
193
- handle_game( date, team1, team2, ft, ht )
194
- else
195
- fail "round required for import; sorry"
196
- end
197
- end
198
-
199
- ###########################
200
- # backtrack and patch round dates (start_at/end_at)
201
-
202
- unless @patch_round_ids.empty?
203
- ###
204
- # note: use uniq - to allow multiple round headers (possible?)
205
-
206
- Round.find( @patch_round_ids.uniq ).each do |r|
207
- logger.debug "patch round start_at/end_at date for #{r.title}:"
208
-
209
- ## note:
210
- ## will add "scope" pos first e.g
211
- #
212
- ## SELECT "games".* FROM "games" WHERE "games"."round_id" = ?
213
- # ORDER BY pos, play_at asc [["round_id", 7]]
214
- # thus will NOT order by play_at but by pos first!!!
215
- # =>
216
- # need to unscope pos!!! or use unordered_games - games_by_play_at_date etc.??
217
- # thus use reorder()!!! - not just order('play_at asc')
218
-
219
- games = r.games.reorder( 'play_at asc' ).all
220
-
221
- ## skip rounds w/ no games
222
-
223
- ## todo/check/fix: what's the best way for checking assoc w/ 0 recs?
224
- next if games.size == 0
225
-
226
- # note: make sure start_at/end_at is date only (e.g. use play_at.to_date)
227
- # sqlite3 saves datetime in date field as datetime, for example (will break date compares later!)
228
-
229
- round_attribs = {
230
- start_at: games[0].play_at.to_date, # use games.first ?
231
- end_at: games[-1].play_at.to_date # use games.last ? why? why not?
232
- }
233
-
234
- logger.debug round_attribs.to_json
235
- r.update_attributes!( round_attribs )
236
- end
237
- end
238
- end # method parse_fixtures
239
-
240
- end # class CsvGameReader
241
- end # module SportDb
@@ -1,446 +0,0 @@
1
- # encoding: utf-8
2
-
3
- #### fix: move to textutils for reuse !!!!!!!!!! - why?? why not ??
4
-
5
-
6
- module SportDb
7
-
8
-
9
- class DateFinderBase
10
-
11
- MONTH_EN_TO_MM = {
12
- 'Jan' => '1', 'January' => '1',
13
- 'Feb' => '2', 'February' => '2',
14
- 'Mar' => '3', 'March' => '3',
15
- 'Apr' => '4', 'April' => '4',
16
- 'May' => '5',
17
- 'Jun' => '6', 'June' => '6',
18
- 'Jul' => '7', 'July' => '7',
19
- 'Aug' => '8', 'August' => '8',
20
- 'Sep' => '9', 'Sept' => '9', 'September' => '9',
21
- 'Oct' => '10', 'October' => '10',
22
- 'Nov' => '11', 'November' => '11',
23
- 'Dec' => '12', 'December' =>'12' }
24
-
25
- MONTH_FR_TO_MM = {
26
- 'Janvier' => '1', 'Janv' => '1', 'Jan' => '1', ## check janv in use??
27
- 'Février' => '2', 'Févr' => '2', 'Fév' => '2', ## check fevr in use???
28
- 'Mars' => '3', 'Mar' => '3',
29
- 'Avril' => '4', 'Avri' => '4', 'Avr' => '4', ## check avri in use??? if not remove
30
- 'Mai' => '5',
31
- 'Juin' => '6',
32
- 'Juillet' => '7', 'Juil' => '7',
33
- 'Août' => '8',
34
- 'Septembre' => '9', 'Sept' => '9',
35
- 'Octobre' => '10', 'Octo' => '10', 'Oct' => '10', ### check octo in use??
36
- 'Novembre' => '11', 'Nove' => '11', 'Nov' => '11', ## check nove in use??
37
- 'Décembre' => '12', 'Déce' => '12', 'Déc' => '12' } ## check dece in use??
38
-
39
- MONTH_ES_TO_MM = {
40
- 'Ene' => '1', 'Enero' => '1',
41
- 'Feb' => '2',
42
- 'Mar' => '3', 'Marzo' => '3',
43
- 'Abr' => '4', 'Abril' => '4',
44
- 'May' => '5', 'Mayo' => '5',
45
- 'Jun' => '6', 'Junio' => '6',
46
- 'Jul' => '7', 'Julio' => '7',
47
- 'Ago' => '8', 'Agosto' => '8',
48
- 'Sep' => '9', 'Set' => '9', 'Sept' => '9',
49
- 'Oct' => '10',
50
- 'Nov' => '11',
51
- 'Dic' => '12' }
52
-
53
- private
54
- def calc_year( month, day, opts )
55
- start_at = opts[:start_at]
56
-
57
- logger.debug " [calc_year] ????-#{month}-#{day} -- start_at: #{start_at}"
58
-
59
- if month >= start_at.month
60
- # assume same year as start_at event (e.g. 2013 for 2013/14 season)
61
- start_at.year
62
- else
63
- # assume year+1 as start_at event (e.g. 2014 for 2013/14 season)
64
- start_at.year+1
65
- end
66
- end
67
-
68
- def parse_date_time( match_data, opts={} )
69
-
70
- # convert regex match_data captures to hash
71
- # - note: cannont use match_data like a hash (e.g. raises exception if key/name not present/found)
72
- h = {}
73
- # - note: do NOT forget to turn name into symbol for lookup in new hash (name.to_sym)
74
- match_data.names.each { |name| h[name.to_sym] = match_data[name] } # or use match_data.names.zip( match_data.captures ) - more cryptic but "elegant"??
75
-
76
- ## puts "[parse_date_time] match_data:"
77
- ## pp h
78
- logger.debug " [parse_date_time] hash: >#{h.inspect}<"
79
-
80
- h[ :month ] = MONTH_EN_TO_MM[ h[:month_en] ] if h[:month_en]
81
- h[ :month ] = MONTH_ES_TO_MM[ h[:month_es] ] if h[:month_es]
82
- h[ :month ] = MONTH_FR_TO_MM[ h[:month_fr] ] if h[:month_fr]
83
-
84
- month = h[:month]
85
- day = h[:day]
86
- year = h[:year] || calc_year( month.to_i, day.to_i, opts ).to_s
87
-
88
- hours = h[:hours] || '12' # default to 12:00 for HH:MM (hours:minutes)
89
- minutes = h[:minutes] || '00'
90
-
91
- value = '%d-%02d-%02d %02d:%02d' % [year.to_i, month.to_i, day.to_i, hours.to_i, minutes.to_i]
92
- logger.debug " date: >#{value}<"
93
-
94
- DateTime.strptime( value, '%Y-%m-%d %H:%M' )
95
- end
96
-
97
- end # class DateFinderBase
98
-
99
-
100
- class DateFinder < DateFinderBase
101
-
102
- include LogUtils::Logging
103
-
104
- # todo: make more generic for reuse
105
- ### fix:
106
- ### move to textutils
107
- ## date/fr.yml en.yml etc. ???
108
- ## why? why not?
109
-
110
- MONTH_FR = 'Janvier|Janv|Jan|' +
111
- 'Février|Févr|Fév|' +
112
- 'Mars|Mar|' +
113
- 'Avril|Avri|Avr|' +
114
- 'Mai|' +
115
- 'Juin|' +
116
- 'Juillet|Juil|' +
117
- 'Août|' +
118
- 'Septembre|Sept|' +
119
- 'Octobre|Octo|Oct|' +
120
- 'Novembre|Nove|Nov|' +
121
- 'Décembre|Déce|Déc'
122
-
123
- WEEKDAY_FR = 'Lundi|Lun|L|' +
124
- 'Mardi|Mar|Ma|' +
125
- 'Mercredi|Mer|Me|' +
126
- 'Jeudi|Jeu|J|' +
127
- 'Vendredi|Ven|V|' +
128
- 'Samedi|Sam|S|' +
129
- 'Dimanche|Dim|D|'
130
-
131
-
132
- MONTH_EN = 'January|Jan|'+
133
- 'February|Feb|'+
134
- 'March|Mar|'+
135
- 'April|Apr|'+
136
- 'May|'+
137
- 'June|Jun|'+
138
- 'July|Jul|'+
139
- 'August|Aug|'+
140
- 'September|Sept|Sep|'+
141
- 'October|Oct|'+
142
- 'November|Nov|'+
143
- 'December|Dec'
144
-
145
- ###
146
- ## todo: add days
147
- ## 1. Sunday - Sun. 2. Monday - Mon.
148
- ## 3. Tuesday - Tu., Tue., or Tues. 4. Wednesday - Wed.
149
- ## 5. Thursday - Th., Thu., Thur., or Thurs. 6. Friday - Fri.
150
- ## 7. Saturday - Sat.
151
-
152
-
153
- MONTH_ES = 'Enero|Ene|'+
154
- 'Feb|'+
155
- 'Marzo|Mar|'+
156
- 'Abril|Abr|'+
157
- 'Mayo|May|'+
158
- 'Junio|Jun|'+
159
- 'Julio|Jul|'+
160
- 'Agosto|Ago|'+
161
- 'Sept|Set|Sep|'+
162
- 'Oct|'+
163
- 'Nov|'+
164
- 'Dic'
165
-
166
- # todo/fix - add de and es too!!
167
- # note: in Austria - Jänner - in Deutschland Januar allow both ??
168
- # MONTH_DE = 'J[aä]n|Feb|Mär|Apr|Mai|Jun|Jul|Aug|Sep|Okt|Nov|Dez'
169
-
170
-
171
- # e.g. 2012-09-14 20:30 => YYYY-MM-DD HH:MM
172
- # nb: allow 2012-9-3 7:30 e.g. no leading zero required
173
- # regex_db
174
- DB__DATE_TIME_REGEX = /\b
175
- (?<year>\d{4})
176
- -
177
- (?<month>\d{1,2})
178
- -
179
- (?<day>\d{1,2})
180
- \s+
181
- (?<hours>\d{1,2})
182
- :
183
- (?<minutes>\d{2})
184
- \b/x
185
-
186
- # e.g. 2012-09-14 w/ implied hours (set to 12:00)
187
- # nb: allow 2012-9-3 e.g. no leading zero required
188
- # regex_db2
189
- DB__DATE_REGEX = /\b
190
- (?<year>\d{4})
191
- -
192
- (?<month>\d{1,2})
193
- -
194
- (?<day>\d{1,2})
195
- \b/x
196
-
197
- # e.g. 14.09.2012 20:30 => DD.MM.YYYY HH:MM
198
- # nb: allow 2.3.2012 e.g. no leading zero required
199
- # nb: allow hour as 20.30
200
- # regex_de
201
- DD_MM_YYYY__DATE_TIME_REGEX = /\b
202
- (?<day>\d{1,2})
203
- \.
204
- (?<month>\d{1,2})
205
- \.
206
- (?<year>\d{4})
207
- \s+
208
- (?<hours>\d{1,2})
209
- [:.]
210
- (?<minutes>\d{2})
211
- \b/x
212
-
213
- # e.g. 14.09. 20:30 => DD.MM. HH:MM
214
- # nb: allow 2.3.2012 e.g. no leading zero required
215
- # nb: allow hour as 20.30 or 3.30 instead of 03.30
216
- # regex_de2
217
- DD_MM__DATE_TIME_REGEX = /\b
218
- (?<day>\d{1,2})
219
- \.
220
- (?<month>\d{1,2})
221
- \.
222
- \s+
223
- (?<hours>\d{1,2})
224
- [:.]
225
- (?<minutes>\d{2})
226
- \b/x
227
-
228
- # e.g. 14.09.2012 => DD.MM.YYYY w/ implied hours (set to 12:00)
229
- # regex_de3
230
- DD_MM_YYYY__DATE_REGEX = /\b
231
- (?<day>\d{1,2})
232
- \.
233
- (?<month>\d{1,2})
234
- \.
235
- (?<year>\d{4})
236
- \b/x
237
-
238
- # e.g. 14.09. => DD.MM. w/ implied year and implied hours (set to 12:00)
239
- # note: allow end delimiter ] e.g. [Sa 12.01.] or end-of-string ($) too
240
- # note: we use a lookahead for last part e.g. (?:\s+|$|[\]]) - do NOT cosume
241
- # regex_de4 (use lookahead assert)
242
- DD_MM__DATE_REGEX = /\b
243
- (?<day>\d{1,2})
244
- \.
245
- (?<month>\d{1,2})
246
- \.
247
- (?=\s+|$|[\]])/x ## note: allow end-of-string/line too
248
-
249
-
250
- # e.g. 12 May 2013 14:00 => D|DD.MMM.YYYY H|HH:MM
251
- EN__DD_MONTH_YYYY__DATE_TIME_REGEX = /\b
252
- (?<day>\d{1,2})
253
- \s
254
- (?<month_en>#{MONTH_EN})
255
- \s
256
- (?<year>\d{4})
257
- \s+
258
- (?<hours>\d{1,2})
259
- :
260
- (?<minutes>\d{2})
261
- \b/x
262
-
263
- ###
264
- # fix: pass in lang (e.g. en or es)
265
- # only process format for lang plus fallback to en?
266
- # e.g. EN__DD_MONTH and ES__DD_MONTH depend on order for match (first listed will match)
267
-
268
- # e.g. 12 May => D|DD.MMM w/ implied year and implied hours
269
- EN__DD_MONTH__DATE_REGEX = /\b
270
- (?<day>\d{1,2})
271
- \s
272
- (?<month_en>#{MONTH_EN})
273
- \b/x
274
-
275
-
276
- # e.g. Jun/12 2011 14:00
277
- EN__MONTH_DD_YYYY__DATE_TIME_REGEX = /\b
278
- (?<month_en>#{MONTH_EN})
279
- \/
280
- (?<day>\d{1,2})
281
- \s
282
- (?<year>\d{4})
283
- \s+
284
- (?<hours>\d{1,2})
285
- :
286
- (?<minutes>\d{2})
287
- \b/x
288
-
289
- # e.g. Jun/12 14:00 w/ implied year H|HH:MM
290
- EN__MONTH_DD__DATE_TIME_REGEX = /\b
291
- (?<month_en>#{MONTH_EN})
292
- \/
293
- (?<day>\d{1,2})
294
- \s+
295
- (?<hours>\d{1,2})
296
- :
297
- (?<minutes>\d{2})
298
- \b/x
299
-
300
- # e.g. Jun/12 2013 w/ implied hours (set to 12:00)
301
- EN__MONTH_DD_YYYY__DATE_REGEX = /\b
302
- (?<month_en>#{MONTH_EN})
303
- \/
304
- (?<day>\d{1,2})
305
- \s
306
- (?<year>\d{4})
307
- \b/x
308
-
309
- # e.g. Jun/12 w/ implied year and implied hours (set to 12:00)
310
- # note: allow space too e.g Jun 12 -- check if conflicts w/ other formats??? (added for rsssf reader)
311
- # -- fix: might eat french weekday mar 12 is mardi (mar) !!! see FR__ pattern
312
- # fix: remove space again for now - and use simple en date reader or something!!!
313
- ## was [\/ ] changed back to \/
314
- EN__MONTH_DD__DATE_REGEX = /\b
315
- (?<month_en>#{MONTH_EN})
316
- \/
317
- (?<day>\d{1,2})
318
- \b/x
319
-
320
-
321
- # e.g. 12 Ene w/ implied year and implied hours (set to 12:00)
322
- ES__DD_MONTH__DATE_REGEX = /\b
323
- (?<day>\d{1,2})
324
- \s
325
- (?<month_es>#{MONTH_ES})
326
- \b/x
327
-
328
- # e.g. Ven 8 Août or [Ven 8 Août] or Ven 8. Août or [Ven 8. Août]
329
- ### note: do NOT consume [] in regex (use lookahead assert)
330
- FR__WEEKDAY_DD_MONTH__DATE_REGEX = /\b
331
- (?:#{WEEKDAY_FR}) # note: skip weekday for now; do NOT capture
332
- \s+
333
- (?<day>\d{1,2})
334
- \.? # note: make dot optional
335
- \s+
336
- (?<month_fr>#{MONTH_FR})
337
- (?=\s+|$|[\]])/x ## note: allow end-of-string/line too
338
-
339
-
340
-
341
-
342
- # map table - 1) tag, 2) regex - note: order matters; first come-first matched/served
343
- FORMATS = [
344
- [ '[YYYY_MM_DD_hh_mm]', DB__DATE_TIME_REGEX ],
345
- [ '[YYYY_MM_DD]', DB__DATE_REGEX ],
346
- [ '[DD_MM_YYYY_hh_mm]', DD_MM_YYYY__DATE_TIME_REGEX ],
347
- [ '[DD_MM_hh_mm]', DD_MM__DATE_TIME_REGEX ],
348
- [ '[DD_MM_YYYY]', DD_MM_YYYY__DATE_REGEX ],
349
- [ '[DD_MM]', DD_MM__DATE_REGEX ],
350
- [ '[FR_WEEKDAY_DD_MONTH]', FR__WEEKDAY_DD_MONTH__DATE_REGEX ],
351
- [ '[EN_DD_MONTH_YYYY_hh_mm]', EN__DD_MONTH_YYYY__DATE_TIME_REGEX ],
352
- [ '[EN_MONTH_DD_YYYY_hh_mm]', EN__MONTH_DD_YYYY__DATE_TIME_REGEX ],
353
- [ '[EN_MONTH_DD_hh_mm]', EN__MONTH_DD__DATE_TIME_REGEX ],
354
- [ '[EN_MONTH_DD_YYYY]', EN__MONTH_DD_YYYY__DATE_REGEX ],
355
- [ '[EN_MONTH_DD]', EN__MONTH_DD__DATE_REGEX ],
356
- [ '[EN_DD_MONTH]', EN__DD_MONTH__DATE_REGEX ],
357
- [ '[ES_DD_MONTH]', ES__DD_MONTH__DATE_REGEX ]
358
- ]
359
-
360
-
361
-
362
- def initialize
363
- # nothing here for now
364
- end
365
-
366
- def find!( line, opts={} )
367
- # fix: use more lookahead for all required trailing spaces!!!!!
368
- # fix: use <name capturing group> for month,day,year etc.!!!
369
-
370
- #
371
- # fix: !!!!
372
- # date in [] will become [[DATE.DE4]] - when getting removed will keep ]!!!!
373
- # fix: change regex to \[[A-Z0-9.]\] !!!!!! plus add unit test too!!!
374
- #
375
-
376
- md = nil
377
- FORMATS.each do |format|
378
- tag = format[0]
379
- pattern = format[1]
380
- md=pattern.match( line )
381
- if md
382
- date = parse_date_time( md, opts )
383
- ## fix: use md[0] e.g. match for sub! instead of using regex again - why? why not???
384
- ## fix: use md.begin(0), md.end(0)
385
- line.sub!( md[0], tag )
386
- ## todo/fix: make sure match data will not get changed (e.g. using sub! before parse_date_time)
387
- return date
388
- end
389
- # no match; continue; try next pattern
390
- end
391
-
392
- return nil # no match found
393
- end
394
-
395
- end # class DateFinder
396
-
397
-
398
- class RsssfDateFinder < DateFinderBase
399
-
400
- include LogUtils::Logging
401
-
402
- MONTH_EN = 'Jan|'+
403
- 'Feb|'+
404
- 'March|Mar|'+
405
- 'April|Apr|'+
406
- 'May|'+
407
- 'June|Jun|'+
408
- 'July|Jul|'+
409
- 'Aug|'+
410
- 'Sept|Sep|'+
411
- 'Oct|'+
412
- 'Nov|'+
413
- 'Dec'
414
-
415
- ## e.g.
416
- ## [Jun 7] or [Aug 12] etc. - not MUST include brackets e.g. []
417
- ##
418
- ## check add \b at the beginning and end - why?? why not?? working??
419
- EN__MONTH_DD__DATE_REGEX = /\[
420
- (?<month_en>#{MONTH_EN})
421
- \s
422
- (?<day>\d{1,2})
423
- \]/x
424
-
425
- def find!( line, opts={} )
426
- # fix: use more lookahead for all required trailing spaces!!!!!
427
- # fix: use <name capturing group> for month,day,year etc.!!!
428
-
429
- tag = '[EN_MONTH_DD]'
430
- pattern = EN__MONTH_DD__DATE_REGEX
431
- md = pattern.match( line )
432
- if md
433
- date = parse_date_time( md, opts )
434
- ## fix: use md[0] e.g. match for sub! instead of using regex again - why? why not???
435
- ## fix: use md.begin(0), md.end(0)
436
- line.sub!( md[0], tag )
437
- ## todo/fix: make sure match data will not get changed (e.g. using sub! before parse_date_time)
438
- return date
439
- end
440
- return nil # no match found
441
- end
442
-
443
-
444
- end ## class RsssfDateFinder
445
-
446
- end # module SportDb