sportdb-readers 0.4.7 → 0.4.8
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 +4 -4
- data/Manifest.txt +0 -4
- data/Rakefile +1 -1
- data/lib/sportdb/readers.rb +0 -2
- data/lib/sportdb/readers/version.rb +1 -1
- metadata +3 -7
- data/lib/sportdb/readers/conf_parser_auto.rb +0 -171
- data/lib/sportdb/readers/match_parser.rb +0 -476
- data/test/test_conf_parser_auto.rb +0 -489
- data/test/test_match_parser.rb +0 -107
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8fdbf4230ab31efee1c3f29d51e3f447caf9b161
|
|
4
|
+
data.tar.gz: 48df0e0b7e1e28c06670431d7642bf9b0d2d6fbf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 40ce7917d320fada2dd95eb7625ea5f1ec9646729c38c9f540c6cd0e78bf5e7fe8200e82a2b6f546239faa5da120af527c867f364a4aa61fe001a3f8b2fae775
|
|
7
|
+
data.tar.gz: 581fffa22c4ffad1e1c8cb385e99307cc19a7099700a76d387e65e5cfb6194aa35ebd0e104a50473f15893b325955e25b648e429b29835241b2440a5641a7515
|
data/Manifest.txt
CHANGED
|
@@ -4,16 +4,12 @@ README.md
|
|
|
4
4
|
Rakefile
|
|
5
5
|
lib/sportdb/readers.rb
|
|
6
6
|
lib/sportdb/readers/conf_linter.rb
|
|
7
|
-
lib/sportdb/readers/conf_parser_auto.rb
|
|
8
7
|
lib/sportdb/readers/conf_reader.rb
|
|
9
8
|
lib/sportdb/readers/league_outline_reader.rb
|
|
10
9
|
lib/sportdb/readers/match_linter.rb
|
|
11
|
-
lib/sportdb/readers/match_parser.rb
|
|
12
10
|
lib/sportdb/readers/match_reader.rb
|
|
13
11
|
lib/sportdb/readers/package.rb
|
|
14
12
|
lib/sportdb/readers/version.rb
|
|
15
13
|
test/helper.rb
|
|
16
|
-
test/test_conf_parser_auto.rb
|
|
17
|
-
test/test_match_parser.rb
|
|
18
14
|
test/test_read.rb
|
|
19
15
|
test/test_reader.rb
|
data/Rakefile
CHANGED
data/lib/sportdb/readers.rb
CHANGED
|
@@ -10,10 +10,8 @@ require 'sportdb/sync'
|
|
|
10
10
|
# our own code
|
|
11
11
|
require 'sportdb/readers/version' # let version always go first
|
|
12
12
|
require 'sportdb/readers/league_outline_reader'
|
|
13
|
-
require 'sportdb/readers/conf_parser_auto'
|
|
14
13
|
require 'sportdb/readers/conf_reader'
|
|
15
14
|
require 'sportdb/readers/conf_linter'
|
|
16
|
-
require 'sportdb/readers/match_parser'
|
|
17
15
|
require 'sportdb/readers/match_reader'
|
|
18
16
|
require 'sportdb/readers/match_linter'
|
|
19
17
|
require 'sportdb/readers/package'
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sportdb-readers
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gerald Bauer
|
|
@@ -30,14 +30,14 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 1.18.
|
|
33
|
+
version: 1.18.6
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: 1.18.
|
|
40
|
+
version: 1.18.6
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: sportdb-sync
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -96,17 +96,13 @@ files:
|
|
|
96
96
|
- Rakefile
|
|
97
97
|
- lib/sportdb/readers.rb
|
|
98
98
|
- lib/sportdb/readers/conf_linter.rb
|
|
99
|
-
- lib/sportdb/readers/conf_parser_auto.rb
|
|
100
99
|
- lib/sportdb/readers/conf_reader.rb
|
|
101
100
|
- lib/sportdb/readers/league_outline_reader.rb
|
|
102
101
|
- lib/sportdb/readers/match_linter.rb
|
|
103
|
-
- lib/sportdb/readers/match_parser.rb
|
|
104
102
|
- lib/sportdb/readers/match_reader.rb
|
|
105
103
|
- lib/sportdb/readers/package.rb
|
|
106
104
|
- lib/sportdb/readers/version.rb
|
|
107
105
|
- test/helper.rb
|
|
108
|
-
- test/test_conf_parser_auto.rb
|
|
109
|
-
- test/test_match_parser.rb
|
|
110
106
|
- test/test_read.rb
|
|
111
107
|
- test/test_reader.rb
|
|
112
108
|
homepage: https://github.com/sportdb/sport.db
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
module SportDb
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class AutoConfParser
|
|
7
|
-
|
|
8
|
-
def self.parse( lines, start: )
|
|
9
|
-
## todo/fix: add support for txt and lines
|
|
10
|
-
## check if lines_or_txt is an array or just a string
|
|
11
|
-
parser = new( lines, start )
|
|
12
|
-
parser.parse
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
include LogUtils::Logging
|
|
17
|
-
|
|
18
|
-
def initialize( lines, start )
|
|
19
|
-
@lines = lines ## todo/check: change to text instead of array of lines - why? why not?
|
|
20
|
-
@start = start
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def parse
|
|
24
|
-
## try to find all clubs in match schedule
|
|
25
|
-
@last_round = nil
|
|
26
|
-
@rounds = {} ## track usage counter and match (two clubs) counter
|
|
27
|
-
@clubs = Hash.new(0) ## keep track of usage counter
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
@lines.each do |line|
|
|
31
|
-
if is_round?( line )
|
|
32
|
-
logger.info "skipping matched round line: >#{line}<"
|
|
33
|
-
|
|
34
|
-
round = @rounds[ line ] ||= {count: 0, match_count: 0} ## usage counter, match counter
|
|
35
|
-
round[:count] +=1
|
|
36
|
-
@last_round = round
|
|
37
|
-
elsif try_parse_game( line )
|
|
38
|
-
# do nothing here
|
|
39
|
-
else
|
|
40
|
-
logger.warn "skipping line (no match found): >#{line}<"
|
|
41
|
-
end
|
|
42
|
-
end # lines.each
|
|
43
|
-
|
|
44
|
-
[@clubs, @rounds]
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def is_round?( line )
|
|
48
|
-
## note: =~ return nil if not match found, and 0,1, etc for match
|
|
49
|
-
(line =~ SportDb.lang.regex_round) != nil
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def try_parse_game( line )
|
|
53
|
-
# note: clone line; for possible test do NOT modify in place for now
|
|
54
|
-
# note: returns true if parsed, false if no match
|
|
55
|
-
parse_game( line.dup )
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def parse_game( line )
|
|
59
|
-
logger.debug "parsing game (fixture) line: >#{line}<"
|
|
60
|
-
|
|
61
|
-
## remove all protected text runs e.g. []
|
|
62
|
-
## fix: add [ to end-of-line too
|
|
63
|
-
## todo/fix: move remove protected text runs AFTER find date!! - why? why not?
|
|
64
|
-
|
|
65
|
-
line = line.gsub( /\[
|
|
66
|
-
[^\]]+?
|
|
67
|
-
\]/x, '' ).strip
|
|
68
|
-
return true if line.empty? ## note: return true (for valid line with no match/clubs)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
## split by geo (@) - remove for now
|
|
72
|
-
values = line.split( '@' )
|
|
73
|
-
line = values[0]
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
## try find date
|
|
77
|
-
date = find_date!( line, start: @start )
|
|
78
|
-
if date ## if found remove tagged run too; note using singular sub (NOT global gsub)
|
|
79
|
-
line = line.sub( /\[
|
|
80
|
-
[^\]]+?
|
|
81
|
-
\]/x, '' ).strip
|
|
82
|
-
|
|
83
|
-
else
|
|
84
|
-
## check for leading hours only e.g. 20.30 or 20:30 or 20h30 or 20H30 or 09h00
|
|
85
|
-
## todo/fix: make language dependent (or move to find_date/hour etc.) - why? why not?
|
|
86
|
-
line = line.sub( %r{^ ## MUST be anchored to beginning of line
|
|
87
|
-
[012]?[0-9]
|
|
88
|
-
[.:hH]
|
|
89
|
-
[0-9][0-9]
|
|
90
|
-
(?=[ ]) ## must be followed by space for now (add end of line too - why? why not?)
|
|
91
|
-
}x, '' ).strip
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
return true if line.empty? ## note: return true (for valid line with no match/clubs)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
scores = find_scores!( line )
|
|
98
|
-
|
|
99
|
-
logger.debug " line: >#{line}<"
|
|
100
|
-
|
|
101
|
-
line = line.sub( /\[
|
|
102
|
-
[^\]]+?
|
|
103
|
-
\]/x, '$$' ) # note: replace first score tag with $$
|
|
104
|
-
line = line.gsub( /\[
|
|
105
|
-
[^\]]+?
|
|
106
|
-
\]/x, '' ) # note: replace/remove all other score tags with nothing
|
|
107
|
-
|
|
108
|
-
## clean-up remove all text run inside () or empty () too
|
|
109
|
-
line = line.gsub( /\(
|
|
110
|
-
[^)]*?
|
|
111
|
-
\)/x, '' )
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
## check for more match separators e.g. - or vs for now
|
|
115
|
-
line = line.sub( / \s+
|
|
116
|
-
( -
|
|
117
|
-
| v
|
|
118
|
-
| vs\.? # note: allow optional dot eg. vs.
|
|
119
|
-
)
|
|
120
|
-
\s+
|
|
121
|
-
/ix, '$$' )
|
|
122
|
-
|
|
123
|
-
values = line.split( '$$' )
|
|
124
|
-
values = values.map { |value| value.strip } ## strip spaces
|
|
125
|
-
values = values.select { |value| !value.empty? } ## remove empty strings
|
|
126
|
-
|
|
127
|
-
return true if values.size == 0 ## note: return true (for valid line with no match/clubs)
|
|
128
|
-
|
|
129
|
-
if values.size == 1
|
|
130
|
-
puts "(auto config) try matching clubs separated by spaces (2+):"
|
|
131
|
-
pp values
|
|
132
|
-
|
|
133
|
-
values = values[0].split( /[ ]{2,}/ )
|
|
134
|
-
pp values
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
return false if values.size != 2
|
|
138
|
-
|
|
139
|
-
puts "(auto config) try matching clubs:"
|
|
140
|
-
pp values
|
|
141
|
-
|
|
142
|
-
@clubs[ values[0] ] += 1 ## update usage counters
|
|
143
|
-
@clubs[ values[1] ] += 1
|
|
144
|
-
|
|
145
|
-
@last_round[ :match_count ] += 1
|
|
146
|
-
|
|
147
|
-
true
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
def find_scores!( line, opts={} )
|
|
153
|
-
# note: always call after find_dates !!!
|
|
154
|
-
# scores match date-like patterns!! e.g. 10-11 or 10:00 etc.
|
|
155
|
-
# -- note: score might have two digits too
|
|
156
|
-
|
|
157
|
-
finder = ScoresFinder.new
|
|
158
|
-
finder.find!( line, opts )
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
def find_date!( line, start: )
|
|
162
|
-
## NB: lets us pass in start_at/end_at date (for event)
|
|
163
|
-
# for auto-complete year
|
|
164
|
-
|
|
165
|
-
# extract date from line
|
|
166
|
-
# and return it
|
|
167
|
-
# NB: side effect - removes date from line string
|
|
168
|
-
DateFormats.find!( line, start: start )
|
|
169
|
-
end
|
|
170
|
-
end # class AutoConfParser
|
|
171
|
-
end # module SportDb
|
|
@@ -1,476 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
module SportDb
|
|
4
|
-
|
|
5
|
-
class MatchParserSimpleV2 ## simple match parser for club match schedules
|
|
6
|
-
|
|
7
|
-
def self.parse( lines, teams, start: )
|
|
8
|
-
## todo/fix: add support for txt and lines
|
|
9
|
-
## check if lines_or_txt is an array or just a string
|
|
10
|
-
## use teams: like start: why? why not?
|
|
11
|
-
parser = new( lines, teams, start )
|
|
12
|
-
parser.parse
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
include LogUtils::Logging
|
|
17
|
-
|
|
18
|
-
def initialize( lines, teams, start )
|
|
19
|
-
@lines = lines ## todo/check: change to text instead of array of lines - why? why not?
|
|
20
|
-
@mapper_teams = TeamMapper.new( teams )
|
|
21
|
-
@start = start
|
|
22
|
-
|
|
23
|
-
## build lookup hash by (team) key
|
|
24
|
-
@teams = teams.reduce({}) { |h,team| h[team.key]=team; h }
|
|
25
|
-
|
|
26
|
-
## debug_dump_teams( teams )
|
|
27
|
-
## exit 1
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def debug_dump_teams( teams )
|
|
31
|
-
puts "== #{teams.size} teams"
|
|
32
|
-
teams.each do |team|
|
|
33
|
-
print "#{team.key}, "
|
|
34
|
-
print "#{team.title}, "
|
|
35
|
-
print "#{team.synonyms.split('|').join(', ')}"
|
|
36
|
-
puts
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
Round = Struct.new( :pos, :title )
|
|
43
|
-
##
|
|
44
|
-
## todo: change db schema
|
|
45
|
-
## make start and end date optional
|
|
46
|
-
## change pos to num - why? why not?
|
|
47
|
-
## make pos/num optional too
|
|
48
|
-
##
|
|
49
|
-
## sort round by scheduled/planed start date
|
|
50
|
-
Match = Struct.new( :date,
|
|
51
|
-
:team1, :team2, ## todo/fix: use team1_name, team2_name or similar - for compat with db activerecord version? why? why not?
|
|
52
|
-
:score1i, :score2i, ## half time (first (i) part)
|
|
53
|
-
:score1, :score2, ## full time
|
|
54
|
-
:round )
|
|
55
|
-
|
|
56
|
-
def parse
|
|
57
|
-
@last_date = nil
|
|
58
|
-
@last_round = nil
|
|
59
|
-
@rounds = {}
|
|
60
|
-
@matches = []
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
@lines.each do |line|
|
|
64
|
-
if is_round?( line )
|
|
65
|
-
parse_round_header( line )
|
|
66
|
-
elsif try_parse_game( line )
|
|
67
|
-
# do nothing here
|
|
68
|
-
elsif try_parse_date_header( line )
|
|
69
|
-
# do nothing here
|
|
70
|
-
else
|
|
71
|
-
logger.info "skipping line (no match found): >#{line}<"
|
|
72
|
-
end
|
|
73
|
-
end # lines.each
|
|
74
|
-
|
|
75
|
-
## todo/fix: reverse - pass matches as first para
|
|
76
|
-
[@rounds.values, @matches]
|
|
77
|
-
end # method parse
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def is_round?( line )
|
|
81
|
-
## note: =~ return nil if not match found, and 0,1, etc for match
|
|
82
|
-
(line =~ SportDb.lang.regex_round) != nil
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
def find_round_pos!( line )
|
|
87
|
-
# pass #1) extract optional round pos from line
|
|
88
|
-
# e.g. (1) - must start line
|
|
89
|
-
regex_pos = /^[ \t]*\((\d{1,3})\)[ \t]+/
|
|
90
|
-
|
|
91
|
-
# pass #2) find free standing number e.g. Matchday 3 or Round 5 or 3. Spieltag etc.
|
|
92
|
-
# note: /\b(\d{1,3})\b/
|
|
93
|
-
# will match -12
|
|
94
|
-
# thus, use space required - will NOT match -2 e.g. Group-2 Play-off
|
|
95
|
-
# note: allow 1. Runde n
|
|
96
|
-
# 1^ Giornata
|
|
97
|
-
regex_num = /(?:^|\s)(\d{1,3})(?:[.\^\s]|$)/
|
|
98
|
-
|
|
99
|
-
if line =~ regex_pos
|
|
100
|
-
logger.debug " pos: >#{$1}<"
|
|
101
|
-
|
|
102
|
-
line.sub!( regex_pos, '[ROUND.POS] ' ) ## NB: add back trailing space that got swallowed w/ regex -> [ \t]+
|
|
103
|
-
return $1.to_i
|
|
104
|
-
elsif line =~ regex_num
|
|
105
|
-
## assume number in title is pos (e.g. Jornada 3, 3 Runde etc.)
|
|
106
|
-
## NB: do NOT remove pos from string (will get removed by round title)
|
|
107
|
-
|
|
108
|
-
num = $1.to_i # note: clone capture; keep a copy (another regex follows; will redefine $1)
|
|
109
|
-
|
|
110
|
-
#### fix:
|
|
111
|
-
# use/make keywords required
|
|
112
|
-
# e.g. Round of 16 -> should NOT match 16!
|
|
113
|
-
# Spiel um Platz 3 (or 5) etc -> should NOT match 3!
|
|
114
|
-
# Round 16 - ok
|
|
115
|
-
# thus, check for required keywords
|
|
116
|
-
|
|
117
|
-
## quick hack for round of 16
|
|
118
|
-
# todo: mask match e.g. Round of xxx ... and try again - might include something
|
|
119
|
-
# reuse pattern for Group XX Replays for example
|
|
120
|
-
if line =~ /^\s*Round of \d{1,3}\b/
|
|
121
|
-
return nil
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
logger.debug " pos: >#{num}<"
|
|
125
|
-
return num
|
|
126
|
-
else
|
|
127
|
-
## fix: add logger.warn no round pos found in line
|
|
128
|
-
return nil
|
|
129
|
-
end
|
|
130
|
-
end # method find_round_pos!
|
|
131
|
-
|
|
132
|
-
def find_round_header_title!( line )
|
|
133
|
-
# assume everything left is the round title
|
|
134
|
-
# extract all other items first (round title2, round pos, group title n pos, etc.)
|
|
135
|
-
|
|
136
|
-
## todo/fix:
|
|
137
|
-
## cleanup method
|
|
138
|
-
## use buf.index( '//' ) to split string (see found_round_def)
|
|
139
|
-
## why? simpler why not?
|
|
140
|
-
## - do we currently allow groups if title2 present? add example if it works?
|
|
141
|
-
|
|
142
|
-
buf = line.dup
|
|
143
|
-
logger.debug " find_round_header_title! line-before: >>#{buf}<<"
|
|
144
|
-
|
|
145
|
-
buf.gsub!( /\[[^\]]+\]/, '' ) # e.g. remove [ROUND.POS], [ROUND.TITLE2], [GROUP.TITLE+POS] etc.
|
|
146
|
-
buf.strip! # remove leading and trailing whitespace
|
|
147
|
-
|
|
148
|
-
logger.debug " find_round_title! line-after: >>#{buf}<<"
|
|
149
|
-
|
|
150
|
-
### bingo - assume what's left is the round title
|
|
151
|
-
|
|
152
|
-
logger.debug " title: >>#{buf}<<"
|
|
153
|
-
line.sub!( buf, '[ROUND.TITLE]' )
|
|
154
|
-
|
|
155
|
-
buf
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
def parse_round_header( line )
|
|
159
|
-
logger.debug "parsing round header line: >#{line}<"
|
|
160
|
-
|
|
161
|
-
## todo/check/fix:
|
|
162
|
-
# make sure Round of 16 will not return pos 16 -- how? possible?
|
|
163
|
-
# add unit test too to verify
|
|
164
|
-
pos = find_round_pos!( line )
|
|
165
|
-
|
|
166
|
-
title = find_round_header_title!( line )
|
|
167
|
-
|
|
168
|
-
logger.debug " line: >#{line}<"
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
round = @rounds[ title ]
|
|
172
|
-
if round.nil?
|
|
173
|
-
round = Round.new( pos, title )
|
|
174
|
-
@rounds[ title ] = round
|
|
175
|
-
end
|
|
176
|
-
## todo/check: if pos match (MUST always match for now)
|
|
177
|
-
@last_round = round
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
## NB: dummy/placeholder start_at, end_at date
|
|
181
|
-
## replace/patch after adding all games for round
|
|
182
|
-
|
|
183
|
-
=begin
|
|
184
|
-
round_attribs = {
|
|
185
|
-
title: title,
|
|
186
|
-
title2: title2,
|
|
187
|
-
knockout: knockout_flag
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
if pos > 999000
|
|
191
|
-
# no pos (e.g. will get autonumbered later) - try match by title for now
|
|
192
|
-
# e.g. lets us use title 'Group Replays', for example, multiple times
|
|
193
|
-
@round = Round.find_by_event_id_and_title( @event.id, title )
|
|
194
|
-
else
|
|
195
|
-
@round = Round.find_by_event_id_and_pos( @event.id, pos )
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
if @round.present?
|
|
199
|
-
logger.debug "update round #{@round.id}:"
|
|
200
|
-
else
|
|
201
|
-
logger.debug "create round:"
|
|
202
|
-
@round = Round.new
|
|
203
|
-
|
|
204
|
-
round_attribs = round_attribs.merge( {
|
|
205
|
-
event_id: @event.id,
|
|
206
|
-
pos: pos,
|
|
207
|
-
start_at: Date.parse('1911-11-11'),
|
|
208
|
-
end_at: Date.parse('1911-11-11')
|
|
209
|
-
})
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
logger.debug round_attribs.to_json
|
|
213
|
-
|
|
214
|
-
@round.update_attributes!( round_attribs )
|
|
215
|
-
|
|
216
|
-
@patch_round_ids_pos << @round.id if pos > 999000
|
|
217
|
-
### store list of round ids for patching start_at/end_at at the end
|
|
218
|
-
@patch_round_ids_dates << @round.id # todo/fix/check: check if round has definition (do NOT patch if definition (not auto-added) present)
|
|
219
|
-
=end
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
def find_scores!( line, opts={} )
|
|
224
|
-
# note: always call after find_dates !!!
|
|
225
|
-
# scores match date-like patterns!! e.g. 10-11 or 10:00 etc.
|
|
226
|
-
# -- note: score might have two digits too
|
|
227
|
-
|
|
228
|
-
finder = ScoresFinder.new
|
|
229
|
-
finder.find!( line, opts )
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
def try_parse_game( line )
|
|
233
|
-
# note: clone line; for possible test do NOT modify in place for now
|
|
234
|
-
# note: returns true if parsed, false if no match
|
|
235
|
-
parse_game( line.dup )
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
def parse_game( line )
|
|
240
|
-
logger.debug "parsing game (fixture) line: >#{line}<"
|
|
241
|
-
|
|
242
|
-
@mapper_teams.map_teams!( line ) ### todo/fix: limit mapping to two(2) teams - why? why not? might avoid matching @ Barcelona ??
|
|
243
|
-
team_keys = @mapper_teams.find_teams!( line )
|
|
244
|
-
team1_key = team_keys[0]
|
|
245
|
-
team2_key = team_keys[1]
|
|
246
|
-
|
|
247
|
-
## note: if we do NOT find two teams; return false - no match found
|
|
248
|
-
if team1_key.nil? || team2_key.nil?
|
|
249
|
-
logger.debug " no game match (two teams required) found for line: >#{line}<"
|
|
250
|
-
return false
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
## pos = find_game_pos!( line )
|
|
254
|
-
|
|
255
|
-
date = find_date!( line, start: @start )
|
|
256
|
-
|
|
257
|
-
###
|
|
258
|
-
# check if date found?
|
|
259
|
-
# NB: ruby falsey is nil & false only (not 0 or empty array etc.)
|
|
260
|
-
if date
|
|
261
|
-
### check: use date_v2 if present? why? why not?
|
|
262
|
-
@last_date = date # keep a reference for later use
|
|
263
|
-
else
|
|
264
|
-
date = @last_date # no date found; (re)use last seen date
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
scores = find_scores!( line )
|
|
269
|
-
|
|
270
|
-
logger.debug " line: >#{line}<"
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
## todo/check: scores are integers or strings?
|
|
274
|
-
@matches << Match.new( date,
|
|
275
|
-
@teams[ team1_key ],
|
|
276
|
-
@teams[ team2_key ],
|
|
277
|
-
scores[0], ## score1i - half time (first (i) part)
|
|
278
|
-
scores[1], ## score2i
|
|
279
|
-
scores[2], ## score1 - full time
|
|
280
|
-
scores[3], ## score2
|
|
281
|
-
@last_round )
|
|
282
|
-
|
|
283
|
-
### todo: cache team lookups in hash?
|
|
284
|
-
|
|
285
|
-
=begin
|
|
286
|
-
team1 = Team.find_by_key!( team1_key )
|
|
287
|
-
team2 = Team.find_by_key!( team2_key )
|
|
288
|
-
|
|
289
|
-
@last_team1 = team1 # store for later use for goals etc.
|
|
290
|
-
@last_team2 = team2
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
if @round.nil?
|
|
294
|
-
## no round header found; calculate round from date
|
|
295
|
-
|
|
296
|
-
###
|
|
297
|
-
## todo/fix: add some unit tests for round look up
|
|
298
|
-
# fix: use date_v2 if present!! (old/original date; otherwise use date)
|
|
299
|
-
|
|
300
|
-
#
|
|
301
|
-
# fix: check - what to do with hours e.g. start_at use 00:00 and for end_at use 23.59 ??
|
|
302
|
-
# -- for now - remove hours (e.g. use end_of_day and beginnig_of_day)
|
|
303
|
-
|
|
304
|
-
##
|
|
305
|
-
# note: start_at and end_at are dates ONLY (note datetime)
|
|
306
|
-
# - do NOT pass in hours etc. in query
|
|
307
|
-
# again use --> date.end_of_day, date.beginning_of_day
|
|
308
|
-
# new: not working: date.to_date, date.to_date
|
|
309
|
-
# will not find round if start_at same as date !! (in theory hours do not matter)
|
|
310
|
-
|
|
311
|
-
###
|
|
312
|
-
# hack:
|
|
313
|
-
# special case for sqlite3 (date compare not working reliable; use casts)
|
|
314
|
-
# fix: move to adapter_name to activerecord_utils as sqlite? or similar?
|
|
315
|
-
|
|
316
|
-
if ActiveRecord::Base.connection.adapter_name.downcase.starts_with?( 'sqlite' )
|
|
317
|
-
logger.debug( " [sqlite] using sqlite-specific query for date compare for rounds finder" )
|
|
318
|
-
round = Round.where( 'event_id = ? AND ( julianday(start_at) <= julianday(?)'+
|
|
319
|
-
'AND julianday(end_at) >= julianday(?))',
|
|
320
|
-
@event.id, date.to_date, date.to_date).first
|
|
321
|
-
else # all other dbs (postgresql, mysql, etc.)
|
|
322
|
-
round = Round.where( 'event_id = ? AND (start_at <= ? AND end_at >= ?)',
|
|
323
|
-
@event.id, date.to_date, date.to_date).first
|
|
324
|
-
end
|
|
325
|
-
|
|
326
|
-
pp round
|
|
327
|
-
if round.nil?
|
|
328
|
-
logger.warn( " !!!! no round match found for date #{date}" )
|
|
329
|
-
pp Round.all
|
|
330
|
-
|
|
331
|
-
###################################
|
|
332
|
-
# -- try auto-adding matchday
|
|
333
|
-
round = Round.new
|
|
334
|
-
|
|
335
|
-
round_attribs = {
|
|
336
|
-
event_id: @event.id,
|
|
337
|
-
title: "Matchday #{date.to_date}",
|
|
338
|
-
pos: 999001+@patch_round_ids_pos.length, # e.g. 999<count> - 999001,999002,etc.
|
|
339
|
-
start_at: date.to_date,
|
|
340
|
-
end_at: date.to_date
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
logger.info( " auto-add round >Matchday #{date.to_date}<" )
|
|
344
|
-
logger.debug round_attribs.to_json
|
|
345
|
-
|
|
346
|
-
round.update_attributes!( round_attribs )
|
|
347
|
-
|
|
348
|
-
@patch_round_ids_pos << round.id # todo/check - add just id or "full" record as now - why? why not?
|
|
349
|
-
end
|
|
350
|
-
|
|
351
|
-
# store pos for auto-number next round if missing
|
|
352
|
-
# - note: only if greater/bigger than last; use max
|
|
353
|
-
# - note: last_round_pos might be nil - thus set to 0
|
|
354
|
-
if round.pos > 999000
|
|
355
|
-
# note: do NOT update last_round_pos for to-be-patched rounds
|
|
356
|
-
else
|
|
357
|
-
@last_round_pos = [round.pos,@last_round_pos||0].max
|
|
358
|
-
end
|
|
359
|
-
|
|
360
|
-
## note: will crash (round.pos) if round is nil
|
|
361
|
-
logger.debug( " using round #{round.pos} >#{round.title}< start_at: #{round.start_at}, end_at: #{round.end_at}" )
|
|
362
|
-
else
|
|
363
|
-
## use round from last round header
|
|
364
|
-
round = @round
|
|
365
|
-
end
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
### check if games exists
|
|
369
|
-
## with this teams in this round if yes only update
|
|
370
|
-
game = Game.find_by_round_id_and_team1_id_and_team2_id(
|
|
371
|
-
round.id, team1.id, team2.id
|
|
372
|
-
)
|
|
373
|
-
|
|
374
|
-
game_attribs = {
|
|
375
|
-
score1i: scores[0],
|
|
376
|
-
score2i: scores[1],
|
|
377
|
-
score1: scores[2],
|
|
378
|
-
score2: scores[3],
|
|
379
|
-
score1et: scores[4],
|
|
380
|
-
score2et: scores[5],
|
|
381
|
-
score1p: scores[6],
|
|
382
|
-
score2p: scores[7],
|
|
383
|
-
play_at: date,
|
|
384
|
-
play_at_v2: date_v2,
|
|
385
|
-
postponed: postponed,
|
|
386
|
-
knockout: round.knockout, ## note: for now always use knockout flag from round - why? why not??
|
|
387
|
-
ground_id: ground.present? ? ground.id : nil,
|
|
388
|
-
group_id: @group.present? ? @group.id : nil
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
game_attribs[ :pos ] = pos if pos.present?
|
|
392
|
-
|
|
393
|
-
####
|
|
394
|
-
# note: only update if any changes (or create if new record)
|
|
395
|
-
if game.present? &&
|
|
396
|
-
game.check_for_changes( game_attribs ) == false
|
|
397
|
-
logger.debug " skip update game #{game.id}; no changes found"
|
|
398
|
-
else
|
|
399
|
-
if game.present?
|
|
400
|
-
logger.debug "update game #{game.id}:"
|
|
401
|
-
else
|
|
402
|
-
logger.debug "create game:"
|
|
403
|
-
game = Game.new
|
|
404
|
-
|
|
405
|
-
more_game_attribs = {
|
|
406
|
-
round_id: round.id,
|
|
407
|
-
team1_id: team1.id,
|
|
408
|
-
team2_id: team2.id
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
## NB: use round.games.count for pos
|
|
412
|
-
## lets us add games out of order if later needed
|
|
413
|
-
more_game_attribs[ :pos ] = round.games.count+1 if pos.nil?
|
|
414
|
-
|
|
415
|
-
game_attribs = game_attribs.merge( more_game_attribs )
|
|
416
|
-
end
|
|
417
|
-
|
|
418
|
-
logger.debug game_attribs.to_json
|
|
419
|
-
game.update_attributes!( game_attribs )
|
|
420
|
-
end
|
|
421
|
-
|
|
422
|
-
@last_game = game # store for later reference (e.g. used for goals etc.)
|
|
423
|
-
=end
|
|
424
|
-
|
|
425
|
-
return true # game match found
|
|
426
|
-
end # method parse_game
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
def try_parse_date_header( line )
|
|
431
|
-
# note: clone line; for possible test do NOT modify in place for now
|
|
432
|
-
# note: returns true if parsed, false if no match
|
|
433
|
-
parse_date_header( line.dup )
|
|
434
|
-
end
|
|
435
|
-
|
|
436
|
-
def find_date!( line, start: )
|
|
437
|
-
## NB: lets us pass in start_at/end_at date (for event)
|
|
438
|
-
# for auto-complete year
|
|
439
|
-
|
|
440
|
-
# extract date from line
|
|
441
|
-
# and return it
|
|
442
|
-
# NB: side effect - removes date from line string
|
|
443
|
-
DateFormats.find!( line, start: start )
|
|
444
|
-
end
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
def parse_date_header( line )
|
|
448
|
-
# note: returns true if parsed, false if no match
|
|
449
|
-
|
|
450
|
-
# line with NO teams plus include date e.g.
|
|
451
|
-
# [Fri Jun/17] or
|
|
452
|
-
# Jun/17 or
|
|
453
|
-
# Jun/17: etc.
|
|
454
|
-
|
|
455
|
-
@mapper_teams.map_teams!( line )
|
|
456
|
-
team_keys = @mapper_teams.find_teams!( line )
|
|
457
|
-
team1_key = team_keys[0]
|
|
458
|
-
team2_key = team_keys[1]
|
|
459
|
-
|
|
460
|
-
date = find_date!( line, start: @start )
|
|
461
|
-
|
|
462
|
-
if date && team1_key.nil? && team2_key.nil?
|
|
463
|
-
logger.debug( "date header line found: >#{line}<")
|
|
464
|
-
logger.debug( " date: #{date}")
|
|
465
|
-
|
|
466
|
-
@last_date = date # keep a reference for later use
|
|
467
|
-
return true
|
|
468
|
-
else
|
|
469
|
-
return false
|
|
470
|
-
end
|
|
471
|
-
end
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
end # class MatchParserSimpleV2
|
|
476
|
-
end # module SportDb
|
|
@@ -1,489 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
###
|
|
4
|
-
# to run use
|
|
5
|
-
# ruby -I ./lib -I ./test test/test_conf_parser_auto.rb
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
require 'helper'
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class TestAutoConfParser < MiniTest::Test
|
|
12
|
-
|
|
13
|
-
def test_mx
|
|
14
|
-
txt= <<TXT
|
|
15
|
-
Jornada 1 // 3, 4 y 5 de enero
|
|
16
|
-
|
|
17
|
-
Vie 3 Ene Monarcas Morelia vs. Querétaro @ Estadio Morelos
|
|
18
|
-
Vie 3 Ene Santos Laguna vs. Guadalajara @ Estadio Corona TSM
|
|
19
|
-
Sáb 4 Ene América vs. Tigres UANL @ Estadio Azteca
|
|
20
|
-
Sáb 4 Ene Monterrey vs. Cruz Azul @ Estadio Tecnológico
|
|
21
|
-
Sáb 4 Ene Pachuca vs. Toluca @ Estadio Hidalgo
|
|
22
|
-
Sáb 4 Ene Jaguares de Chiapas vs. Veracruz @ Estadio Víctor M. Reyna
|
|
23
|
-
Sáb 4 Ene Atlas vs. Tijuana @ Estadio Jalisco
|
|
24
|
-
Dom 5 Ene Universidad Nacional vs. Puebla @ Estadio Olímpico Universitario
|
|
25
|
-
Dom 5 Ene Atlante vs. León @ Estadio Andrés Quintana Roo
|
|
26
|
-
|
|
27
|
-
Jornada 2 // 10, 11 y 12 de enero
|
|
28
|
-
|
|
29
|
-
Vie 10 Ene Querétaro vs. Universidad Nacional @ Estadio La Corregidora
|
|
30
|
-
Vie 10 Ene Tijuana vs. América @ Estadio Caliente
|
|
31
|
-
Sáb 11 Ene Veracruz vs. Atlante @ Estadio Luis Pirata Fuente
|
|
32
|
-
Sáb 11 Ene Cruz Azul vs. Santos Laguna @ Estadio Azul
|
|
33
|
-
Sáb 11 Ene Tigres UANL vs. Pachuca @ Estadio Universitario
|
|
34
|
-
Sáb 11 Ene León vs. Atlas @ Estadio Nou Camp
|
|
35
|
-
Dom 12 Ene Puebla vs. Monterrey @ Estadio Cuauhtémoc
|
|
36
|
-
Dom 12 Ene Toluca vs. Monarcas Morelia @ Estadio Nemesio Díez
|
|
37
|
-
Dom 12 Ene Guadalajara vs. Jaguares de Chiapas @ Estadio Omnilife
|
|
38
|
-
TXT
|
|
39
|
-
clubs, rounds = parse( txt, lang: 'es' )
|
|
40
|
-
|
|
41
|
-
assert_equal Hash(
|
|
42
|
-
'Monarcas Morelia'=>2,
|
|
43
|
-
'Querétaro'=>2,
|
|
44
|
-
'Santos Laguna'=>2,
|
|
45
|
-
'Guadalajara'=>2,
|
|
46
|
-
'América'=>2,
|
|
47
|
-
'Tigres UANL'=>2,
|
|
48
|
-
'Monterrey'=>2,
|
|
49
|
-
'Cruz Azul'=>2,
|
|
50
|
-
'Pachuca'=>2,
|
|
51
|
-
'Toluca'=>2,
|
|
52
|
-
'Jaguares de Chiapas'=>2,
|
|
53
|
-
'Veracruz'=>2,
|
|
54
|
-
'Atlas'=>2,
|
|
55
|
-
'Tijuana'=>2,
|
|
56
|
-
'Universidad Nacional'=>2,
|
|
57
|
-
'Puebla'=>2,
|
|
58
|
-
'Atlante'=>2,
|
|
59
|
-
'León'=>2 ), clubs
|
|
60
|
-
|
|
61
|
-
assert_equal Hash(
|
|
62
|
-
'Jornada 1 // 3, 4 y 5 de enero' => { count: 1, match_count: 9},
|
|
63
|
-
'Jornada 2 // 10, 11 y 12 de enero' => { count: 1, match_count: 9} ), rounds
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def test_br
|
|
67
|
-
txt= <<TXT
|
|
68
|
-
1ª Rodada
|
|
69
|
-
29/03/2003 - Sábado
|
|
70
|
-
16h00 Guarani 4x2 Vasco @ Brinco de Ouro
|
|
71
|
-
Atlético-PR 2x0 Grêmio @ Arena da Baixada
|
|
72
|
-
|
|
73
|
-
30/03/2003 - Domingo
|
|
74
|
-
09h00 Flamengo 1x1 Coritiba @ Maracanã
|
|
75
|
-
16h00 Goiás 2x2 Paysandu @ Serra Dourada
|
|
76
|
-
Internacional 1x1 Ponte Preta @ Beira Rio
|
|
77
|
-
Criciúma 2x0 Fluminense @ Heriberto Hulse
|
|
78
|
-
Juventude 2x2 São Paulo @ Alfredo Jaconi
|
|
79
|
-
Fortaleza 0x0 Bahia @ Castelão
|
|
80
|
-
Cruzeiro 2x2 São Caetano @ Mineirão
|
|
81
|
-
Vitória 1x1 Figueirense @ Barradão
|
|
82
|
-
18h00 Santos 2x2 Paraná @ Vila Belmiro
|
|
83
|
-
Corinthians 0x3 Atlético-MG @ Pacaembu
|
|
84
|
-
|
|
85
|
-
2ª Rodada
|
|
86
|
-
05/04/2003 - Sábado
|
|
87
|
-
16h00 Fluminense 1x1 Fortaleza @ Maracanã
|
|
88
|
-
Atlético-MG 0x0 Santos @ Mineirão
|
|
89
|
-
Coritiba 0x1 Internacional @ Couto Pereira
|
|
90
|
-
18h00 Grêmio 3x1 Guarani @ Olímpico
|
|
91
|
-
|
|
92
|
-
06/04/2003 - Domingo
|
|
93
|
-
16h00 Bahia 1x2 Flamengo @ Fonte Nova
|
|
94
|
-
Figueirense 3x3 Corinthians @ Orlando Scarpelli
|
|
95
|
-
Paysandu 1x2 Vitória @ Mangueirão
|
|
96
|
-
Ponte Preta 1x0 Juventude @ Moisés Lucarelli
|
|
97
|
-
Paraná 3x0 Atlético-PR @ Pinheirão
|
|
98
|
-
São Caetano 3x2 Criciúma @ Anacleto Campanella
|
|
99
|
-
18h00 São Paulo 2x4 Cruzeiro @ Morumbi
|
|
100
|
-
Vasco 6x4 Goiás @ São Januário
|
|
101
|
-
TXT
|
|
102
|
-
clubs, rounds = parse( txt, lang: 'pt' )
|
|
103
|
-
|
|
104
|
-
assert_equal Hash(
|
|
105
|
-
'Guarani'=>2,
|
|
106
|
-
'Vasco'=>2,
|
|
107
|
-
'Atlético-PR'=>2,
|
|
108
|
-
'Grêmio'=>2,
|
|
109
|
-
'Flamengo'=>2,
|
|
110
|
-
'Coritiba'=>2,
|
|
111
|
-
'Goiás'=>2,
|
|
112
|
-
'Paysandu'=>2,
|
|
113
|
-
'Internacional'=>2,
|
|
114
|
-
'Ponte Preta'=>2,
|
|
115
|
-
'Criciúma'=>2,
|
|
116
|
-
'Fluminense'=>2,
|
|
117
|
-
'Juventude'=>2,
|
|
118
|
-
'São Paulo'=>2,
|
|
119
|
-
'Fortaleza'=>2,
|
|
120
|
-
'Bahia'=>2,
|
|
121
|
-
'Cruzeiro'=>2,
|
|
122
|
-
'São Caetano'=>2,
|
|
123
|
-
'Vitória'=>2,
|
|
124
|
-
'Figueirense'=>2,
|
|
125
|
-
'Santos'=>2,
|
|
126
|
-
'Paraná'=>2,
|
|
127
|
-
'Corinthians'=>2,
|
|
128
|
-
'Atlético-MG'=>2 ), clubs
|
|
129
|
-
|
|
130
|
-
assert_equal Hash(
|
|
131
|
-
'1ª Rodada' => {count: 1, match_count: 12},
|
|
132
|
-
'2ª Rodada' => {count: 1, match_count: 12} ), rounds
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
def test_at
|
|
137
|
-
txt = <<TXT
|
|
138
|
-
29. Runde
|
|
139
|
-
|
|
140
|
-
Sa 7.4.
|
|
141
|
-
16.00 RB Salzburg 2:0 Wacker Innsbruck
|
|
142
|
-
18.30 SV Ried 0:1 Austria Wien
|
|
143
|
-
Kapfenberger SV 2:3 Admira Wacker
|
|
144
|
-
Rapid Wien 2:1 Wr. Neustadt
|
|
145
|
-
So 8.4.
|
|
146
|
-
16.00 SV Mattersburg 0:2 Sturm Graz
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
30. Runde
|
|
150
|
-
|
|
151
|
-
Sa 14.4.
|
|
152
|
-
16.00 Wr. Neustadt 0:0 Kapfenberger SV
|
|
153
|
-
18.30 Admira Wacker 1:1 Wacker Innsbruck
|
|
154
|
-
Sturm Graz 2:2 RB Salzburg
|
|
155
|
-
SV Ried 2:0 SV Mattersburg
|
|
156
|
-
So 15.4.
|
|
157
|
-
16.00 Austria Wien 0:0 Rapid Wien
|
|
158
|
-
TXT
|
|
159
|
-
|
|
160
|
-
clubs, rounds = parse( txt, lang: 'de' )
|
|
161
|
-
|
|
162
|
-
assert_equal Hash(
|
|
163
|
-
'RB Salzburg' => 2,
|
|
164
|
-
'Wacker Innsbruck' => 2,
|
|
165
|
-
'SV Ried' => 2,
|
|
166
|
-
'Austria Wien' => 2,
|
|
167
|
-
'Kapfenberger SV' => 2,
|
|
168
|
-
'Admira Wacker' => 2,
|
|
169
|
-
'Rapid Wien' => 2,
|
|
170
|
-
'Wr. Neustadt' => 2,
|
|
171
|
-
'SV Mattersburg' => 2,
|
|
172
|
-
'Sturm Graz' => 2 ), clubs
|
|
173
|
-
|
|
174
|
-
assert_equal Hash(
|
|
175
|
-
'29. Runde' => { count: 1, match_count: 5 },
|
|
176
|
-
'30. Runde' => { count: 1, match_count: 5 } ), rounds
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
def test_es
|
|
180
|
-
txt = <<TXT
|
|
181
|
-
Jornada 1
|
|
182
|
-
|
|
183
|
-
18.08.2012 Barcelona R. Sociedad 5-1
|
|
184
|
-
18.08.2012 Levante Atlético 1-1
|
|
185
|
-
18.08.2012 Athletic Betis 3-5
|
|
186
|
-
18.08.2012 Zaragoza Valladolid 0-1
|
|
187
|
-
18.08.2012 R. Madrid Valencia 1-1
|
|
188
|
-
18.08.2012 Celta Málaga 0-1
|
|
189
|
-
18.08.2012 Sevilla Getafe 2-1
|
|
190
|
-
18.08.2012 Mallorca Espanyol 2-1
|
|
191
|
-
18.08.2012 Rayo Granada 1-0
|
|
192
|
-
18.08.2012 Deportivo Osasuna 2-0
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
Jornada 2
|
|
196
|
-
|
|
197
|
-
25.08.2012 Valladolid Levante 2-0
|
|
198
|
-
25.08.2012 Espanyol Zaragoza 1-2
|
|
199
|
-
25.08.2012 Málaga Mallorca 1-1
|
|
200
|
-
25.08.2012 R. Sociedad Celta 2-1
|
|
201
|
-
25.08.2012 Osasuna Barcelona 1-2
|
|
202
|
-
25.08.2012 Valencia Deportivo 3-3
|
|
203
|
-
25.08.2012 Getafe R. Madrid 2-1
|
|
204
|
-
25.08.2012 Granada Sevilla 1-1
|
|
205
|
-
25.08.2012 Betis Rayo 1-2
|
|
206
|
-
25.08.2012 Atlético Athletic 4-0
|
|
207
|
-
TXT
|
|
208
|
-
|
|
209
|
-
clubs, rounds = parse( txt, lang: 'es' )
|
|
210
|
-
|
|
211
|
-
assert_equal Hash(
|
|
212
|
-
'Barcelona' => 2,
|
|
213
|
-
'R. Sociedad' => 2,
|
|
214
|
-
'Levante' => 2,
|
|
215
|
-
'Atlético' => 2,
|
|
216
|
-
'Athletic' => 2,
|
|
217
|
-
'Betis' => 2,
|
|
218
|
-
'Zaragoza' => 2,
|
|
219
|
-
'Valladolid' => 2,
|
|
220
|
-
'R. Madrid' => 2,
|
|
221
|
-
'Valencia' => 2,
|
|
222
|
-
'Celta' => 2,
|
|
223
|
-
'Málaga' => 2,
|
|
224
|
-
'Sevilla' => 2,
|
|
225
|
-
'Getafe' => 2,
|
|
226
|
-
'Mallorca' => 2,
|
|
227
|
-
'Espanyol' => 2,
|
|
228
|
-
'Rayo' => 2,
|
|
229
|
-
'Granada' => 2,
|
|
230
|
-
'Deportivo' => 2,
|
|
231
|
-
'Osasuna' => 2), clubs
|
|
232
|
-
|
|
233
|
-
assert_equal Hash(
|
|
234
|
-
'Jornada 1' => {count: 1, match_count: 10},
|
|
235
|
-
'Jornada 2' => {count: 1, match_count: 10} ), rounds
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
def test_fr
|
|
240
|
-
txt = <<TXT
|
|
241
|
-
Journée 1
|
|
242
|
-
|
|
243
|
-
Ven 8. Août
|
|
244
|
-
20h30 Stade de Reims 2-2 Paris SG
|
|
245
|
-
Sam 9. Août
|
|
246
|
-
21h00 SC Bastia 3-3 Olympique de Marseille
|
|
247
|
-
Évian TG 0-3 SM Caen
|
|
248
|
-
EA Guingamp 0-2 AS Saint-Étienne
|
|
249
|
-
LOSC Lille 0-0 FC Metz
|
|
250
|
-
Montpellier Hérault SC 0-1 Girondins de Bordeaux
|
|
251
|
-
FC Nantes 1-0 RC Lens
|
|
252
|
-
OGC Nice 3-2 Toulouse FC
|
|
253
|
-
Dim 10. Août
|
|
254
|
-
17h00 Olympique Lyonnais 2-0 Stade Rennais FC
|
|
255
|
-
21h00 AS Monaco FC 1-2 FC Lorient
|
|
256
|
-
|
|
257
|
-
Journée 2
|
|
258
|
-
|
|
259
|
-
Ven 15. Août
|
|
260
|
-
20h30 SM Caen 0-1 LOSC Lille
|
|
261
|
-
Sam 16. Août
|
|
262
|
-
17h00 Paris SG 2-0 SC Bastia
|
|
263
|
-
20h00 RC Lens 0-1 EA Guingamp
|
|
264
|
-
FC Lorient 0-0 OGC Nice
|
|
265
|
-
FC Metz 1-1 FC Nantes
|
|
266
|
-
Stade Rennais FC 6-2 Évian TG
|
|
267
|
-
Toulouse FC 2-1 Olympique Lyonnais
|
|
268
|
-
Dim 17. Août
|
|
269
|
-
17h00 Olympique de Marseille 0-2 Montpellier Hérault SC
|
|
270
|
-
AS Saint-Étienne 3-1 Stade de Reims
|
|
271
|
-
21h00 Girondins de Bordeaux 4-1 AS Monaco FC
|
|
272
|
-
TXT
|
|
273
|
-
|
|
274
|
-
clubs, rounds = parse( txt, lang: 'fr' )
|
|
275
|
-
|
|
276
|
-
assert_equal Hash(
|
|
277
|
-
'Stade de Reims' => 2,
|
|
278
|
-
'Paris SG' => 2,
|
|
279
|
-
'SC Bastia' => 2,
|
|
280
|
-
'Olympique de Marseille' => 2,
|
|
281
|
-
'Évian TG' => 2,
|
|
282
|
-
'SM Caen' => 2,
|
|
283
|
-
'EA Guingamp' => 2,
|
|
284
|
-
'AS Saint-Étienne' => 2,
|
|
285
|
-
'LOSC Lille' => 2,
|
|
286
|
-
'FC Metz' => 2,
|
|
287
|
-
'Montpellier Hérault SC' => 2,
|
|
288
|
-
'Girondins de Bordeaux' => 2,
|
|
289
|
-
'FC Nantes' => 2,
|
|
290
|
-
'RC Lens' => 2,
|
|
291
|
-
'OGC Nice' => 2,
|
|
292
|
-
'Toulouse FC' => 2,
|
|
293
|
-
'Olympique Lyonnais' => 2,
|
|
294
|
-
'Stade Rennais FC' => 2,
|
|
295
|
-
'AS Monaco FC' => 2,
|
|
296
|
-
'FC Lorient' => 2), clubs
|
|
297
|
-
|
|
298
|
-
assert_equal Hash(
|
|
299
|
-
'Journée 1' => { count: 1, match_count: 10 },
|
|
300
|
-
'Journée 2' => { count: 1, match_count: 10 } ), rounds
|
|
301
|
-
end
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
def test_eng
|
|
305
|
-
txt = <<TXT
|
|
306
|
-
Matchday 1
|
|
307
|
-
|
|
308
|
-
Fri, Aug 11
|
|
309
|
-
Arsenal FC 4-3 Leicester City
|
|
310
|
-
Sat, Aug 12
|
|
311
|
-
Watford FC 3-3 Liverpool FC
|
|
312
|
-
Chelsea FC 2-3 Burnley FC
|
|
313
|
-
Crystal Palace 0-3 Huddersfield Town
|
|
314
|
-
Everton FC 1-0 Stoke City
|
|
315
|
-
Southampton FC 0-0 Swansea City
|
|
316
|
-
West Bromwich Albion 1-0 AFC Bournemouth
|
|
317
|
-
Brighton & Hove Albion 0-2 Manchester City
|
|
318
|
-
Sun, Aug 13
|
|
319
|
-
Newcastle United 0-2 Tottenham Hotspur
|
|
320
|
-
Manchester United 4-0 West Ham United
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
Matchday 2
|
|
324
|
-
|
|
325
|
-
Sat, Aug 19
|
|
326
|
-
Swansea City 0-4 Manchester United
|
|
327
|
-
AFC Bournemouth 0-2 Watford FC
|
|
328
|
-
Burnley FC 0-1 West Bromwich Albion
|
|
329
|
-
Leicester City 2-0 Brighton & Hove Albion
|
|
330
|
-
Liverpool FC 1-0 Crystal Palace
|
|
331
|
-
Southampton FC 3-2 West Ham United
|
|
332
|
-
Stoke City 1-0 Arsenal FC
|
|
333
|
-
Sun, Aug 20
|
|
334
|
-
Huddersfield Town 1-0 Newcastle United
|
|
335
|
-
Tottenham Hotspur 1-2 Chelsea FC
|
|
336
|
-
Mon, Aug 21
|
|
337
|
-
Manchester City 1-1 Everton FC
|
|
338
|
-
TXT
|
|
339
|
-
|
|
340
|
-
clubs, rounds = parse( txt )
|
|
341
|
-
|
|
342
|
-
assert_equal Hash(
|
|
343
|
-
'Arsenal FC' => 2,
|
|
344
|
-
'Leicester City' => 2,
|
|
345
|
-
'Watford FC' => 2,
|
|
346
|
-
'Liverpool FC' => 2,
|
|
347
|
-
'Chelsea FC' => 2,
|
|
348
|
-
'Burnley FC' => 2,
|
|
349
|
-
'Crystal Palace' => 2,
|
|
350
|
-
'Huddersfield Town' => 2,
|
|
351
|
-
'Everton FC' => 2,
|
|
352
|
-
'Stoke City' => 2,
|
|
353
|
-
'Southampton FC' => 2,
|
|
354
|
-
'Swansea City' => 2,
|
|
355
|
-
'West Bromwich Albion' => 2,
|
|
356
|
-
'AFC Bournemouth' => 2,
|
|
357
|
-
'Brighton & Hove Albion' => 2,
|
|
358
|
-
'Manchester City' => 2,
|
|
359
|
-
'Newcastle United' => 2,
|
|
360
|
-
'Tottenham Hotspur' => 2,
|
|
361
|
-
'Manchester United' => 2,
|
|
362
|
-
'West Ham United' => 2 ), clubs
|
|
363
|
-
|
|
364
|
-
assert_equal Hash(
|
|
365
|
-
'Matchday 1' => { count: 1, match_count: 10},
|
|
366
|
-
'Matchday 2' => { count: 1, match_count: 10} ), rounds
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
txt =<<TXT
|
|
370
|
-
Round 38
|
|
371
|
-
|
|
372
|
-
May/22 Aston Villa 1-0 Liverpool
|
|
373
|
-
May/22 Bolton 0-2 Manchester City
|
|
374
|
-
May/22 Everton 1-0 Chelsea
|
|
375
|
-
May/22 Fulham 2-2 Arsenal
|
|
376
|
-
May/22 Manchester United 4-2 Blackpool
|
|
377
|
-
May/22 Newcastle Utd 3-3 West Brom
|
|
378
|
-
May/22 Stoke City 0-1 Wigan
|
|
379
|
-
May/22 Tottenham 2-1 Birmingham
|
|
380
|
-
May/22 West Ham 0-3 Sunderland
|
|
381
|
-
May/22 Wolves 2-3 Blackburn
|
|
382
|
-
|
|
383
|
-
Round 37
|
|
384
|
-
|
|
385
|
-
May/17 Manchester City 3-0 Stoke City
|
|
386
|
-
May/15 Arsenal 1-2 Aston Villa
|
|
387
|
-
May/15 Birmingham 0-2 Fulham
|
|
388
|
-
May/15 Liverpool 0-2 Tottenham
|
|
389
|
-
May/15 Wigan 3-2 West Ham
|
|
390
|
-
May/15 Chelsea 2-2 Newcastle Utd
|
|
391
|
-
May/14 Blackburn 1-1 Manchester United
|
|
392
|
-
May/14 Blackpool 4-3 Bolton
|
|
393
|
-
May/14 Sunderland 1-3 Wolves
|
|
394
|
-
May/14 West Brom 1-0 Everton
|
|
395
|
-
TXT
|
|
396
|
-
clubs, rounds = parse( txt )
|
|
397
|
-
|
|
398
|
-
assert_equal Hash(
|
|
399
|
-
'Aston Villa' => 2,
|
|
400
|
-
'Liverpool' => 2,
|
|
401
|
-
'Bolton' => 2,
|
|
402
|
-
'Manchester City' => 2,
|
|
403
|
-
'Everton' => 2,
|
|
404
|
-
'Chelsea' => 2,
|
|
405
|
-
'Fulham' => 2,
|
|
406
|
-
'Arsenal' => 2,
|
|
407
|
-
'Manchester United' => 2,
|
|
408
|
-
'Blackpool' => 2,
|
|
409
|
-
'Newcastle Utd' => 2,
|
|
410
|
-
'West Brom' => 2,
|
|
411
|
-
'Stoke City'=> 2,
|
|
412
|
-
'Wigan' => 2,
|
|
413
|
-
'Tottenham' => 2,
|
|
414
|
-
'Birmingham' => 2,
|
|
415
|
-
'West Ham' => 2,
|
|
416
|
-
'Sunderland' => 2,
|
|
417
|
-
'Wolves' => 2,
|
|
418
|
-
'Blackburn' => 2), clubs
|
|
419
|
-
|
|
420
|
-
assert_equal Hash(
|
|
421
|
-
'Round 38' => { count: 1, match_count: 10 },
|
|
422
|
-
'Round 37' => { count: 1, match_count: 10 } ), rounds
|
|
423
|
-
end # method test_parse
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
def test_mauritius
|
|
427
|
-
txt = <<TXT
|
|
428
|
-
Preliminary Round
|
|
429
|
-
Mon Jun 22
|
|
430
|
-
Pointe-aux-Sables Mates 3-4 AS Port-Louis 2000 @ St. François Xavier Stadium, Port Louis
|
|
431
|
-
|
|
432
|
-
Quarterfinals
|
|
433
|
-
Wed Jun 24
|
|
434
|
-
Rivière du Rempart 3-1 pen (1-1) La Cure Sylvester @ Auguste Vollaire Stadium, Central Flacq
|
|
435
|
-
Chamarel SC 3-4 Petite Rivière Noire @ Germain Comarmond Stadium, Bambous
|
|
436
|
-
Thu Jun 25
|
|
437
|
-
Pamplemousses 2-0 AS Port-Louis 2000 @ Auguste Vollaire Stadium, Central Flacq
|
|
438
|
-
Sat Jun 27
|
|
439
|
-
Savanne SC 3-6 Entente Boulet Rouge @ Anjalay Stadium, Mapou
|
|
440
|
-
|
|
441
|
-
Semifinals
|
|
442
|
-
Wed Jul 15
|
|
443
|
-
Rivière du Rempart 2-3 Petite Rivière Noire @ New George V Stadium, Curepipe
|
|
444
|
-
Entente Boulet Rouge 0-2 Pamplemousses @ Germain Comarmond Stadium, Bambous
|
|
445
|
-
|
|
446
|
-
Final
|
|
447
|
-
Sun Jul 19
|
|
448
|
-
Petite Rivière Noire 2-0 Pamplemousses @ New George V Stadium, Curepipe
|
|
449
|
-
TXT
|
|
450
|
-
|
|
451
|
-
clubs, rounds = parse( txt )
|
|
452
|
-
|
|
453
|
-
assert_equal Hash(
|
|
454
|
-
'Pointe-aux-Sables Mates' => 1,
|
|
455
|
-
'AS Port-Louis 2000' => 2,
|
|
456
|
-
'Rivière du Rempart' => 2,
|
|
457
|
-
'La Cure Sylvester' => 1,
|
|
458
|
-
'Chamarel SC' => 1,
|
|
459
|
-
'Petite Rivière Noire' => 3,
|
|
460
|
-
'Pamplemousses' => 3,
|
|
461
|
-
'Savanne SC' => 1,
|
|
462
|
-
'Entente Boulet Rouge' => 2), clubs
|
|
463
|
-
|
|
464
|
-
assert_equal Hash(
|
|
465
|
-
'Preliminary Round' => {count: 1, match_count: 1},
|
|
466
|
-
'Quarterfinals' => {count: 1, match_count: 4},
|
|
467
|
-
'Semifinals' => {count: 1, match_count: 2},
|
|
468
|
-
'Final' => {count: 1, match_count: 1} ), rounds
|
|
469
|
-
end
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
################
|
|
473
|
-
## helper
|
|
474
|
-
def parse( txt, lang: 'en' )
|
|
475
|
-
lines = txt.split( /\n+/ ) # note: removes/strips empty lines
|
|
476
|
-
pp lines
|
|
477
|
-
|
|
478
|
-
start = Date.new( 2017, 7, 1 )
|
|
479
|
-
|
|
480
|
-
DateFormats.lang = lang # e.g. 'en'
|
|
481
|
-
SportDb.lang.lang = lang
|
|
482
|
-
|
|
483
|
-
parser = SportDb::AutoConfParser.new( lines, start )
|
|
484
|
-
clubs, rounds = parser.parse
|
|
485
|
-
pp rounds
|
|
486
|
-
pp clubs
|
|
487
|
-
[clubs, rounds]
|
|
488
|
-
end
|
|
489
|
-
end # class AutoConfParser
|
data/test/test_match_parser.rb
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
###
|
|
4
|
-
# to run use
|
|
5
|
-
# ruby -I ./lib -I ./test test/test_match_parser.rb
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
require 'helper'
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class TestMatchParser < MiniTest::Test
|
|
13
|
-
|
|
14
|
-
## build ActiveRecord-like club records/structs
|
|
15
|
-
Club = Struct.new( :key, :title, :synonyms )
|
|
16
|
-
def Club.read( txt )
|
|
17
|
-
recs = []
|
|
18
|
-
txt.each_line do |line|
|
|
19
|
-
values = line.split( '|' )
|
|
20
|
-
values = values.map { |value| value.strip }
|
|
21
|
-
|
|
22
|
-
title = values[0]
|
|
23
|
-
## note: quick hack - auto-generate key, that is, remove all non-ascii chars and downcase
|
|
24
|
-
key = title.downcase.gsub( /[^a-z]/, '' )
|
|
25
|
-
synonyms = values.size > 1 ? values[1..-1].join( '|' ) : nil
|
|
26
|
-
|
|
27
|
-
recs << Club.new( key, title, synonyms )
|
|
28
|
-
end
|
|
29
|
-
recs
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def test_parse
|
|
34
|
-
txt = <<TXT
|
|
35
|
-
Matchday 1
|
|
36
|
-
|
|
37
|
-
[Fri Aug/11]
|
|
38
|
-
Arsenal FC 4-3 Leicester City
|
|
39
|
-
[Sat Aug/12]
|
|
40
|
-
Watford FC 3-3 Liverpool FC
|
|
41
|
-
Chelsea FC 2-3 Burnley FC
|
|
42
|
-
Crystal Palace 0-3 Huddersfield Town
|
|
43
|
-
Everton FC 1-0 Stoke City
|
|
44
|
-
Southampton FC 0-0 Swansea City
|
|
45
|
-
West Bromwich Albion 1-0 AFC Bournemouth
|
|
46
|
-
Brighton & Hove Albion 0-2 Manchester City
|
|
47
|
-
[Sun Aug/13]
|
|
48
|
-
Newcastle United 0-2 Tottenham Hotspur
|
|
49
|
-
Manchester United 4-0 West Ham United
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Matchday 2
|
|
53
|
-
|
|
54
|
-
[Sat Aug/19]
|
|
55
|
-
Swansea City 0-4 Manchester United
|
|
56
|
-
AFC Bournemouth 0-2 Watford FC
|
|
57
|
-
Burnley FC 0-1 West Bromwich Albion
|
|
58
|
-
Leicester City 2-0 Brighton & Hove Albion
|
|
59
|
-
Liverpool FC 1-0 Crystal Palace
|
|
60
|
-
Southampton FC 3-2 West Ham United
|
|
61
|
-
Stoke City 1-0 Arsenal FC
|
|
62
|
-
[Sun Aug/20]
|
|
63
|
-
Huddersfield Town 1-0 Newcastle United
|
|
64
|
-
Tottenham Hotspur 1-2 Chelsea FC
|
|
65
|
-
[Mon Aug/21]
|
|
66
|
-
Manchester City 1-1 Everton FC
|
|
67
|
-
TXT
|
|
68
|
-
|
|
69
|
-
clubs_txt = <<TXT
|
|
70
|
-
Arsenal FC | Arsenal | FC Arsenal
|
|
71
|
-
Leicester City FC | Leicester | Leicester City
|
|
72
|
-
Watford FC | Watford | FC Watford
|
|
73
|
-
Liverpool FC | Liverpool | FC Liverpool
|
|
74
|
-
Chelsea FC | Chelsea | FC Chelsea
|
|
75
|
-
Burnley FC | Burnley | FC Burnley
|
|
76
|
-
Crystal Palace FC | Crystal Palace | C Palace | Palace | Crystal P
|
|
77
|
-
Huddersfield Town AFC | Huddersfield | Huddersfield Town
|
|
78
|
-
Everton FC | Everton | FC Everton
|
|
79
|
-
Stoke City FC | Stoke | Stoke City
|
|
80
|
-
Southampton FC | Southampton | FC Southampton
|
|
81
|
-
Swansea City FC | Swansea | Swansea City | Swansea City AFC
|
|
82
|
-
West Bromwich Albion FC | West Brom | West Bromwich Albion | West Bromwich | Albion
|
|
83
|
-
AFC Bournemouth | Bournemouth | A.F.C. Bournemouth | Bournemouth FC
|
|
84
|
-
Brighton & Hove Albion FC | Brighton | Brighton & Hove | Brighton & Hove Albion
|
|
85
|
-
Manchester City FC | Man City | Manchester City | Man. City | Manchester C
|
|
86
|
-
Newcastle United FC | Newcastle | Newcastle Utd | Newcastle United
|
|
87
|
-
Tottenham Hotspur FC | Tottenham | Tottenham Hotspur | Spurs
|
|
88
|
-
Manchester United FC | Man Utd | Man. United | Manchester U. | Manchester Utd | Manchester United
|
|
89
|
-
West Ham United FC | West Ham | West Ham United
|
|
90
|
-
TXT
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
clubs = Club.read( clubs_txt )
|
|
94
|
-
pp clubs
|
|
95
|
-
|
|
96
|
-
lines = txt.split( /\n+/ ) # note: removes/strips empty lines
|
|
97
|
-
pp lines
|
|
98
|
-
|
|
99
|
-
start = Date.new( 2017, 7, 1 )
|
|
100
|
-
|
|
101
|
-
DateFormats.lang = 'en'
|
|
102
|
-
parser = SportDb::MatchParserSimpleV2.new( lines, clubs, start )
|
|
103
|
-
rounds, matches = parser.parse
|
|
104
|
-
pp rounds
|
|
105
|
-
pp matches
|
|
106
|
-
end # method test_parse
|
|
107
|
-
end # class TestMatchParser
|