sportdb-readers 0.5.0 → 1.0.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 +4 -4
- data/Manifest.txt +5 -3
- data/NOTES.md +35 -0
- data/Rakefile +1 -3
- data/lib/sportdb/readers.rb +21 -60
- data/lib/sportdb/readers/conf_reader.rb +69 -57
- data/lib/sportdb/readers/match_reader.rb +109 -77
- data/lib/sportdb/readers/package.rb +22 -83
- data/lib/sportdb/readers/version.rb +2 -2
- data/test/helper.rb +11 -7
- data/test/test_conf_reader.rb +78 -0
- data/test/test_match_reader_champs.rb +487 -0
- data/test/test_match_reader_eng.rb +1 -1
- data/test/test_match_reader_euro.rb +156 -0
- data/test/test_match_reader_mu.rb +5 -5
- data/test/test_reader_champs.rb +187 -0
- metadata +10 -35
- data/lib/sportdb/readers/conf_linter.rb +0 -73
- data/lib/sportdb/readers/league_outline_reader.rb +0 -146
- data/lib/sportdb/readers/match_linter.rb +0 -30
@@ -2,130 +2,69 @@
|
|
2
2
|
module SportDb
|
3
3
|
class Package
|
4
4
|
|
5
|
-
|
6
|
-
CLUB_PROPS_RE = Datafile::CLUB_PROPS_RE
|
7
|
-
LEAGUES_RE = Datafile::LEAGUES_RE
|
8
|
-
CLUBS_RE = Datafile::CLUBS_RE
|
9
|
-
|
10
|
-
|
11
|
-
## note: if pattern includes directory add here (otherwise move to more "generic" datafile) - why? why not?
|
12
|
-
MATCH_RE = %r{ /(?: \d{4}-\d{2} ## season folder e.g. /2019-20
|
13
|
-
| \d{4} ## season year-only folder e.g. /2019
|
14
|
-
)
|
15
|
-
/[a-z0-9_-]+\.txt$ ## txt e.g /1-premierleague.txt
|
16
|
-
}x
|
17
|
-
|
18
|
-
|
19
|
-
attr_reader :pack ## allow access to embedded ("low-level") delegate package
|
20
|
-
|
21
|
-
def initialize( path_or_pack )
|
22
|
-
if path_or_pack.is_a?( Datafile::Package )
|
23
|
-
@pack = path_or_pack
|
24
|
-
else ## assume it's a (string) path
|
25
|
-
path = path_or_pack
|
26
|
-
if !File.exist?( path ) ## file or directory
|
27
|
-
puts "** !!! ERROR !!! file NOT found >#{path}<; cannot open package"
|
28
|
-
exit 1
|
29
|
-
end
|
30
|
-
|
31
|
-
if File.directory?( path )
|
32
|
-
@pack = Datafile::DirPackage.new( path ) ## delegate to "generic" package
|
33
|
-
elsif File.file?( path ) && File.extname( path ) == '.zip' # note: includes dot (.) eg .zip
|
34
|
-
@pack = Datafile::ZipPackage.new( path )
|
35
|
-
else
|
36
|
-
puts "** !!! ERROR !!! cannot open package - directory or file with .zip extension required"
|
37
|
-
exit 1
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def each_conf( &blk ) @pack.each( pattern: CONF_RE, &blk ); end
|
43
|
-
def each_match( &blk ) @pack.each( pattern: MATCH_RE, &blk ); end
|
44
|
-
def each_club_props( &blk ) @pack.each( pattern: CLUB_PROPS_RE, &blk ); end
|
45
|
-
|
46
|
-
def each_leagues( &blk ) @pack.each( pattern: LEAGUES_RE, &blk ); end
|
47
|
-
def each_clubs( &blk ) @pack.each( pattern: CLUBS_RE, &blk ); end
|
48
|
-
|
5
|
+
## note: add readers here; for full class def see the sourcein sportdb-formats!!!
|
49
6
|
|
50
7
|
def read_leagues
|
51
|
-
each_leagues
|
52
|
-
SportDb.parse_leagues( entry.read )
|
53
|
-
end
|
8
|
+
each_leagues { |entry| SportDb.parse_leagues( entry.read ) }
|
54
9
|
end
|
55
10
|
|
56
11
|
def read_clubs
|
57
|
-
each_clubs
|
58
|
-
SportDb.parse_clubs( entry.read )
|
59
|
-
end
|
12
|
+
each_clubs { |entry| SportDb.parse_clubs( entry.read ) }
|
60
13
|
end
|
61
14
|
|
62
|
-
|
63
|
-
|
64
|
-
each_club_props do |entry|
|
65
|
-
SportDb.parse_club_props( entry.read, sync: sync )
|
66
|
-
end
|
15
|
+
def read_club_props
|
16
|
+
each_club_props { |entry| SportDb.parse_club_props( entry.read ) }
|
67
17
|
end
|
68
18
|
|
69
|
-
|
70
|
-
|
19
|
+
|
20
|
+
def read_conf( *names, season: nil )
|
71
21
|
if names.empty? ## no (entry) names passed in; read in all
|
72
22
|
each_conf do |entry|
|
73
|
-
SportDb.parse_conf( entry.read, season: season
|
23
|
+
SportDb.parse_conf( entry.read, season: season )
|
74
24
|
end
|
75
25
|
else
|
76
26
|
names.each do |name|
|
77
27
|
entry = @pack.find( name )
|
78
|
-
SportDb.parse_conf( entry.read, season: season
|
28
|
+
SportDb.parse_conf( entry.read, season: season )
|
79
29
|
end
|
80
30
|
end
|
81
31
|
end
|
82
32
|
|
83
|
-
def read_match( *names,
|
84
|
-
season: nil, sync: true )
|
33
|
+
def read_match( *names, season: nil )
|
85
34
|
if names.empty? ## no (entry) names passed in; read in all
|
86
35
|
each_match do |entry|
|
87
|
-
SportDb.parse_match( entry.read, season: season
|
36
|
+
SportDb.parse_match( entry.read, season: season )
|
88
37
|
end
|
89
38
|
else
|
90
39
|
names.each do |name|
|
91
40
|
entry = @pack.find( name )
|
92
|
-
SportDb.parse_match( entry.read, season: season
|
41
|
+
SportDb.parse_match( entry.read, season: season )
|
93
42
|
end
|
94
43
|
end
|
95
44
|
end
|
96
45
|
|
97
46
|
|
98
|
-
def read( *names,
|
99
|
-
season: nil, sync: true )
|
47
|
+
def read( *names, season: nil )
|
100
48
|
if names.empty? ## read all datafiles
|
101
49
|
read_leagues()
|
102
50
|
read_clubs()
|
103
|
-
read_club_props(
|
104
|
-
read_conf( season: season
|
105
|
-
read_match( season: season
|
51
|
+
read_club_props()
|
52
|
+
read_conf( season: season )
|
53
|
+
read_match( season: season )
|
106
54
|
else
|
107
55
|
names.each do |name|
|
108
56
|
entry = @pack.find( name )
|
109
57
|
## fix/todo: add read_leagues, read_clubs too!!!
|
110
|
-
if
|
111
|
-
SportDb.parse_conf( entry.read, season: season
|
112
|
-
elsif
|
113
|
-
SportDb.parse_club_props( entry.read
|
114
|
-
else ## assume "regular" match datafile
|
115
|
-
SportDb.parse_match( entry.read, season: season
|
58
|
+
if match_conf?( name ) ## check if datafile matches conf(iguration) naming (e.g. .conf.txt)
|
59
|
+
SportDb.parse_conf( entry.read, season: season )
|
60
|
+
elsif match_club_props?( name )
|
61
|
+
SportDb.parse_club_props( entry.read )
|
62
|
+
else ## assume "regular" match datafile or check pattern and report error on fail - why? why not?
|
63
|
+
SportDb.parse_match( entry.read, season: season )
|
116
64
|
end
|
117
65
|
end
|
118
66
|
end
|
119
67
|
end
|
120
68
|
end # class Package
|
121
69
|
|
122
|
-
|
123
|
-
class DirPackage < Package
|
124
|
-
def initialize( path ) super( Datafile::DirPackage.new( path ) ); end
|
125
|
-
end
|
126
|
-
|
127
|
-
class ZipPackage < Package
|
128
|
-
def initialize( path ) super( Datafile::ZipPackage.new( path ) ); end
|
129
|
-
end
|
130
|
-
|
131
70
|
end # module SportDb
|
@@ -4,8 +4,8 @@
|
|
4
4
|
module SportDb
|
5
5
|
module Readers
|
6
6
|
|
7
|
-
MAJOR =
|
8
|
-
MINOR =
|
7
|
+
MAJOR = 1 ## todo: namespace inside version or something - why? why not??
|
8
|
+
MINOR = 0
|
9
9
|
PATCH = 0
|
10
10
|
VERSION = [MAJOR,MINOR,PATCH].join('.')
|
11
11
|
|
data/test/helper.rb
CHANGED
@@ -1,19 +1,23 @@
|
|
1
|
-
##
|
1
|
+
## note: use the local version of sportdb gems
|
2
|
+
$LOAD_PATH.unshift( File.expand_path( '../sportdb-formats/lib' ))
|
3
|
+
$LOAD_PATH.unshift( File.expand_path( '../sportdb-config/lib' ))
|
4
|
+
$LOAD_PATH.unshift( File.expand_path( '../sportdb-models/lib' ))
|
5
|
+
$LOAD_PATH.unshift( File.expand_path( '../sportdb-sync/lib' ))
|
6
|
+
|
2
7
|
|
3
8
|
## minitest setup
|
4
9
|
require 'minitest/autorun'
|
5
10
|
|
6
11
|
|
7
|
-
## note: use the local version of sportdb gems
|
8
|
-
$LOAD_PATH.unshift( File.expand_path( '../sportdb-match-formats/lib' ))
|
9
|
-
|
10
12
|
|
11
13
|
## our own code
|
12
14
|
require 'sportdb/readers'
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
16
|
## use (switch to) "external" datasets
|
18
17
|
SportDb::Import.config.leagues_dir = "../../../openfootball/leagues"
|
19
18
|
SportDb::Import.config.clubs_dir = "../../../openfootball/clubs"
|
19
|
+
|
20
|
+
|
21
|
+
COUNTRIES = SportDb::Import.catalog.countries
|
22
|
+
LEAGUES = SportDb::Import.catalog.leagues
|
23
|
+
CLUBS = SportDb::Import.catalog.clubs
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
###
|
4
|
+
# to run use
|
5
|
+
# ruby -I ./lib -I ./test test/test_conf_reader.rb
|
6
|
+
|
7
|
+
|
8
|
+
require 'helper'
|
9
|
+
|
10
|
+
|
11
|
+
class TestConfReader < MiniTest::Test
|
12
|
+
|
13
|
+
def setup
|
14
|
+
SportDb.connect( adapter: 'sqlite3',
|
15
|
+
database: ':memory:' )
|
16
|
+
SportDb.create_all ## build schema
|
17
|
+
|
18
|
+
## turn on logging to console
|
19
|
+
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_read
|
23
|
+
# path = "../../../openfootball/austria/2018-19/.conf.txt"
|
24
|
+
path = "../../../openfootball/england/2015-16/.conf.txt"
|
25
|
+
# path = "../../../openfootball/england/2017-18/.conf.txt"
|
26
|
+
# path = "../../../openfootball/england/2018-19/.conf.txt"
|
27
|
+
# path = "../../../openfootball/england/2019-20/.conf.txt"
|
28
|
+
SportDb::ConfReaderV2.read( path )
|
29
|
+
end # method test_read
|
30
|
+
|
31
|
+
|
32
|
+
def test_read_champs
|
33
|
+
txt =<<TXT
|
34
|
+
= UEFA Champions League 2017/18
|
35
|
+
|
36
|
+
Manchester United › ENG
|
37
|
+
Liverpool › ENG
|
38
|
+
Chelsea › ENG
|
39
|
+
Manchester City › ENG
|
40
|
+
Tottenham Hotspur › ENG
|
41
|
+
|
42
|
+
Atlético Madrid › ESP
|
43
|
+
Barcelona › ESP
|
44
|
+
Sevilla › ESP
|
45
|
+
Real Madrid › ESP
|
46
|
+
|
47
|
+
Roma › ITA
|
48
|
+
Juventus › ITA
|
49
|
+
Napoli › ITA
|
50
|
+
|
51
|
+
Bayern München › GER
|
52
|
+
Borussia Dortmund › GER
|
53
|
+
RB Leipzig › GER
|
54
|
+
|
55
|
+
Benfica › POR
|
56
|
+
Sporting CP › POR
|
57
|
+
Porto › POR
|
58
|
+
|
59
|
+
CSKA Moscow › RUS
|
60
|
+
Spartak Moscow › RUS
|
61
|
+
|
62
|
+
Paris Saint-Germain › FRA
|
63
|
+
Basel › SUI
|
64
|
+
Celtic › SCO
|
65
|
+
Anderlecht › BEL
|
66
|
+
Qarabağ › AZE
|
67
|
+
Olympiacos › GRE
|
68
|
+
Maribor › SVN
|
69
|
+
Shakhtar Donetsk › UKR
|
70
|
+
Feyenoord › NED
|
71
|
+
Beşiktaş › TUR
|
72
|
+
Monaco › MCO
|
73
|
+
APOEL › CYP
|
74
|
+
TXT
|
75
|
+
|
76
|
+
SportDb::ConfReaderV2.parse( txt )
|
77
|
+
end
|
78
|
+
end # class TestConfReader
|
@@ -0,0 +1,487 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
###
|
4
|
+
# to run use
|
5
|
+
# ruby -I ./lib -I ./test test/test_match_reader_champs.rb
|
6
|
+
|
7
|
+
|
8
|
+
require 'helper'
|
9
|
+
|
10
|
+
|
11
|
+
class TestMatchReaderChamps < MiniTest::Test
|
12
|
+
|
13
|
+
def setup
|
14
|
+
SportDb.connect( adapter: 'sqlite3',
|
15
|
+
database: ':memory:' )
|
16
|
+
SportDb.create_all ## build schema
|
17
|
+
|
18
|
+
## turn on logging to console
|
19
|
+
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def test_read_group
|
24
|
+
txt = <<TXT
|
25
|
+
= UEFA Champions League 2017/18
|
26
|
+
|
27
|
+
Group A | Manchester United Basel CSKA Moscow Benfica
|
28
|
+
Group B | Paris Saint-Germain Bayern München Celtic Anderlecht
|
29
|
+
Group C | Roma Chelsea Atlético Madrid Qarabağ
|
30
|
+
Group D | Barcelona Juventus Sporting CP Olympiacos
|
31
|
+
Group E | Liverpool Sevilla Spartak Moscow Maribor
|
32
|
+
Group F | Manchester City Shakhtar Donetsk Napoli Feyenoord
|
33
|
+
Group G | Beşiktaş Porto RB Leipzig Monaco
|
34
|
+
Group H | Tottenham Hotspur Real Madrid Borussia Dortmund APOEL
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
Matchday 1 | Sep/12 - Sep/13 ## Tu+We 12-13 September 2017
|
39
|
+
Matchday 2 | Sep/26 - Sep/27 ## Tu+We 26-27 September 2017
|
40
|
+
Matchday 3 | Oct/17 - Oct/18 ## Tu+We 17-18 October 2017
|
41
|
+
Matchday 4 | Oct/31 - Nov/1 ## Tu+We 31 October - 1 November 2017
|
42
|
+
Matchday 5 | Nov/21 - Nov/22 ## Tu+We 21-22 November 2017
|
43
|
+
Matchday 6 | Dec/5 - Dec/6 ## Tu+We 5-6 December 2017
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
Group A:
|
48
|
+
|
49
|
+
[Tue Sep/12]
|
50
|
+
20.45 Benfica 1-2 CSKA Moscow @ Estádio da Luz, Lisbon
|
51
|
+
[Seferović 50'; Vitinho 63' (pen.) Zhamaletdinov 71']
|
52
|
+
20.45 Manchester United 3-0 Basel @ Old Trafford, Manchester
|
53
|
+
[Fellaini 35' Lukaku 53' Rashford 84']
|
54
|
+
|
55
|
+
[Wed Sep/27]
|
56
|
+
20.45 Basel 5-0 Benfica @ St. Jakob-Park, Basel
|
57
|
+
[Lang 2' Oberlin 20', 69' Van Wolfswinkel 60' (pen.) Riveros 76']
|
58
|
+
20.45 CSKA Moscow 1-4 Manchester United @ VEB Arena, Moscow
|
59
|
+
[Kuchayev 90'; Lukaku 4', 27' Martial 19' (pen.) Mkhitaryan 57']
|
60
|
+
|
61
|
+
[Wed Oct/18]
|
62
|
+
20.45 CSKA Moscow 0-2 Basel @ VEB Arena, Moscow
|
63
|
+
[-; Xhaka 29' Oberlin 90']
|
64
|
+
20.45 Benfica 0-1 Manchester United @ Estádio da Luz, Lisbon
|
65
|
+
[-; Rashford 64']
|
66
|
+
|
67
|
+
[Tue Oct/31]
|
68
|
+
20.45 Basel 1-2 CSKA Moscow @ St. Jakob-Park, Basel
|
69
|
+
[Zuffi 32'; Dzagoev 65' Wernbloom 79']
|
70
|
+
20.45 Manchester United 2-0 Benfica @ Old Trafford, Manchester
|
71
|
+
[Svilar 45' (o.g.) Blind 78' (pen.)]
|
72
|
+
|
73
|
+
[Wed Nov/22]
|
74
|
+
18.00 CSKA Moscow 2-0 Benfica @ VEB Arena, Moscow
|
75
|
+
[Shchennikov 13' Jardel 56' (o.g.)]
|
76
|
+
20.45 Basel 1-0 Manchester United @ St. Jakob-Park, Basel
|
77
|
+
[Lang 89']
|
78
|
+
|
79
|
+
[Tue Dec/5]
|
80
|
+
20.45 Benfica 0-2 Basel @ Estádio da Luz, Lisbon
|
81
|
+
[-; Elyounoussi 5' Oberlin 65']
|
82
|
+
20.45 Manchester United 2-1 CSKA Moscow @ Old Trafford, Manchester
|
83
|
+
[Lukaku 64' Rashford 66'; Vitinho 45']
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
Group B:
|
88
|
+
|
89
|
+
[Tue Sep/12]
|
90
|
+
20.45 Bayern München 3-0 Anderlecht @ Allianz Arena, München
|
91
|
+
[Lewandowski 12' (pen.) Thiago 65' Kimmich 90']
|
92
|
+
20.45 Celtic 0-5 Paris Saint-Germain @ Celtic Park, Glasgow
|
93
|
+
[-; Neymar 19' Mbappé 34' Cavani 40' (pen.), 85' Lustig 83' (o.g.)]
|
94
|
+
|
95
|
+
[Wed Sep/27]
|
96
|
+
20.45 Paris Saint-Germain 3-0 Bayern München @ Parc des Princes, Paris
|
97
|
+
[Dani Alves 2' Cavani 31' Neymar 63']
|
98
|
+
20.45 Anderlecht 0-3 Celtic @ Constant Vanden Stock Stadium, Anderlecht
|
99
|
+
[-; Griffiths 38' Roberts 50' Sinclair 90+3']
|
100
|
+
|
101
|
+
[Wed Oct/18]
|
102
|
+
20.45 Anderlecht 0-4 Paris Saint-Germain @ Constant Vanden Stock Stadium, Anderlecht
|
103
|
+
[-; Mbappé 3' Cavani 44' Neymar 66' Di María 88']
|
104
|
+
20.45 Bayern München 3-0 Celtic @ Allianz Arena, München
|
105
|
+
[Müller 17' Kimmich 29' Hummels 51']
|
106
|
+
|
107
|
+
[Tue Oct/31]
|
108
|
+
20.45 Paris Saint-Germain 5-0 Anderlecht @ Parc des Princes, Paris
|
109
|
+
[Verratti 30' Neymar 45+4' Kurzawa 52', 72', 78']
|
110
|
+
20.45 Celtic 1-2 Bayern München @ Celtic Park, Glasgow
|
111
|
+
[McGregor 74'; Coman 22' Martínez 77']
|
112
|
+
|
113
|
+
[Wed Nov/22]
|
114
|
+
20.45 Anderlecht 1-2 Bayern München @ Constant Vanden Stock Stadium, Anderlecht
|
115
|
+
[Hanni 63'; Lewandowski 51' Tolisso 77']
|
116
|
+
20.45 Paris Saint-Germain 7-1 Celtic @ Parc des Princes, Paris
|
117
|
+
[Neymar 9', 22' Cavani 28', 79' Mbappé 35' Verratti 75' Dani Alves 80'; Dembélé 1']
|
118
|
+
|
119
|
+
[Tue Dec/5]
|
120
|
+
20.45 Bayern München 3-1 Paris Saint-Germain @ Allianz Arena, München
|
121
|
+
[Lewandowski 8' Tolisso 37', 69'; Mbappé 50']
|
122
|
+
20.45 Celtic 0-1 Anderlecht @ Celtic Park, Glasgow
|
123
|
+
[-; Šimunović 62' (o.g.)]
|
124
|
+
|
125
|
+
|
126
|
+
Group C:
|
127
|
+
|
128
|
+
[Tue Sep/12]
|
129
|
+
20.45 Chelsea 6-0 Qarabağ @ Stamford Bridge, London
|
130
|
+
[Pedro 5' Zappacosta 30' Azpilicueta 55' Bakayoko 71' Batshuayi 76' Medvedev 82' (o.g.)]
|
131
|
+
20.45 Roma 0-0 Atlético Madrid @ Stadio Olimpico, Rome
|
132
|
+
|
133
|
+
[Wed Sep/27]
|
134
|
+
18.00 Qarabağ 1-2 Roma @ Olympic Stadium, Baku [A]
|
135
|
+
[Pedro Henrique 28'; Manolas 7' Džeko 15']
|
136
|
+
20.45 Atlético Madrid 1-2 Chelsea @ Wanda Metropolitano, Madrid
|
137
|
+
[Griezmann 40' (pen.); Morata 60' Batshuayi 90+3']
|
138
|
+
|
139
|
+
[Wed Oct/18]
|
140
|
+
18.00 Qarabağ 0-0 Atlético Madrid @ Olympic Stadium, Baku [A]
|
141
|
+
20.45 Chelsea 3-3 Roma @ Stamford Bridge, London
|
142
|
+
[David Luiz 11' Hazard 37', 75'; Kolarov 40' Džeko 64', 70']
|
143
|
+
|
144
|
+
[Tue Oct/31]
|
145
|
+
20.45 Atlético Madrid 1-1 Qarabağ @ Wanda Metropolitano, Madrid
|
146
|
+
[Partey 56'; Míchel 40']
|
147
|
+
20.45 Roma 3-0 Chelsea @ Stadio Olimpico, Rome
|
148
|
+
[El Shaarawy 1', 36' Perotti 63']
|
149
|
+
|
150
|
+
[Wed Nov/22]
|
151
|
+
18.00 Qarabağ 0-4 Chelsea @ Olympic Stadium, Baku [A]
|
152
|
+
[-; Hazard 21' (pen.) Willian 36', 85' Fàbregas 73' (pen.)]
|
153
|
+
20.45 Atlético Madrid 2-0 Roma @ Wanda Metropolitano, Madrid
|
154
|
+
[Griezmann 69' Gameiro 85']
|
155
|
+
|
156
|
+
[Tue Dec/5]
|
157
|
+
20.45 Chelsea 1-1 Atlético Madrid @ Stamford Bridge, London
|
158
|
+
[Savić 75' (o.g.); Saúl 56']
|
159
|
+
20.45 Roma 1-0 Qarabağ @ Stadio Olimpico, Rome
|
160
|
+
[Perotti 53']
|
161
|
+
|
162
|
+
###
|
163
|
+
# [^A]: Qarabağ played their home matches at Olympic Stadium, Baku,
|
164
|
+
# instead of their regular stadium Azersun Arena, Baku.
|
165
|
+
|
166
|
+
|
167
|
+
|
168
|
+
Group D:
|
169
|
+
|
170
|
+
[Tue Sep/12]
|
171
|
+
20.45 Barcelona 3-0 Juventus @ Camp Nou, Barcelona
|
172
|
+
[Messi 45', 69' Rakitić 56']
|
173
|
+
20.45 Olympiacos 2-3 Sporting CP @ Karaiskakis Stadium, Piraeus
|
174
|
+
[Pardo 89', 90+3'; Doumbia 2' Gelson M. 13' Fernandes 43']
|
175
|
+
|
176
|
+
[Wed Sep/27]
|
177
|
+
20.45 Sporting CP 0-1 Barcelona @ Estádio José Alvalade, Lisbon
|
178
|
+
[-; Coates 49' (o.g.)]
|
179
|
+
20.45 Juventus 2-0 Olympiacos @ Juventus Stadium, Turin
|
180
|
+
[Higuaín 69' Mandžukić 80']
|
181
|
+
|
182
|
+
[Wed Oct/18]
|
183
|
+
20.45 Juventus 2-1 Sporting CP @ Juventus Stadium, Turin
|
184
|
+
[Pjanić 29' Mandžukić 84'; Alex Sandro 12' (o.g.)]
|
185
|
+
20.45 Barcelona 3-1 Olympiacos @ Camp Nou, Barcelona
|
186
|
+
[Nikolaou 18' (o.g.) Messi 61' Digne 64'; Nikolaou 90']
|
187
|
+
|
188
|
+
[Tue Oct/31]
|
189
|
+
20.45 Sporting CP 1-1 Juventus @ Estádio José Alvalade, Lisbon
|
190
|
+
[Bruno César 20'; Higuaín 79']
|
191
|
+
20.45 Olympiacos 0-0 Barcelona @ Karaiskakis Stadium, Piraeus
|
192
|
+
|
193
|
+
[Wed Nov/22]
|
194
|
+
20.45 Juventus 0-0 Barcelona @ Juventus Stadium, Turin
|
195
|
+
20.45 Sporting CP 3-1 Olympiacos @ Estádio José Alvalade, Lisbon
|
196
|
+
[Dost 40', 66' Bruno César 43'; Odjidja-Ofoe 86']
|
197
|
+
|
198
|
+
[Tue Dec/5]
|
199
|
+
20.45 Barcelona 2-0 Sporting CP @ Camp Nou, Barcelona
|
200
|
+
[Alcácer 59' Mathieu 90+1' (o.g.)]
|
201
|
+
20.45 Olympiacos 0-2 Juventus @ Karaiskakis Stadium, Piraeus
|
202
|
+
[-; Cuadrado 15' Bernardeschi 90']
|
203
|
+
|
204
|
+
|
205
|
+
Group E:
|
206
|
+
|
207
|
+
[Wed Sep/13]
|
208
|
+
20.45 Maribor 1-1 Spartak Moscow @ Ljudski vrt, Maribor
|
209
|
+
[Bohar 85'; Samedov 59']
|
210
|
+
20.45 Liverpool 2-2 Sevilla @ Anfield, Liverpool
|
211
|
+
[Firmino 21' Salah 37'; Ben Yedder 5' Correa 72']
|
212
|
+
|
213
|
+
[Tue Sep/26]
|
214
|
+
20.45 Sevilla 3-0 Maribor @ Ramón Sánchez Pizjuán, Seville
|
215
|
+
[Ben Yedder 27', 38', 83' (pen.)]
|
216
|
+
20.45 Spartak Moscow 1-1 Liverpool @ Otkritie Arena, Moscow
|
217
|
+
[Fernando 23'; Coutinho 31']
|
218
|
+
|
219
|
+
[Tue Oct/17]
|
220
|
+
20.45 Spartak Moscow 5-1 Sevilla @ Otkritie Arena, Moscow
|
221
|
+
[Promes 18', 90' Melgarejo 58' Glushakov 67' Luiz Adriano 74'; Kjær 30']
|
222
|
+
20.45 Maribor 0-7 Liverpool @ Ljudski vrt, Maribor
|
223
|
+
[-; Firmino 4', 54' Coutinho 13' Salah 19', 40' Oxlade-Chamberlain 86' Alexander-Arnold 90']
|
224
|
+
|
225
|
+
[Wed Nov/1]
|
226
|
+
20.45 Sevilla 2-1 Spartak Moscow @ Ramón Sánchez Pizjuán, Seville
|
227
|
+
[Lenglet 30' Banega 59'; Zé Luís 78']
|
228
|
+
20.45 Liverpool 3-0 Maribor @ Anfield, Liverpool
|
229
|
+
[Salah 49' Can 64' Sturridge 90']
|
230
|
+
|
231
|
+
[Tue Nov/21]
|
232
|
+
18.00 Spartak Moscow 1-1 Maribor @ Otkritie Arena, Moscow
|
233
|
+
[Zé Luís 82'; Mešanović 90+2']
|
234
|
+
20.45 Sevilla 3-3 Liverpool @ Ramón Sánchez Pizjuán, Seville
|
235
|
+
[Ben Yedder 51', 60' (pen.) Pizarro 90+3'; Firmino 2', 30' Mané 22']
|
236
|
+
|
237
|
+
[Wed Dec/6]
|
238
|
+
20.45 Maribor 1-1 Sevilla @ Ljudski vrt, Maribor
|
239
|
+
[Tavares 10'; Ganso 75']
|
240
|
+
20.45 Liverpool 7-0 Spartak Moscow @ Anfield, Liverpool
|
241
|
+
[Coutinho 4' (pen.), 15', 50' Firmino 19' Mané 47', 76' Salah 86']
|
242
|
+
|
243
|
+
|
244
|
+
Group F:
|
245
|
+
|
246
|
+
[Wed Sep/13]
|
247
|
+
20.45 Feyenoord 0-4 Manchester City @ De Kuip, Rotterdam
|
248
|
+
[-; Stones 2', 63' Agüero 10' Gabriel Jesus 25']
|
249
|
+
20.45 Shakhtar Donetsk 2-1 Napoli @ Metalist Stadium, Kharkiv [B]
|
250
|
+
[Taison 15' Ferreyra 58'; Milik 72' (pen.)]
|
251
|
+
|
252
|
+
[Tue Sep/26]
|
253
|
+
20.45 Napoli 3-1 Feyenoord @ Stadio San Paolo, Naples
|
254
|
+
[Insigne 7' Mertens 49' Callejón 70'; Amrabat 90+3']
|
255
|
+
20.45 Manchester City 2-0 Shakhtar Donetsk @ City of Manchester Stadium, Manchester
|
256
|
+
[De Bruyne 48' Sterling 90']
|
257
|
+
|
258
|
+
[Tue Oct/17]
|
259
|
+
20.45 Manchester City 2-1 Napoli @ City of Manchester Stadium, Manchester
|
260
|
+
[Sterling 9' Gabriel Jesus 13'; Diawara 73' (pen.)]
|
261
|
+
20.45 Feyenoord 1-2 Shakhtar Donetsk @ De Kuip, Rotterdam
|
262
|
+
[Berghuis 8'; Bernard 24', 54']
|
263
|
+
|
264
|
+
[Wed Nov/1]
|
265
|
+
20.45 Napoli 2-4 Manchester City @ Stadio San Paolo, Naples
|
266
|
+
[Insigne 21' Jorginho 62' (pen.); Otamendi 34' Stones 48' Agüero 69' Sterling 90+2']
|
267
|
+
20.45 Shakhtar Donetsk 3-1 Feyenoord @ Metalist Stadium, Kharkiv [B]
|
268
|
+
[Ferreyra 14' Marlos 17', 68'; Jørgensen 12']
|
269
|
+
|
270
|
+
[Tue Nov/21]
|
271
|
+
20.45 Manchester City 1-0 Feyenoord @ City of Manchester Stadium, Manchester
|
272
|
+
[Sterling 88']
|
273
|
+
20.45 Napoli 3-0 Shakhtar Donetsk @ Stadio San Paolo, Naples
|
274
|
+
[Insigne 56' Zieliński 81' Mertens 83']
|
275
|
+
|
276
|
+
[Wed Dec/6]
|
277
|
+
20.45 Feyenoord 2-1 Napoli @ De Kuip, Rotterdam
|
278
|
+
[Jørgensen 33' St. Juste 90+1'; Zieliński 2']
|
279
|
+
20.45 Shakhtar Donetsk 2-1 Manchester City @ Metalist Stadium, Kharkiv [B]
|
280
|
+
[Bernard 26' Ismaily 32'; Agüero 90+2' (pen.)]
|
281
|
+
|
282
|
+
###
|
283
|
+
# [^B]: Shakhtar Donetsk played their home matches at Metalist Stadium, Kharkiv,
|
284
|
+
# instead of their regular stadium Donbass Arena, Donetsk,
|
285
|
+
# due to the war conditions in Eastern Ukraine.
|
286
|
+
|
287
|
+
|
288
|
+
Group G:
|
289
|
+
|
290
|
+
[Wed Sep/13]
|
291
|
+
20.45 RB Leipzig 1-1 Monaco @ Red Bull Arena, Leipzig
|
292
|
+
[Forsberg 33'; Tielemans 34']
|
293
|
+
20.45 Porto 1-3 Beşiktaş @ Estádio do Dragão, Porto
|
294
|
+
[Tošić 21' (o.g.); Talisca 13' Tosun 28' Babel 86']
|
295
|
+
|
296
|
+
[Tue Sep/26]
|
297
|
+
20.45 Beşiktaş 2-0 RB Leipzig @ Vodafone Park, Istanbul
|
298
|
+
[Babel 11' Talisca 43']
|
299
|
+
20.45 Monaco 0-3 Porto @ Stade Louis II, Monaco
|
300
|
+
[-; Aboubakar 31', 69' Layún 89']
|
301
|
+
|
302
|
+
[Tue Oct/17]
|
303
|
+
20.45 Monaco 1-2 Beşiktaş @ Stade Louis II, Monaco
|
304
|
+
[Falcao 30'; Tosun 34', 54']
|
305
|
+
20.45 RB Leipzig 3-2 Porto @ Red Bull Arena, Leipzig
|
306
|
+
[Orban 8' Forsberg 38' Augustin 41'; Aboubakar 18' Marcano 44']
|
307
|
+
|
308
|
+
[Wed Nov/1]
|
309
|
+
18.00 Beşiktaş 1-1 Monaco @ Vodafone Park, Istanbul
|
310
|
+
[Tosun 54' (pen.); Lopes 45+1']
|
311
|
+
20.45 Porto 3-1 RB Leipzig @ Estádio do Dragão, Porto
|
312
|
+
[Herrera 13' Danilo 61' Pereira 90+3'; Werner 48']
|
313
|
+
|
314
|
+
[Tue Nov/21]
|
315
|
+
18.00 Beşiktaş 1-1 Porto @ Vodafone Park, Istanbul
|
316
|
+
[Talisca 41'; Felipe 29']
|
317
|
+
20.45 Monaco 1-4 RB Leipzig @ Stade Louis II, Monaco
|
318
|
+
[Falcao 43'; Jemerson 6' (o.g.) Werner 9', 31' (pen.) Keïta 45']
|
319
|
+
|
320
|
+
[Wed Dec/6]
|
321
|
+
20.45 RB Leipzig 1-2 Beşiktaş @ Red Bull Arena, Leipzig
|
322
|
+
[Keïta 87'; Negredo 10' (pen.) Talisca 90']
|
323
|
+
20.45 Porto 5-2 Monaco @ Estádio do Dragão, Porto
|
324
|
+
[Aboubakar 9', 33' Brahimi 45' Alex Telles 65' Soares 88'; Glik 61' (pen.) Falcao 78']
|
325
|
+
|
326
|
+
|
327
|
+
Group H:
|
328
|
+
|
329
|
+
[Wed Sep/13]
|
330
|
+
20.45 Real Madrid 3-0 APOEL @ Santiago Bernabéu, Madrid
|
331
|
+
[Ronaldo 12', 51' (pen.) Ramos 61']
|
332
|
+
20.45 Tottenham Hotspur 3-1 Borussia Dortmund @ Wembley Stadium, London
|
333
|
+
[Son Heung-min 4' Kane 15', 60'; Yarmolenko 11']
|
334
|
+
|
335
|
+
[Tue Sep/26]
|
336
|
+
20.45 Borussia Dortmund 1-3 Real Madrid @ Westfalenstadion, Dortmund
|
337
|
+
[Aubameyang 54'; Bale 18' Ronaldo 50', 79']
|
338
|
+
20.45 APOEL 0-3 Tottenham Hotspur @ GSP Stadium, Nicosia
|
339
|
+
[-; Kane 39', 62', 67']
|
340
|
+
|
341
|
+
[Tue Oct/17]
|
342
|
+
20.45 APOEL 1-1 Borussia Dortmund @ GSP Stadium, Nicosia
|
343
|
+
[Poté 62'; Papastathopoulos 67']
|
344
|
+
20.45 Real Madrid 1-1 Tottenham Hotspur @ Santiago Bernabéu, Madrid
|
345
|
+
[Ronaldo 43' (pen.); Varane 28' (o.g.)]
|
346
|
+
|
347
|
+
[Wed Nov/1]
|
348
|
+
20.45 Borussia Dortmund 1-1 APOEL @ Westfalenstadion, Dortmund
|
349
|
+
[Guerreiro 29'; Poté 51']
|
350
|
+
20.45 Tottenham Hotspur 3-1 Real Madrid @ Wembley Stadium, London
|
351
|
+
[Alli 27', 56' Eriksen 65'; Ronaldo 80']
|
352
|
+
|
353
|
+
[Tue Nov/21]
|
354
|
+
20.45 APOEL 0-6 Real Madrid @ GSP Stadium, Nicosia
|
355
|
+
[-; Modrić 23' Benzema 39', 45+1' Nacho 41' Ronaldo 49', 54']
|
356
|
+
20.45 Borussia Dortmund 1-2 Tottenham Hotspur @ Westfalenstadion, Dortmund
|
357
|
+
[Aubameyang 31'; Kane 49' Son Heung-min 76']
|
358
|
+
|
359
|
+
[Wed Dec/6]
|
360
|
+
20.45 Real Madrid 3-2 Borussia Dortmund @ Santiago Bernabéu, Madrid
|
361
|
+
[Mayoral 8' Ronaldo 12' Vázquez 81'; Aubameyang 43', 49']
|
362
|
+
20.45 Tottenham Hotspur 3-0 APOEL @ Wembley Stadium, London
|
363
|
+
[Llorente 20' Son Heung-min 37' N'Koudou 80']
|
364
|
+
TXT
|
365
|
+
|
366
|
+
SportDb::MatchReaderV2.parse( txt )
|
367
|
+
end
|
368
|
+
|
369
|
+
def test_read_finals
|
370
|
+
txt =<<TXT
|
371
|
+
= UEFA Champions League 2017/18
|
372
|
+
|
373
|
+
Round of 16 - 1st Leg
|
374
|
+
|
375
|
+
[Tue Feb/13]
|
376
|
+
20.45 Juventus 2-2 Tottenham Hotspur @ Juventus Stadium, Turin
|
377
|
+
[Higuaín 2', 9' (pen.); Kane 35' Eriksen 71']
|
378
|
+
20.45 Basel 0-4 Manchester City @ St. Jakob-Park, Basel
|
379
|
+
[-; Gündoğan 14', 53' B. Silva 18' Agüero 23']
|
380
|
+
|
381
|
+
[Wed Feb/14]
|
382
|
+
20.45 Porto 0-5 Liverpool @ Estádio do Dragão, Porto
|
383
|
+
[-; Mané 25', 53', 85' Salah 29' Firmino 69']
|
384
|
+
20.45 Real Madrid 3-1 Paris Saint-Germain @ Santiago Bernabéu, Madrid
|
385
|
+
[Ronaldo 45' (pen.), 83' Marcelo 86'; Rabiot 33']
|
386
|
+
|
387
|
+
[Tue Feb/20]
|
388
|
+
20.45 Bayern München 5-0 Beşiktaş @ Allianz Arena, München
|
389
|
+
[Müller 43', 66' Coman 53' Lewandowski 79', 88']
|
390
|
+
20.45 Chelsea 1-1 Barcelona @ Stamford Bridge, London
|
391
|
+
[Willian 62'; Messi 75']
|
392
|
+
|
393
|
+
[Wed Feb/21]
|
394
|
+
20.45 Shakhtar Donetsk 2-1 Roma @ Metalist Stadium, Kharkiv [†]
|
395
|
+
[Ferreyra 52' Fred 71'; Ünder 41']
|
396
|
+
20.45 Sevilla 0-0 Manchester United @ Ramón Sánchez Pizjuán, Seville
|
397
|
+
|
398
|
+
|
399
|
+
Round of 16 - 2nd Leg
|
400
|
+
|
401
|
+
[Tue Mar/6]
|
402
|
+
20.45 Liverpool 0-0 Porto @ Anfield, Liverpool
|
403
|
+
20.45 Paris Saint-Germain 1-2 Real Madrid @ Parc des Princes, Paris
|
404
|
+
[Cavani 71'; Ronaldo 51' Casemiro 80']
|
405
|
+
|
406
|
+
[Wed Mar/7]
|
407
|
+
20.45 Manchester City 1-2 Basel @ City of Manchester Stadium, Manchester
|
408
|
+
[Gabriel Jesus 8'; Elyounoussi 17' Lang 71']
|
409
|
+
20.45 Tottenham Hotspur 1-2 Juventus @ Wembley Stadium, London
|
410
|
+
[Son Heung-min 39'; Higuaín 64' Dybala 67']
|
411
|
+
|
412
|
+
[Tue Mar/13]
|
413
|
+
20.45 Roma 1-0 Shakhtar Donetsk @ Stadio Olimpico, Rome
|
414
|
+
[Džeko 52']
|
415
|
+
20.45 Manchester United 1-2 Sevilla @ Old Trafford, Manchester
|
416
|
+
[Lukaku 84'; Ben Yedder 74', 78']
|
417
|
+
|
418
|
+
[Wed Mar/14]
|
419
|
+
20.45 Barcelona 3-0 Chelsea @ Camp Nou, Barcelona
|
420
|
+
[Messi 3', 63' Dembélé 20']
|
421
|
+
18.00 Beşiktaş 1-3 Bayern München @ Vodafone Park, Istanbul
|
422
|
+
[Vágner Love 59'; Thiago 18' Gönül 46' (o.g.) Wagner 84']
|
423
|
+
|
424
|
+
|
425
|
+
Quarter-finals - 1st Leg
|
426
|
+
|
427
|
+
[Tue Apr/3]
|
428
|
+
20.45 Juventus 0-3 Real Madrid @ Juventus Stadium, Turin
|
429
|
+
[-; Ronaldo 3', 64' Marcelo 72']
|
430
|
+
20.45 Sevilla 1-2 Bayern München @ Ramón Sánchez Pizjuán, Seville
|
431
|
+
[Sarabia 31'; Navas 37' (o.g.) Thiago 68']
|
432
|
+
|
433
|
+
[Wed Apr/4]
|
434
|
+
20.45 Barcelona 4-1 Roma @ Camp Nou, Barcelona
|
435
|
+
[De Rossi 38' (o.g.) Manolas 55' (o.g.) Piqué 59' L. Suárez 87'; Džeko 80']
|
436
|
+
20.45 Liverpool 3-0 Manchester City @ Anfield, Liverpool
|
437
|
+
[Salah 12' Oxlade-Chamberlain 21' Mané 31']
|
438
|
+
|
439
|
+
|
440
|
+
Quarter-finals - 2nd Leg
|
441
|
+
|
442
|
+
[Tue Apr/10]
|
443
|
+
20.45 Roma 3-0 Barcelona @ Stadio Olimpico, Rome
|
444
|
+
[Džeko 6' De Rossi 58' (pen.) Manolas 82']
|
445
|
+
20.45 Manchester City 1-2 Liverpool @ City of Manchester Stadium, Manchester
|
446
|
+
[Gabriel Jesus 2'; Salah 56' Firmino 77']
|
447
|
+
|
448
|
+
[Wed Apr/11]
|
449
|
+
20.45 Real Madrid 1-3 Juventus @ Santiago Bernabéu, Madrid
|
450
|
+
[Ronaldo 90+8' (pen.); Mandžukić 2', 37' Matuidi 61']
|
451
|
+
20.45 Bayern München 0-0 Sevilla @ Allianz Arena, München
|
452
|
+
|
453
|
+
|
454
|
+
|
455
|
+
Semi-finals - 1st Leg
|
456
|
+
|
457
|
+
[Tue Apr/24]
|
458
|
+
20.45 Liverpool 5-2 Roma @ Anfield, Liverpool
|
459
|
+
[Salah 36', 45+1' Mané 56' Firmino 61', 69'; Džeko 81' Perotti 85' (pen.)]
|
460
|
+
|
461
|
+
[Wed Apr/25]
|
462
|
+
20.45 Bayern München 1-2 Real Madrid @ Allianz Arena, München
|
463
|
+
[Kimmich 28'; Marcelo 44' Asensio 57']
|
464
|
+
|
465
|
+
|
466
|
+
Semi-finals - 2nd Leg
|
467
|
+
|
468
|
+
[Tue May/1]
|
469
|
+
20.45 Real Madrid 2-2 Bayern München @ Santiago Bernabéu, Madrid
|
470
|
+
[Benzema 11', 46'; Kimmich 3' Rodríguez 63']
|
471
|
+
|
472
|
+
[Wed May/2]
|
473
|
+
20.45 Roma 4-2 Liverpool @ Stadio Olimpico, Rome
|
474
|
+
[Milner 15' (o.g.) Džeko 52' Nainggolan 86', 90+4' (pen.); Mané 9' Wijnaldum 25']
|
475
|
+
|
476
|
+
Final
|
477
|
+
|
478
|
+
[Sat May/26]
|
479
|
+
20.45 Real Madrid 3-1 Liverpool @ NSC Olimpiyskiy Stadium, Kiev
|
480
|
+
[Benzema 51' Bale 64', 83'; Mané 55']
|
481
|
+
TXT
|
482
|
+
|
483
|
+
SportDb::MatchReaderV2.parse( txt )
|
484
|
+
end
|
485
|
+
|
486
|
+
|
487
|
+
end # class TestMatchReaderChamps
|