sportdb-formats 1.1.6 → 1.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 +5 -5
- data/CHANGELOG.md +2 -0
- data/Manifest.txt +4 -25
- data/Rakefile +1 -1
- data/lib/sportdb/formats/country/country_reader.rb +142 -142
- data/lib/sportdb/formats/datafile.rb +59 -59
- data/lib/sportdb/formats/event/event_reader.rb +184 -183
- data/lib/sportdb/formats/goals.rb +37 -1
- data/lib/sportdb/formats/ground/ground_reader.rb +289 -0
- data/lib/sportdb/formats/league/league_reader.rb +152 -168
- data/lib/sportdb/formats/lines_reader.rb +47 -0
- data/lib/sportdb/formats/match/match_parser.rb +102 -12
- data/lib/sportdb/formats/match/match_parser_auto_conf.rb +270 -202
- data/lib/sportdb/formats/outline_reader.rb +0 -1
- data/lib/sportdb/formats/package.rb +394 -374
- data/lib/sportdb/formats/search/sport.rb +357 -0
- data/lib/sportdb/formats/search/world.rb +139 -0
- data/lib/sportdb/formats/team/club_index_history.rb +134 -134
- data/lib/sportdb/formats/team/club_reader.rb +318 -350
- data/lib/sportdb/formats/team/club_reader_history.rb +203 -203
- data/lib/sportdb/formats/team/wiki_reader.rb +108 -108
- data/lib/sportdb/formats/version.rb +4 -7
- data/lib/sportdb/formats.rb +60 -27
- metadata +13 -35
- data/lib/sportdb/formats/country/country_index.rb +0 -192
- data/lib/sportdb/formats/event/event_index.rb +0 -141
- data/lib/sportdb/formats/league/league_index.rb +0 -178
- data/lib/sportdb/formats/team/club_index.rb +0 -338
- data/lib/sportdb/formats/team/national_team_index.rb +0 -114
- data/lib/sportdb/formats/team/team_index.rb +0 -43
- data/test/helper.rb +0 -132
- data/test/test_club_index.rb +0 -183
- data/test/test_club_index_history.rb +0 -107
- data/test/test_club_reader.rb +0 -201
- data/test/test_club_reader_history.rb +0 -212
- data/test/test_club_reader_props.rb +0 -54
- data/test/test_country_index.rb +0 -63
- data/test/test_country_reader.rb +0 -89
- data/test/test_datafile.rb +0 -30
- data/test/test_datafile_package.rb +0 -46
- data/test/test_goals.rb +0 -113
- data/test/test_league_index.rb +0 -157
- data/test/test_league_outline_reader.rb +0 -55
- data/test/test_league_reader.rb +0 -72
- data/test/test_outline_reader.rb +0 -31
- data/test/test_package.rb +0 -78
- data/test/test_package_match.rb +0 -102
- data/test/test_regex.rb +0 -67
- data/test/test_wiki_reader.rb +0 -77
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
|
3
2
|
module SportDb
|
4
3
|
|
@@ -21,13 +20,44 @@ class MatchParser ## simple match parser for team match schedules
|
|
21
20
|
# for convenience split string into lines
|
22
21
|
## note: removes/strips empty lines
|
23
22
|
## todo/check: change to text instead of array of lines - why? why not?
|
24
|
-
|
25
|
-
|
23
|
+
|
24
|
+
## note - wrap in enumerator/iterator a.k.a lines reader
|
25
|
+
@lines = LinesReader.new( lines.is_a?( String ) ?
|
26
|
+
read_lines( lines ) :
|
27
|
+
lines
|
28
|
+
)
|
29
|
+
|
26
30
|
@mapper_teams = TeamMapper.new( teams )
|
27
31
|
@start = start
|
28
32
|
end
|
29
33
|
|
30
34
|
|
35
|
+
|
36
|
+
|
37
|
+
## note: colon (:) MUST be followed by one (or more) spaces
|
38
|
+
## make sure mon feb 12 18:10 will not match
|
39
|
+
## allow 1. FC Köln etc.
|
40
|
+
## Mainz 05:
|
41
|
+
## limit to 30 chars max
|
42
|
+
## only allow chars incl. intl buut (NOT ()[]/;)
|
43
|
+
##
|
44
|
+
## Group A:
|
45
|
+
## Group B: - remove colon
|
46
|
+
## or lookup first
|
47
|
+
|
48
|
+
ATTRIB_REGEX = /^
|
49
|
+
[ ]*? # slurp leading spaces
|
50
|
+
(?<key>[^:|\]\[()\/; -]
|
51
|
+
[^:|\]\[()\/;]{0,30}
|
52
|
+
)
|
53
|
+
[ ]*? # slurp trailing spaces
|
54
|
+
:[ ]+
|
55
|
+
(?<value>.+)
|
56
|
+
[ ]*? # slurp trailing spaces
|
57
|
+
$
|
58
|
+
/ix
|
59
|
+
|
60
|
+
|
31
61
|
def parse
|
32
62
|
@last_date = nil
|
33
63
|
@last_round = nil
|
@@ -39,11 +69,10 @@ class MatchParser ## simple match parser for team match schedules
|
|
39
69
|
|
40
70
|
@warns = [] ## track list of warnings (unmatched lines) too - why? why not?
|
41
71
|
|
42
|
-
|
72
|
+
## todo/fix - use @lines.rewind first here - why? why not?
|
43
73
|
@lines.each do |line|
|
44
|
-
|
45
|
-
|
46
|
-
elsif is_round_def?( line )
|
74
|
+
|
75
|
+
if is_round_def?( line )
|
47
76
|
## todo/fix: add round definition (w begin n end date)
|
48
77
|
## todo: do not patch rounds with definition (already assume begin/end date is good)
|
49
78
|
## -- how to deal with matches that get rescheduled/postponed?
|
@@ -56,6 +85,32 @@ class MatchParser ## simple match parser for team match schedules
|
|
56
85
|
elsif is_group?( line )
|
57
86
|
## -- lets you set group e.g. Group A etc.
|
58
87
|
parse_group_header( line )
|
88
|
+
|
89
|
+
elsif m=ATTRIB_REGEX.match( line )
|
90
|
+
## note: check attrib regex AFTER group def e.g.:
|
91
|
+
## Group A:
|
92
|
+
## Group B: etc.
|
93
|
+
## todo/fix - change Group A: to Group A etc.
|
94
|
+
## Group B: to Group B
|
95
|
+
|
96
|
+
## check if line ends with dot
|
97
|
+
## if not slurp up lines to the next do!!!
|
98
|
+
logger.debug "skipping key/value line - >#{line}<"
|
99
|
+
while !line.end_with?( '.' ) || line.nil? do
|
100
|
+
line = @lines.next
|
101
|
+
logger.debug "skipping key/value line (cont.) - >#{line}<"
|
102
|
+
end
|
103
|
+
elsif is_goals?( line )
|
104
|
+
## note - goals must be AFTER attributes!!!
|
105
|
+
logger.debug "matched goals line: >#{line}<"
|
106
|
+
logger.debug " try parse:"
|
107
|
+
|
108
|
+
goals = GoalsFinder.new.find!( line )
|
109
|
+
pp goals
|
110
|
+
## quick & dirty - auto add goals to last match
|
111
|
+
match = @matches[-1]
|
112
|
+
match.goals = goals
|
113
|
+
|
59
114
|
elsif try_parse_game( line )
|
60
115
|
# do nothing here
|
61
116
|
elsif try_parse_date_header( line )
|
@@ -317,12 +372,28 @@ class MatchParser ## simple match parser for team match schedules
|
|
317
372
|
def parse_game( line )
|
318
373
|
logger.debug "parsing game (fixture) line: >#{line}<"
|
319
374
|
|
320
|
-
## split by geo (@)
|
375
|
+
## split by geo (@)
|
321
376
|
## split into parts e.g. break using @ !!!
|
322
377
|
values = line.split( '@' )
|
323
|
-
|
378
|
+
|
379
|
+
## for now pass along ground, city (timezone) as string as is
|
380
|
+
## parse (map) later - why? why not??
|
381
|
+
### check for ground/stadium and cities
|
382
|
+
ground = if values.size == 1
|
383
|
+
nil ## no stadium
|
384
|
+
elsif values.size == 2 # bingo!!!
|
385
|
+
## process stadium, city (timezone) etc.
|
386
|
+
## for now keep it simple - pass along "unparsed" all-in-one
|
387
|
+
values[1].gsub( /[ \t]+/, ' ').strip ## squish
|
388
|
+
else
|
389
|
+
puts "!! ERROR - too many @-markers found in line:"
|
390
|
+
puts line
|
391
|
+
exit 1
|
392
|
+
end
|
324
393
|
|
325
394
|
|
395
|
+
line = values[0]
|
396
|
+
|
326
397
|
@mapper_teams.map_teams!( line ) ### todo/fix: limit mapping to two(2) teams - why? why not? might avoid matching @ Barcelona ??
|
327
398
|
teams = @mapper_teams.find_teams!( line )
|
328
399
|
team1 = teams[0]
|
@@ -340,7 +411,12 @@ class MatchParser ## simple match parser for team match schedules
|
|
340
411
|
|
341
412
|
## pos = find_game_pos!( line )
|
342
413
|
|
343
|
-
date = find_date!( line, start: @start )
|
414
|
+
date = find_date!( line, start: @start ) ## date or datetime (but NOT time!)
|
415
|
+
|
416
|
+
## todo/fix:
|
417
|
+
## add support for find_time! e.g. 21.00 (or 21:00 ?)
|
418
|
+
|
419
|
+
|
344
420
|
|
345
421
|
###
|
346
422
|
# check if date found?
|
@@ -387,13 +463,27 @@ class MatchParser ## simple match parser for team match schedules
|
|
387
463
|
|
388
464
|
## todo/check: pass along round and group refs or just string (canonical names) - why? why not?
|
389
465
|
|
390
|
-
|
466
|
+
|
467
|
+
## split date in date & time if DateTime
|
468
|
+
time_str = nil
|
469
|
+
date_str = nil
|
470
|
+
if date.is_a?( DateTime )
|
471
|
+
date_str = date.strftime('%Y-%m-%d')
|
472
|
+
time_str = date.strftime('%H:%M')
|
473
|
+
elsif date.is_a?( Date )
|
474
|
+
date_str = date.strftime('%Y-%m-%d')
|
475
|
+
else # assume date is nil
|
476
|
+
end
|
477
|
+
|
478
|
+
@matches << Import::Match.new( date: date_str,
|
479
|
+
time: time_str,
|
391
480
|
team1: team1, ## note: for now always use mapping value e.g. rec (NOT string e.g. team1.name)
|
392
481
|
team2: team2, ## note: for now always use mapping value e.g. rec (NOT string e.g. team2.name)
|
393
482
|
score: score,
|
394
483
|
round: round ? round.name : nil, ## note: for now always use string (assume unique canonical name for event)
|
395
484
|
group: @last_group ? @last_group.name : nil, ## note: for now always use string (assume unique canonical name for event)
|
396
|
-
status: status
|
485
|
+
status: status,
|
486
|
+
ground: ground )
|
397
487
|
### todo: cache team lookups in hash?
|
398
488
|
|
399
489
|
=begin
|
@@ -1,202 +1,270 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
##
|
10
|
-
|
11
|
-
parser
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
include
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
##
|
23
|
-
|
24
|
-
|
25
|
-
@
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
@
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
##
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
1
|
+
|
2
|
+
module SportDb
|
3
|
+
|
4
|
+
|
5
|
+
class AutoConfParser ## todo/check: rename/change to MatchAutoConfParser - why? why not?
|
6
|
+
|
7
|
+
def self.parse( lines, start: )
|
8
|
+
## todo/fix: add support for txt and lines
|
9
|
+
## check if lines_or_txt is an array or just a string
|
10
|
+
parser = new( lines, start )
|
11
|
+
parser.parse
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
include Logging ## e.g. logger#debug, logger#info, etc.
|
16
|
+
include ParserHelper ## e.g. read_lines, etc.
|
17
|
+
|
18
|
+
|
19
|
+
def initialize( lines, start )
|
20
|
+
# for convenience split string into lines
|
21
|
+
## note: removes/strips empty lines
|
22
|
+
## todo/check: change to text instead of array of lines - why? why not?
|
23
|
+
|
24
|
+
## note - wrap in enumerator/iterator a.k.a lines reader
|
25
|
+
@lines = LinesReader.new( lines.is_a?( String ) ?
|
26
|
+
read_lines( lines ) :
|
27
|
+
lines
|
28
|
+
)
|
29
|
+
|
30
|
+
@start = start
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
## note: colon (:) MUST be followed by one (or more) spaces
|
35
|
+
## make sure mon feb 12 18:10 will not match
|
36
|
+
## allow 1. FC Köln etc.
|
37
|
+
## Mainz 05:
|
38
|
+
## limit to 30 chars max
|
39
|
+
## only allow chars incl. intl buut (NOT ()[]/;)
|
40
|
+
##
|
41
|
+
## Group A:
|
42
|
+
## Group B: - remove colon
|
43
|
+
## or lookup first
|
44
|
+
|
45
|
+
ATTRIB_REGEX = /^
|
46
|
+
[ ]*? # slurp leading spaces
|
47
|
+
(?<key>[^:|\]\[()\/; -]
|
48
|
+
[^:|\]\[()\/;]{0,30}
|
49
|
+
)
|
50
|
+
[ ]*? # slurp trailing spaces
|
51
|
+
:[ ]+
|
52
|
+
(?<value>.+)
|
53
|
+
[ ]*? # slurp trailing spaces
|
54
|
+
$
|
55
|
+
/ix
|
56
|
+
|
57
|
+
|
58
|
+
def parse
|
59
|
+
## try to find all teams in match schedule
|
60
|
+
@last_round = nil
|
61
|
+
@last_group = nil
|
62
|
+
|
63
|
+
## definitions/defs
|
64
|
+
@round_defs = Hash.new(0)
|
65
|
+
@group_defs = Hash.new(0)
|
66
|
+
|
67
|
+
## usage/refs
|
68
|
+
@rounds = {} ## track usage counter and match (two teams) counter
|
69
|
+
@groups = {} ## -"-
|
70
|
+
|
71
|
+
@teams = Hash.new(0) ## keep track of usage counter
|
72
|
+
|
73
|
+
## note: ground incl. optional city (timezone) etc. - why? why not?
|
74
|
+
@grounds = Hash.new(0)
|
75
|
+
|
76
|
+
@warns = [] ## track list of warnings (unmatched lines) too - why? why not?
|
77
|
+
|
78
|
+
|
79
|
+
## todo/fix - use @lines.rewind first here - why? why not?
|
80
|
+
@lines.each do |line|
|
81
|
+
if is_round_def?( line )
|
82
|
+
## todo/fix: add round definition (w begin n end date)
|
83
|
+
## todo: do not patch rounds with definition (already assume begin/end date is good)
|
84
|
+
## -- how to deal with matches that get rescheduled/postponed?
|
85
|
+
logger.debug "skipping matched round def line: >#{line}<"
|
86
|
+
@round_defs[ line ] += 1
|
87
|
+
elsif is_round?( line )
|
88
|
+
logger.debug "skipping matched round line: >#{line}<"
|
89
|
+
|
90
|
+
round = @rounds[ line ] ||= {count: 0, match_count: 0} ## usage counter, match counter
|
91
|
+
round[:count] +=1
|
92
|
+
@last_round = round
|
93
|
+
elsif is_group_def?( line ) ## NB: group goes after round (round may contain group marker too)
|
94
|
+
### todo: add pipe (|) marker (required)
|
95
|
+
logger.debug "skipping matched group def line: >#{line}<"
|
96
|
+
@group_defs[ line ] += 1
|
97
|
+
elsif is_group?( line )
|
98
|
+
## -- lets you set group e.g. Group A etc.
|
99
|
+
logger.debug "skipping matched group line: >#{line}<"
|
100
|
+
|
101
|
+
group = @groups[ line ] ||= {count: 0, match_count: 0}
|
102
|
+
group[:count] +=1
|
103
|
+
@last_group = group
|
104
|
+
## todo/fix: parse group line!!!
|
105
|
+
elsif m=ATTRIB_REGEX.match( line )
|
106
|
+
## note: check attrib regex AFTER group def e.g.:
|
107
|
+
## Group A:
|
108
|
+
## Group B: etc.
|
109
|
+
## todo/fix - change Group A: to Group A etc.
|
110
|
+
## Group B: to Group B
|
111
|
+
|
112
|
+
## check if line ends with dot
|
113
|
+
## if not slurp up lines to the next do!!!
|
114
|
+
logger.debug "skipping key/value line - >#{line}<"
|
115
|
+
while !line.end_with?( '.' ) || line.nil? do
|
116
|
+
line = @lines.next
|
117
|
+
logger.debug "skipping key/value line (cont.) - >#{line}<"
|
118
|
+
end
|
119
|
+
elsif is_goals?( line )
|
120
|
+
## note - goals must be AFTER attributes!!!
|
121
|
+
logger.debug "skipping matched goals line: >#{line}<"
|
122
|
+
elsif try_parse_game( line )
|
123
|
+
# do nothing here
|
124
|
+
else
|
125
|
+
logger.warn "skipping line (no match found): >#{line}<"
|
126
|
+
@warns << line
|
127
|
+
end
|
128
|
+
end # lines.each
|
129
|
+
|
130
|
+
## new - add grounds and cities
|
131
|
+
[@teams, @rounds, @groups, @round_defs, @group_defs,
|
132
|
+
@grounds, ## note: ground incl. optional city (timezone) etc.
|
133
|
+
@warns]
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
def try_parse_game( line )
|
138
|
+
# note: clone line; for possible test do NOT modify in place for now
|
139
|
+
# note: returns true if parsed, false if no match
|
140
|
+
parse_game( line.dup )
|
141
|
+
end
|
142
|
+
|
143
|
+
def parse_game( line )
|
144
|
+
logger.debug "parsing game (fixture) line: >#{line}<"
|
145
|
+
|
146
|
+
## remove all protected text runs e.g. []
|
147
|
+
## fix: add [ to end-of-line too
|
148
|
+
## todo/fix: move remove protected text runs AFTER find date!! - why? why not?
|
149
|
+
|
150
|
+
line = line.gsub( /\[
|
151
|
+
[^\]]+?
|
152
|
+
\]/x, '' ).strip
|
153
|
+
return true if line.empty? ## note: return true (for valid line with no match/teams)
|
154
|
+
|
155
|
+
|
156
|
+
## split by geo (@) - remove for now
|
157
|
+
values = line.split( '@' )
|
158
|
+
|
159
|
+
### check for ground/stadium and cities
|
160
|
+
if values.size == 1
|
161
|
+
## no stadium
|
162
|
+
elsif values.size == 2 # bingo!!!
|
163
|
+
## process stadium, city (timezone) etc.
|
164
|
+
## for now keep it simple - pass along "unparsed" all-in-one
|
165
|
+
ground = values[1].gsub( /[ \t]+/, ' ').strip ## squish
|
166
|
+
@grounds[ ground ] += 1
|
167
|
+
else
|
168
|
+
puts "!! ERROR - too many @-markers found in line:"
|
169
|
+
puts line
|
170
|
+
exit 1
|
171
|
+
end
|
172
|
+
|
173
|
+
line = values[0]
|
174
|
+
|
175
|
+
|
176
|
+
## try find date
|
177
|
+
date = find_date!( line, start: @start )
|
178
|
+
if date ## if found remove tagged run too; note using singular sub (NOT global gsub)
|
179
|
+
line = line.sub( /\[
|
180
|
+
[^\]]+?
|
181
|
+
\]/x, '' ).strip
|
182
|
+
|
183
|
+
else
|
184
|
+
## check for leading hours only e.g. 20.30 or 20:30 or 20h30 or 20H30 or 09h00
|
185
|
+
## todo/fix: make language dependent (or move to find_date/hour etc.) - why? why not?
|
186
|
+
line = line.sub( %r{^ ## MUST be anchored to beginning of line
|
187
|
+
[012]?[0-9]
|
188
|
+
[.:hH]
|
189
|
+
[0-9][0-9]
|
190
|
+
(?=[ ]) ## must be followed by space for now (add end of line too - why? why not?)
|
191
|
+
}x, '' ).strip
|
192
|
+
end
|
193
|
+
|
194
|
+
return true if line.empty? ## note: return true (for valid line with no match/teams)
|
195
|
+
|
196
|
+
|
197
|
+
score = find_score!( line )
|
198
|
+
|
199
|
+
logger.debug " line: >#{line}<"
|
200
|
+
|
201
|
+
line = line.sub( /\[
|
202
|
+
[^\]]+?
|
203
|
+
\]/x, '$$' ) # note: replace first score tag with $$
|
204
|
+
line = line.gsub( /\[
|
205
|
+
[^\]]+?
|
206
|
+
\]/x, '' ) # note: replace/remove all other score tags with nothing
|
207
|
+
|
208
|
+
## clean-up remove all text run inside () or empty () too
|
209
|
+
line = line.gsub( /\(
|
210
|
+
[^)]*?
|
211
|
+
\)/x, '' )
|
212
|
+
|
213
|
+
|
214
|
+
## check for more match separators e.g. - or vs for now
|
215
|
+
line = line.sub( / \s+
|
216
|
+
( -
|
217
|
+
| v
|
218
|
+
| vs\.? # note: allow optional dot eg. vs.
|
219
|
+
)
|
220
|
+
\s+
|
221
|
+
/ix, '$$' )
|
222
|
+
|
223
|
+
values = line.split( '$$' )
|
224
|
+
values = values.map { |value| value.strip } ## strip spaces
|
225
|
+
values = values.select { |value| !value.empty? } ## remove empty strings
|
226
|
+
|
227
|
+
return true if values.size == 0 ## note: return true (for valid line with no match/teams)
|
228
|
+
|
229
|
+
if values.size == 1
|
230
|
+
puts "(auto config) try matching teams separated by spaces (2+):"
|
231
|
+
pp values
|
232
|
+
|
233
|
+
values = values[0].split( /[ ]{2,}/ )
|
234
|
+
pp values
|
235
|
+
end
|
236
|
+
|
237
|
+
return false if values.size != 2
|
238
|
+
|
239
|
+
puts "(auto config) try matching teams:"
|
240
|
+
pp values
|
241
|
+
|
242
|
+
@teams[ values[0] ] += 1 ## update usage counters
|
243
|
+
@teams[ values[1] ] += 1
|
244
|
+
|
245
|
+
@last_round[ :match_count ] += 1 if @last_round
|
246
|
+
@last_group[ :match_count ] += 1 if @last_group
|
247
|
+
|
248
|
+
true
|
249
|
+
end
|
250
|
+
|
251
|
+
|
252
|
+
|
253
|
+
def find_score!( line )
|
254
|
+
# note: always call after find_dates !!!
|
255
|
+
# scores match date-like patterns!! e.g. 10-11 or 10:00 etc.
|
256
|
+
# -- note: score might have two digits too
|
257
|
+
ScoreFormats.find!( line )
|
258
|
+
end
|
259
|
+
|
260
|
+
def find_date!( line, start: )
|
261
|
+
## NB: lets us pass in start_at/end_at date (for event)
|
262
|
+
# for auto-complete year
|
263
|
+
|
264
|
+
# extract date from line
|
265
|
+
# and return it
|
266
|
+
# NB: side effect - removes date from line string
|
267
|
+
DateFormats.find!( line, start: start )
|
268
|
+
end
|
269
|
+
end # class AutoConfParser
|
270
|
+
end # module SportDb
|