sportdb-quick 0.3.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b43470a4bd201f62546d9a790b837f3bfc8210f6dedadef0fbe812dc64e7d97d
4
- data.tar.gz: 95d9917fd58cc4b0967bcac350c5d11893acffd9f420b2d04310d3b8c9464baf
3
+ metadata.gz: d352420645cf51612b5f1c1185f955ac0766d6bb26d84cae1a9e2adc16b2bd1e
4
+ data.tar.gz: fa83e99ca9c5b86ad8f9a101513d537e52338d03e181809579ef06ad03788cff
5
5
  SHA512:
6
- metadata.gz: 89c899e6c26a654f8e799935f5c9a0521c7c985d1cd80957c60bbeacbe90304511f204bca1511d0b8fc621bf05629fad98fd438e38eb9c0f0d2d224960702f64
7
- data.tar.gz: 57ae74125c564a83487a03bf47734f14590a35ff99e54d8b8343bbff71740d3bab6fc7edf707ca1f8cbc510502f2fb819555b0c6863f71bc4dca5d60a6f5d2bb
6
+ metadata.gz: 3f962bf9735b43bf53aa733c7543679f00daa08582862b4c4624fdc96556d148a2bcb2ea7a16f7a9637bae908cd71591bbc6f0b2fd7b7a0124d3106712a9094b
7
+ data.tar.gz: 818778f17464a71e2e8f7997661a00d4fd0844a5ebffdb22eb7800590f55bf7a7ccbd49aefe7fdd2d325eef84cb4669cdfb1287b5f819d5e5d6aae438c7ae759
data/CHANGELOG.md CHANGED
@@ -1,4 +1,4 @@
1
- ### 0.3.0
1
+ ### 0.5.0
2
2
  ### 0.0.1 / 2024-08-27
3
3
 
4
4
  * Everything is new. First release.
data/Manifest.txt CHANGED
@@ -2,8 +2,6 @@ CHANGELOG.md
2
2
  Manifest.txt
3
3
  README.md
4
4
  Rakefile
5
- bin/fbt
6
- bin/fbx
7
5
  lib/sportdb/quick.rb
8
6
  lib/sportdb/quick/match_parser.rb
9
7
  lib/sportdb/quick/quick_league_outline_reader.rb
data/Rakefile CHANGED
@@ -21,7 +21,7 @@ Hoe.spec 'sportdb-quick' do
21
21
  self.licenses = ['Public Domain']
22
22
 
23
23
  self.extra_deps = [
24
- ['sportdb-parser', '>= 0.2.2'],
24
+ ['sportdb-parser', '>= 0.5.0'],
25
25
  ['sportdb-structs', '>= 0.5.0'],
26
26
  ['logutils', '>= 0.6.1'],
27
27
  ]
@@ -88,8 +88,6 @@ class MatchParser ## simple match parser for team match schedules
88
88
  @last_round = nil
89
89
  @last_group = nil
90
90
 
91
- ## last_goals - rename to (longer) @last_team_goals or such - why? why not?
92
- @last_goals = 1 ## toggle between 1|2 - hacky (quick & dirty) support for multi-line goals, fix soon!
93
91
 
94
92
  @teams = Hash.new(0) ## track counts (only) for now for (interal) team stats - why? why not?
95
93
  @rounds = {}
@@ -99,12 +97,12 @@ class MatchParser ## simple match parser for team match schedules
99
97
  @warns = [] ## track list of warnings (unmatched lines) too - why? why not?
100
98
 
101
99
 
102
-
103
- @parser = Parser.new
104
100
  @tree = []
105
101
 
106
102
  attrib_found = false
107
103
 
104
+
105
+ lines = []
108
106
  @lines.each_with_index do |line,i|
109
107
 
110
108
  if debug?
@@ -134,6 +132,9 @@ class MatchParser ## simple match parser for team match schedules
134
132
  next
135
133
  end
136
134
 
135
+ lines << line
136
+
137
+ =begin
137
138
  t, error_messages = @parser.parse_with_errors( line )
138
139
 
139
140
 
@@ -151,71 +152,47 @@ class MatchParser ## simple match parser for team match schedules
151
152
  pp t if debug?
152
153
 
153
154
  @tree << t
155
+ =end
154
156
  end # each lines
155
157
 
158
+ txt = lines.join( "\n") + "\n"
159
+ parser = RaccMatchParser.new( txt ) ## use own parser instance (not shared) - why? why not?
160
+ @tree = parser.parse
161
+ ## pp @tree
162
+
156
163
  ## pp @tree
157
164
 
158
165
  ## report parse errors here - why? why not?
159
166
 
160
167
 
161
168
 
162
- @tree.each do |nodes|
169
+ @tree.each do |node|
163
170
 
164
- node_type = nodes[0][0] ## get node type of first/head node
165
-
166
- if node_type == :round_def
171
+ if node.is_a? RaccMatchParser::RoundDef
167
172
  ## todo/fix: add round definition (w begin n end date)
168
173
  ## todo: do not patch rounds with definition (already assume begin/end date is good)
169
174
  ## -- how to deal with matches that get rescheduled/postponed?
170
- parse_round_def( nodes )
171
- elsif node_type == :group_def ## NB: group goes after round (round may contain group marker too)
175
+ on_round_def( node )
176
+ elsif node.is_a? RaccMatchParser::GroupDef ## NB: group goes after round (round may contain group marker too)
172
177
  ### todo: add pipe (|) marker (required)
173
- parse_group_def( nodes )
174
-
175
- elsif node_type == :player ||
176
- node_type == :none # e.g [[:none], [:";"], [:player, "Xhaka"],...]
177
- ## note - for now goals line MUST start with player!!
178
- parse_goals( nodes )
179
- else
180
- ## try to be liberal/flexible
181
- ## eat-up nodes as we go
182
- ## assume match with group / round header
183
- ## etc. on its own line or not
184
-
185
- ## preprocess possible before match nodes
186
-
187
- while !nodes.empty? do
188
- node_type = nodes[0][0] ## get node type of first/head node
189
- if node_type == :round
190
- node = nodes.shift ## eat-up
191
- parse_round_header( node )
192
- elsif node_type == :leg
193
- node = nodes.shift ## eat-up
194
- ## ignore (round) leg for now - add later leg - 1|2|3 etc!!!
195
- ## needs to get added to db/schema too!!!!
196
- ## add @last_leg = nil or 1|2|3 etc.
197
- elsif node_type == :group
198
- ## -- lets you set group e.g. Group A etc.
199
- node = nodes.shift ## eat-up
200
- parse_group_header( node )
201
- elsif node_type == :date
202
- node = nodes.shift ## eat-up
203
- parse_date_header( node )
204
- ## add time here too - why? why not?
205
- ## add skip comma separator here too - why? why not?
206
- ## "slurp-up" in upstream parser?
207
- ## e.g. round, group or group, round ?
208
- else
209
- break
210
- end
211
- end
212
- next if nodes.empty?
213
-
214
- ## rename to try_parse_match - why? why not?
215
- parse_match( nodes )
178
+ on_group_def( node )
179
+ elsif node.is_a? RaccMatchParser::GroupHeader
180
+ on_group_header( node )
181
+ elsif node.is_a? RaccMatchParser::RoundHeader
182
+ on_round_header( node )
183
+ elsif node.is_a? RaccMatchParser::DateHeader
184
+ on_date_header( node )
185
+ elsif node.is_a? RaccMatchParser::MatchLine
186
+ on_match_line( node )
187
+ elsif node.is_a? RaccMatchParser::GoalLine
188
+ on_goal_line( node )
189
+ else
190
+ ## report error
191
+ puts "!! ERROR - unknown node (parse tree type)"
192
+ pp node
193
+ exit 1
216
194
  end
217
-
218
- end # tree.each
195
+ end # tree.each
219
196
 
220
197
  ## note - team keys are names and values are "internal" stats!!
221
198
  ## and NOT team/club/nat_team structs!!
@@ -224,8 +201,8 @@ class MatchParser ## simple match parser for team match schedules
224
201
 
225
202
 
226
203
 
227
- def parse_group_header( node )
228
- logger.debug "parsing group header: >#{node}<"
204
+ def on_group_header( node )
205
+ logger.debug "on group header: >#{node}<"
229
206
 
230
207
  # note: group header resets (last) round (allows, for example):
231
208
  # e.g.
@@ -235,7 +212,7 @@ class MatchParser ## simple match parser for team match schedules
235
212
  # team1 team2 - match (will get new auto-matchday! not last round)
236
213
  @last_round = nil
237
214
 
238
- name = node[1]
215
+ name = node.name
239
216
 
240
217
  group = @groups[ name ]
241
218
  if group.nil?
@@ -248,8 +225,8 @@ class MatchParser ## simple match parser for team match schedules
248
225
  end
249
226
 
250
227
 
251
- def parse_group_def( nodes )
252
- logger.debug "parsing group def: >#{nodes}<"
228
+ def on_group_def( node )
229
+ logger.debug "on group def: >#{node}<"
253
230
 
254
231
  ## e.g
255
232
  ## [:group_def, "Group A"],
@@ -258,26 +235,15 @@ class MatchParser ## simple match parser for team match schedules
258
235
  ## [:team, "Hungary"],
259
236
  ## [:team, "Switzerland"]
260
237
 
261
- node = nodes[0]
262
- name = node[1] ## group name
263
-
264
- teams = nodes[1..-1].map do |node|
265
- if node[0] == :team
266
- team = node[1]
267
- @teams[ team ] += 1
268
- team
269
- else
270
- puts "!! PARSE ERROR - only teams expected in group def; got:"
271
- pp nodes
272
- exit 1
273
- end
274
- end
275
-
238
+ node.teams.each do |team|
239
+ @teams[ team ] += 1
240
+ end
241
+
276
242
  ## todo/check/fix: add back group key - why? why not?
277
- group = Import::Group.new( name: name,
278
- teams: teams )
243
+ group = Import::Group.new( name: node.name,
244
+ teams: node.teams )
279
245
 
280
- @groups[ name ] = group
246
+ @groups[ node.name ] = group
281
247
  end
282
248
 
283
249
 
@@ -307,37 +273,35 @@ class MatchParser ## simple match parser for team match schedules
307
273
  Date.new( y,m,d ) ## y,m,d
308
274
  end
309
275
 
310
- def parse_round_def( nodes )
311
- logger.debug "parsing round def: >#{nodes}<"
276
+
277
+ def on_round_def( node )
278
+ logger.debug "on round def: >#{node}<"
312
279
 
313
280
  ## e.g. [[:round_def, "Matchday 1"], [:duration, "Fri Jun/14 - Tue Jun/18"]]
314
281
  ## [[:round_def, "Matchday 2"], [:duration, "Wed Jun/19 - Sat Jun/22"]]
315
282
  ## [[:round_def, "Matchday 3"], [:duration, "Sun Jun/23 - Wed Jun/26"]]
316
283
 
317
- node = nodes[0]
318
- name = node[1]
284
+ name = node.name
319
285
  # NB: use extracted round name for knockout check
320
286
  # knockout_flag = is_knockout_round?( name )
321
287
 
322
- node = nodes[1]
323
- node_type = node[0]
324
- if node_type == :date
325
- start_date = end_date = _build_date( m: node[2][:m],
326
- d: node[2][:d],
327
- y: node[2][:y],
288
+ if node.date
289
+ start_date = end_date = _build_date( m: node.date[:m],
290
+ d: node.date[:d],
291
+ y: node.date[:y],
328
292
  start: @start)
329
- elsif node_type == :duration
330
- start_date = _build_date( m: node[2][:start][:m],
331
- d: node[2][:start][:d],
332
- y: node[2][:start][:y],
293
+ elsif node.duration
294
+ start_date = _build_date( m: node.duration[:start][:m],
295
+ d: node.duration[:start][:d],
296
+ y: node.duration[:start][:y],
333
297
  start: @start)
334
- end_date = _build_date( m: node[2][:end][:m],
335
- d: node[2][:end][:d],
336
- y: node[2][:end][:y],
298
+ end_date = _build_date( m: node.duration[:end][:m],
299
+ d: node.duration[:end][:d],
300
+ y: node.duration[:end][:y],
337
301
  start: @start)
338
302
  else
339
303
  puts "!! PARSE ERROR - expected date or duration for round def; got:"
340
- pp nodes
304
+ pp node
341
305
  exit 1
342
306
  end
343
307
 
@@ -375,10 +339,11 @@ class MatchParser ## simple match parser for team match schedules
375
339
  end
376
340
 
377
341
 
378
- def parse_round_header( node )
379
- logger.debug "parsing round header: >#{node}<"
342
+ def on_round_header( node )
343
+ logger.debug "on round header: >#{node}<"
380
344
 
381
- name = node[1]
345
+ name = node.names[0] ## ignore more names for now
346
+ ## fix later - fix more names!!!
382
347
 
383
348
  # name = name.sub( ROUND_EXTRA_WORDS_RE, '' )
384
349
  # name = name.strip
@@ -399,12 +364,12 @@ class MatchParser ## simple match parser for team match schedules
399
364
  ## reset date/time e.g. @last_date = nil !!!!
400
365
  end
401
366
 
402
- def parse_date_header( node )
367
+ def on_date_header( node )
403
368
  logger.debug( "date header: >#{node}<")
404
369
 
405
- date = _build_date( m: node[2][:m],
406
- d: node[2][:d],
407
- y: node[2][:y],
370
+ date = _build_date( m: node.date[:m],
371
+ d: node.date[:d],
372
+ y: node.date[:y],
408
373
  start: @start )
409
374
 
410
375
  logger.debug( " date: #{date} with start: #{@start}")
@@ -431,93 +396,17 @@ class MatchParser ## simple match parser for team match schedules
431
396
  =end
432
397
  end
433
398
 
434
- def parse_minutes( nodes )
435
- ## parse goals by player
436
- ## may have multiple minutes!!
437
- goals = []
438
-
439
- node = nodes.shift ## get player
440
- name = node[1]
441
-
442
- loop do
443
- goal = {}
444
- goal[:name] = name
445
-
446
- node_type = nodes[0][0]
447
- if node_type != :minute
448
- puts "!! PARSE ERROR - minute expected to follow player (in goal); got #{node_type}:"
449
- pp nodes
450
- exit 1
451
- end
452
-
453
- node = nodes.shift
454
- goal[:minute] = node[2][:m]
455
- goal[:offset] = node[2][:offset] if node[2][:offset]
456
-
457
- ## check for own goal or penalty or such
458
- if !nodes.empty?
459
- node_type = nodes[0][0]
460
- if node_type == :og
461
- nodes.shift
462
- goal[:og] = true
463
- elsif node_type == :pen
464
- nodes.shift
465
- goal[:pen] = true
466
- else
467
- # do nothing
468
- end
469
- end
470
-
471
- goals << goal
472
-
473
- ## check if another minute ahead; otherwise break
474
- break if nodes.empty?
475
-
476
- node_type = nodes[0][0]
477
399
 
478
- ## Kane 39', 62', 67'
479
- ## consume/eat-up (optional?) commas
480
- if node_type == :','
481
- nodes.shift
482
- node_type = nodes[0][0]
483
- end
400
+ def on_goal_line( node )
401
+ logger.debug "on goal line: >#{node}<"
484
402
 
485
- break if node_type != :minute
486
- end
487
-
488
-
489
- goals
490
- end
491
-
492
-
493
- def parse_goals( nodes )
494
- logger.debug "parse goals: >#{nodes}<"
495
-
496
- goals1 = []
497
- goals2 = []
498
-
499
- while !nodes.empty?
500
- node_type = nodes[0][0]
501
- if node_type == :player
502
- more_goals = parse_minutes( nodes )
503
- ## hacky multi-line support for goals
504
- ## using last_goal (1|2)
505
- @last_goals == 2 ? goals2 += more_goals :
506
- goals1 += more_goals
507
- elsif node_type == :';' ## team separator
508
- nodes.shift # eat-up
509
- @last_goals = 2
510
- elsif node_type == :none
511
- nodes.shift # eat-up
512
- else
513
- puts "!! PARSE ERROR - unexpected node type in goals;; got #{node_type}:"
514
- pp nodes
515
- exit 1
516
- end
517
- end
403
+ goals1 = node.goals1
404
+ goals2 = node.goals2
518
405
 
406
+
519
407
  pp [goals1,goals2] if debug?
520
408
 
409
+
521
410
  ## wrap in struct andd add/append to match
522
411
  =begin
523
412
  class GoalStruct
@@ -532,26 +421,30 @@ class GoalStruct
532
421
 
533
422
  goals = []
534
423
  goals1.each do |rec|
535
- goal = Import::Goal.new(
536
- player: rec[:name],
424
+ rec.minutes.each do |minute|
425
+ goal = Import::Goal.new(
426
+ player: rec.player,
537
427
  team: 1,
538
- minute: rec[:minute],
539
- offset: rec[:offset],
540
- penalty: rec[:pen] || false, # note: pass along/use false NOT nil
541
- owngoal: rec[:og] || false
428
+ minute: minute.m,
429
+ offset: minute.offset,
430
+ penalty: minute.pen || false, # note: pass along/use false NOT nil
431
+ owngoal: minute.og || false
542
432
  )
543
- goals << goal
433
+ goals << goal
434
+ end
544
435
  end
545
436
  goals2.each do |rec|
546
- goal = Import::Goal.new(
547
- player: rec[:name],
437
+ rec.minutes.each do |minute|
438
+ goal = Import::Goal.new(
439
+ player: rec.player,
548
440
  team: 2,
549
- minute: rec[:minute],
550
- offset: rec[:offset],
551
- penalty: rec[:pen] || false, # note: pass along/use false NOT nil
552
- owngoal: rec[:og] || false
441
+ minute: minute.m,
442
+ offset: minute.offset,
443
+ penalty: minute.pen || false, # note: pass along/use false NOT nil
444
+ owngoal: minute.og || false
553
445
  )
554
446
  goals << goal
447
+ end
555
448
  end
556
449
 
557
450
  pp goals if debug?
@@ -569,90 +462,65 @@ class GoalStruct
569
462
  end
570
463
 
571
464
 
572
- def parse_match( nodes )
573
- logger.debug( "parse match: >#{nodes}<" )
465
+ def on_match_line( node )
466
+ logger.debug( "on match: >#{node}<" )
574
467
 
575
468
  ## collect (possible) nodes by type
576
469
  num = nil
470
+ num = node.ord if node.ord
471
+
577
472
  date = nil
578
- time = nil
579
- teams = []
473
+ date = _build_date( m: node.date[:m],
474
+ d: node.date[:d],
475
+ y: node.date[:y],
476
+ start: @start ) if node.date
477
+
478
+ ## note - there's no time (-only) type in ruby
479
+ ## use string (e.g. '14:56', '1:44')
480
+ ## use 01:44 or 1:44 ?
481
+ ## check for 0:00 or 24:00 possible?
482
+ time = ('%d:%02d' % [node.time[:h], node.time[:m]]) if node.time
483
+
484
+
485
+ ### todo/fix
486
+ ## add keywords (e.g. ht, ft or such) to Score.new - why? why not?
487
+ ## or use new Score.build( ht:, ft:, ) or such - why? why not?
488
+ ## pp score
580
489
  score = nil
490
+ if node.score
491
+ ht = node.score[:ht] || [nil,nil]
492
+ ft = node.score[:ft] || [nil,nil]
493
+ et = node.score[:et] || [nil,nil]
494
+ p = node.score[:p] || [nil,nil]
495
+ values = [*ht, *ft, *et, *p]
496
+ ## pp values
497
+ score = Score.new( *values )
498
+ end
499
+
581
500
  more = []
501
+
582
502
  status = nil
503
+ ## if node_type == :status # e.g. awarded, canceled, postponed, etc.
504
+ ## status = node[1]
505
+
583
506
 
584
- while !nodes.empty?
585
- node = nodes.shift
586
- node_type = node[0]
587
-
588
- if node_type == :num
589
- num = node[1]
590
- elsif node_type == :date
591
- ## note: date wipes out/clear time
592
- ## time MUST always come after date
593
- time = nil
594
- date = _build_date( m: node[2][:m],
595
- d: node[2][:d],
596
- y: node[2][:y],
597
- start: @start )
598
- elsif node_type == :time
599
- ## note - there's no time (-only) type in ruby
600
- ## use string (e.g. '14:56', '1:44')
601
- ## use 01:44 or 1:44 ?
602
- ## check for 0:00 or 24:00 possible?
603
- time = '%d:%02d' % [node[2][:h], node[2][:m]]
604
- elsif node_type == :team
605
- teams << node[1]
606
- elsif node_type == :score
607
- ### todo/fix
608
- ## add keywords (e.g. ht, ft or such) to Score.new - why? why not?
609
- ## or use new Score.build( ht:, ft:, ) or such - why? why not?
610
- ht = node[2][:ht] || [nil,nil]
611
- ft = node[2][:ft] || [nil,nil]
612
- et = node[2][:et] || [nil,nil]
613
- p = node[2][:p] || [nil,nil]
614
- values = [*ht, *ft, *et, *p]
615
- ## pp values
616
-
617
- score = Score.new( *values )
618
- ## pp score
619
- elsif node_type == :status # e.g. awarded, canceled, postponed, etc.
620
- status = node[1]
621
- elsif node_type == :vs
622
- ## skip; do nothing
623
- ##
507
+ #
624
508
  ## todo - add ## find (optional) match status e.g. [abandoned] or [replay] or [awarded]
625
509
  ## or [cancelled] or [postponed] etc.
626
510
  ## status = find_status!( line ) ## todo/check: allow match status also in geo part (e.g. after @) - why? why not?
627
-
628
- elsif node_type == :'@' ||
629
- node_type == :',' ||
630
- node_type == :geo ||
631
- node_type == :timezone
511
+ #
512
+ # elsif node_type == :'@' ||
513
+ # node_type == :',' ||
514
+ # node_type == :geo ||
515
+ # node_type == :timezone
632
516
  ## e.g.
633
517
  ## [:"@"], [:geo, "Stade de France"], [:","], [:geo, "Saint-Denis"]]
634
518
  ## [:"@"], [:geo, "Arena de São Paulo"], [:","], [:geo, "São Paulo"], [:timezone, "(UTC-3)"]
635
- more << node[1] if node_type == :geo
636
- else
637
- puts "!! PARSE ERROR - unexpected node type #{node_type} in match line; got:"
638
- pp node
639
- ## exit 1
640
- @errors << ["PARSE ERROR - unexpected node type #{node_type} in match line; got: #{node.inspect}"]
641
- return
642
- end
643
- end
644
-
519
+ # more << node[1] if node_type == :geo
520
+
645
521
 
646
- if teams.size != 2
647
- puts "!! PARSE ERROR - expected two teams; got #{teams.size}:"
648
- pp teams
649
- ## exit 1
650
- @errors << ["PARSE ERROR - expected two teams; got #{teams.size}: #{teams.inspect}"]
651
- return
652
- end
653
-
654
- team1 = teams[0]
655
- team2 = teams[1]
522
+ team1 = node.team1
523
+ team2 = node.team2
656
524
 
657
525
  @teams[ team1 ] += 1
658
526
  @teams[ team2 ] += 1
@@ -738,10 +606,6 @@ class GoalStruct
738
606
  status: status,
739
607
  ground: ground )
740
608
  ### todo: cache team lookups in hash?
741
-
742
- ## hacky goals support
743
- ### reset/toggle 1/2
744
- @last_goals = 1
745
609
  end
746
610
  end # class MatchParser
747
611
  end # module SportDb
@@ -3,7 +3,7 @@ module SportDb
3
3
  module Module
4
4
  module Quick
5
5
  MAJOR = 0 ## todo: namespace inside version or something - why? why not??
6
- MINOR = 3
6
+ MINOR = 5
7
7
  PATCH = 0
8
8
  VERSION = [MAJOR,MINOR,PATCH].join('.')
9
9
 
data/lib/sportdb/quick.rb CHANGED
@@ -17,10 +17,6 @@ end
17
17
  ## our own code
18
18
  require_relative 'quick/version'
19
19
 
20
- # require_relative 'quick/opts'
21
- # require_relative 'quick/linter'
22
- # require_relative 'quick/outline_reader'
23
-
24
20
 
25
21
  require_relative 'quick/match_parser'
26
22
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sportdb-quick
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.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-12-30 00:00:00.000000000 Z
11
+ date: 2025-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sportdb-parser
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.2.2
19
+ version: 0.5.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.2.2
26
+ version: 0.5.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sportdb-structs
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -88,9 +88,7 @@ dependencies:
88
88
  version: '4.2'
89
89
  description: sportdb-quick - football.txt (quick) match readers and more
90
90
  email: gerald.bauer@gmail.com
91
- executables:
92
- - fbt
93
- - fbx
91
+ executables: []
94
92
  extensions: []
95
93
  extra_rdoc_files:
96
94
  - CHANGELOG.md
@@ -101,8 +99,6 @@ files:
101
99
  - Manifest.txt
102
100
  - README.md
103
101
  - Rakefile
104
- - bin/fbt
105
- - bin/fbx
106
102
  - lib/sportdb/quick.rb
107
103
  - lib/sportdb/quick/match_parser.rb
108
104
  - lib/sportdb/quick/quick_league_outline_reader.rb
data/bin/fbt DELETED
@@ -1,170 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- ## tip: to test run:
4
- ## ruby -I ./lib bin/fbt
5
- ## -or-
6
- ## ruby -I ../parser/lib -I ./lib bin/fbt
7
- ## -or-
8
- ## ruby -I ../parser/lib -I ../sportdb-structs/lib -I ./lib bin/fbt
9
-
10
-
11
- ## our own code
12
- require 'sportdb/quick'
13
-
14
-
15
-
16
- require 'optparse'
17
-
18
- ##
19
- ## read textfile
20
- ## and dump tokens
21
- ##
22
- ## fbt ../openfootball/.../euro.txt
23
-
24
-
25
-
26
-
27
- args = ARGV
28
- opts = { debug: false,
29
- file: nil,
30
- }
31
-
32
- parser = OptionParser.new do |parser|
33
- parser.banner = "Usage: #{$PROGRAM_NAME} [options]"
34
-
35
- ##
36
- ## check if git has a offline option?? (use same)
37
- ## check for other tools - why? why not?
38
- # parser.on( "-q", "--quiet",
39
- # "less debug output/messages - default is (#{!opts[:debug]})" ) do |debug|
40
- # opts[:debug] = false
41
- # end
42
- parser.on( "--verbose", "--debug",
43
- "turn on verbose / debug output (default: #{opts[:debug]})" ) do |debug|
44
- opts[:debug] = true
45
- end
46
-
47
- parser.on( "-f FILE", "--file FILE",
48
- "read datafiles (pathspecs) via .csv file") do |file|
49
- opts[:file] = file
50
- end
51
-
52
-
53
- end
54
- parser.parse!( args )
55
-
56
- puts "OPTS:"
57
- p opts
58
- puts "ARGV:"
59
- p args
60
-
61
-
62
- ## todo/check - use packs or projects or such
63
- ## instead of specs - why? why not?
64
- specs = []
65
- if opts[:file]
66
- recs = read_csv( opts[:file] )
67
- pp recs
68
- ## note - make pathspecs relative to passed in file arg!!!
69
- basedir = File.dirname( opts[:file] )
70
- recs.each do |rec|
71
- paths = SportDb::Parser::Opts.find( rec['path'], dir: basedir )
72
- specs << [paths, rec]
73
- end
74
- else
75
- paths = if args.empty?
76
- [
77
- '../../../openfootball/euro/2021--europe/euro.txt',
78
- '../../../openfootball/euro/2024--germany/euro.txt',
79
- ]
80
- else
81
- ## check for directories
82
- ## and auto-expand
83
- SportDb::Parser::Opts.expand_args( args )
84
- end
85
- specs << [paths, {}]
86
- end
87
-
88
-
89
- if opts[:debug]
90
- SportDb::QuickMatchReader.debug = true
91
- SportDb::MatchParser.debug = true
92
- else
93
- SportDb::QuickMatchReader.debug = false
94
- SportDb::MatchParser.debug = false
95
- LogUtils::Logger.root.level = :info
96
- end
97
-
98
-
99
- specs.each_with_index do |(paths, rec),i|
100
- errors = []
101
- paths.each_with_index do |path,j|
102
- puts "==> [#{j+1}/#{paths.size}] reading >#{path}<..."
103
- quick = SportDb::QuickMatchReader.new( read_text( path ) )
104
- matches = quick.parse
105
-
106
- if quick.errors?
107
- puts "!! #{quick.errors.size} error(s):"
108
- pp quick.errors
109
-
110
- quick.errors.each do |err|
111
- errors << [ path, *err ] # note: use splat (*) to add extra values (starting with msg)
112
- end
113
- end
114
- puts " #{matches.size} match(es)"
115
- end
116
-
117
- if errors.size > 0
118
- puts
119
- puts "!! #{errors.size} PARSE ERRORS in #{paths.size} datafile(s)"
120
- pp errors
121
- else
122
- puts
123
- puts " OK - no parse errors in #{paths.size} datafile(s)"
124
- end
125
-
126
- ## add errors to rec via rec['errors'] to allow
127
- ## for further processing/reporting
128
- rec['errors'] = errors
129
- end
130
-
131
-
132
-
133
- ###
134
- ## generate a report if --file option used
135
- if opts[:file]
136
-
137
- buf = String.new
138
-
139
- buf << "# fbt summary report - #{specs.size} dataset(s)\n\n"
140
-
141
- specs.each_with_index do |(paths, rec),i|
142
- errors = rec['errors']
143
-
144
- if errors.size > 0
145
- buf << "!! #{errors.size} ERROR(S) "
146
- else
147
- buf << " OK "
148
- end
149
- buf << "%-20s" % rec['path']
150
- buf << " - #{paths.size} datafile(s)"
151
- buf << "\n"
152
-
153
- if errors.size > 0
154
- buf << errors.pretty_inspect
155
- buf << "\n"
156
- end
157
- end
158
-
159
- puts
160
- puts "SUMMARY:"
161
- puts buf
162
-
163
- # maybe write out in the future?
164
- # basedir = File.dirname( opts[:file] )
165
- # basename = File.basename( opts[:file], File.extname( opts[:file] ))
166
- end
167
-
168
-
169
- puts "bye"
170
-
data/bin/fbx DELETED
@@ -1,152 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- ## tip: to test run:
4
- ## ruby -I ./lib -I ../parser/lib bin/fbx
5
-
6
- ##
7
- ## todo/fix - use for testing
8
- # reads textfile and dumps results in json
9
- #
10
- # check - keep fbx name or find a differnt name - why? why not?
11
-
12
-
13
- ## our own code
14
- require 'sportdb/quick'
15
-
16
-
17
-
18
- require 'optparse'
19
-
20
- ##
21
- ## read textfile
22
- ## and dump match parse results
23
- ##
24
- ## fbt ../openfootball/.../euro.txt
25
-
26
-
27
-
28
-
29
- args = ARGV
30
- opts = { debug: false,
31
- outline: false }
32
-
33
- parser = OptionParser.new do |parser|
34
- parser.banner = "Usage: #{$PROGRAM_NAME} [options]"
35
-
36
- ##
37
- ## check if git has a offline option?? (use same)
38
- ## check for other tools - why? why not?
39
-
40
-
41
- parser.on( "--verbose", "--debug",
42
- "turn on verbose / debug output (default: #{opts[:debug]})" ) do |debug|
43
- opts[:debug] = debug
44
- end
45
-
46
- parser.on( "--outline",
47
- "turn on outline (only) output (default: #{opts[:outline]})" ) do |outline|
48
- opts[:outline] = outline
49
- end
50
- end
51
- parser.parse!( args )
52
-
53
- puts "OPTS:"
54
- p opts
55
- puts "ARGV:"
56
- p args
57
-
58
-
59
-
60
-
61
-
62
- paths = if args.empty?
63
- [
64
- '../../../openfootball/euro/2021--europe/euro.txt',
65
- '../../../openfootball/euro/2024--germany/euro.txt',
66
- ]
67
- else
68
- ## check for directories
69
- ## and auto-expand
70
-
71
- SportDb::Parser::Opts.expand_args( args )
72
- end
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
- SportDb::MatchParser.debug = true if opts[:debug]
81
-
82
-
83
- ## errors = []
84
-
85
-
86
- paths.each_with_index do |path,i|
87
- puts "==> [#{i+1}/#{paths.size}] reading >#{path}<..."
88
-
89
- txt = read_text( path )
90
- secs = SportDb::LeagueOutlineReader.parse( txt )
91
- ## pp secs
92
-
93
- secs.each_with_index do |sec,j| ## sec(tion)s
94
- season = sec[:season]
95
- league = sec[:league]
96
- stage = sec[:stage]
97
- lines = sec[:lines]
98
-
99
- puts " section #{j+1}/#{secs.size} - #{league.name} #{season}, #{stage} - #{lines.size} line(s)"
100
-
101
- next if opts[:outline]
102
-
103
- =begin
104
- ### check if event info availabe - use start_date;
105
- ## otherwise we have to guess (use a "synthetic" start_date)
106
- event_info = catalog.events.find_by( season: season,
107
- league: league )
108
-
109
- start = if event_info && event_info.start_date
110
- puts "event info found:"
111
- puts " using start date from event: "
112
- pp event_info
113
- pp event_info.start_date
114
- event_info.start_date
115
- else
116
- =end
117
- start = if season.year?
118
- Date.new( season.start_year, 1, 1 )
119
- else
120
- Date.new( season.start_year, 7, 1 )
121
- end
122
-
123
- parser = SportDb::MatchParser.new( lines,
124
- start ) ## note: keep season start_at date for now (no need for more specific stage date need for now)
125
-
126
- auto_conf_teams, matches, rounds, groups = parser.parse
127
-
128
- puts ">>> #{auto_conf_teams.size} teams:"
129
- pp auto_conf_teams
130
- puts ">>> #{matches.size} matches:"
131
- ## pp matches
132
- puts ">>> #{rounds.size} rounds:"
133
- pp rounds
134
- puts ">>> #{groups.size} groups:"
135
- pp groups
136
- end # each secs
137
- end # each paths
138
-
139
- =begin
140
- if errors.size > 0
141
- puts
142
- pp errors
143
- puts
144
- puts "!! #{errors.size} parse error(s) in #{paths.size} datafiles(s)"
145
- else
146
- puts
147
- puts "OK no parse errors found in #{paths.size} datafile(s)"
148
- end
149
- =end
150
-
151
- puts "bye"
152
-