sportdb-formats 0.4.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Manifest.txt +24 -4
- data/Rakefile +3 -3
- data/lib/sportdb/formats.rb +25 -2
- data/lib/sportdb/formats/config.rb +40 -0
- data/lib/sportdb/formats/datafile.rb +42 -62
- data/lib/sportdb/formats/datafile_package.rb +160 -0
- data/lib/sportdb/formats/match/conf_parser.rb +120 -0
- data/lib/sportdb/formats/match/mapper.rb +319 -0
- data/lib/sportdb/formats/match/mapper_teams.rb +23 -0
- data/lib/sportdb/formats/match/match_parser.rb +659 -0
- data/lib/sportdb/formats/match/match_parser_auto_conf.rb +202 -0
- data/lib/sportdb/formats/name_helper.rb +84 -0
- data/lib/sportdb/formats/outline_reader.rb +53 -15
- data/lib/sportdb/formats/package.rb +172 -160
- data/lib/sportdb/formats/parser_helper.rb +81 -0
- data/lib/sportdb/formats/score/score_formats.rb +180 -0
- data/lib/sportdb/formats/score/score_parser.rb +196 -0
- data/lib/sportdb/formats/structs/country.rb +1 -43
- data/lib/sportdb/formats/structs/group.rb +25 -0
- data/lib/sportdb/formats/structs/league.rb +7 -26
- data/lib/sportdb/formats/structs/match.rb +72 -51
- data/lib/sportdb/formats/structs/round.rb +14 -4
- data/lib/sportdb/formats/structs/season.rb +3 -0
- data/lib/sportdb/formats/structs/team.rb +144 -0
- data/lib/sportdb/formats/version.rb +2 -2
- data/test/helper.rb +83 -1
- data/test/test_clubs.rb +3 -3
- data/test/test_conf.rb +65 -0
- data/test/test_datafile.rb +21 -30
- data/test/test_match.rb +0 -6
- data/test/test_match_auto.rb +72 -0
- data/test/test_match_auto_champs.rb +45 -0
- data/test/test_match_auto_euro.rb +37 -0
- data/test/test_match_auto_worldcup.rb +61 -0
- data/test/test_match_champs.rb +27 -0
- data/test/test_match_eng.rb +26 -0
- data/test/test_match_euro.rb +27 -0
- data/test/test_match_worldcup.rb +27 -0
- data/test/test_name_helper.rb +67 -0
- data/test/test_outline_reader.rb +3 -3
- data/test/test_package.rb +21 -2
- data/test/test_package_match.rb +78 -0
- data/test/test_scores.rb +67 -51
- metadata +32 -12
- data/lib/sportdb/formats/scores.rb +0 -253
- data/lib/sportdb/formats/structs/club.rb +0 -213
- data/test/test_club_helpers.rb +0 -63
- data/test/test_datafile_match.rb +0 -65
@@ -4,8 +4,8 @@
|
|
4
4
|
module SportDb
|
5
5
|
module Formats
|
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,4 +1,6 @@
|
|
1
|
-
##
|
1
|
+
## note: use the local version of gems
|
2
|
+
$LOAD_PATH.unshift( File.expand_path( '../date-formats/lib' ))
|
3
|
+
|
2
4
|
|
3
5
|
## minitest setup
|
4
6
|
require 'minitest/autorun'
|
@@ -6,3 +8,83 @@ require 'minitest/autorun'
|
|
6
8
|
|
7
9
|
## our own code
|
8
10
|
require 'sportdb/formats'
|
11
|
+
|
12
|
+
|
13
|
+
################
|
14
|
+
## helper
|
15
|
+
|
16
|
+
def parse_auto_conf( txt, lang: 'en', start: nil )
|
17
|
+
start = start ? start : Date.new( 2017, 7, 1 )
|
18
|
+
|
19
|
+
SportDb::Import.config.lang = lang
|
20
|
+
|
21
|
+
parser = SportDb::AutoConfParser.new( txt, start )
|
22
|
+
parser.parse
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse_conf( txt )
|
26
|
+
parser = SportDb::ConfParser.new( txt )
|
27
|
+
parser.parse
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
## note: json always returns hash tables with string keys (not symbols),
|
32
|
+
## thus, always stringify keys before comparing!!!!
|
33
|
+
class Object
|
34
|
+
def deep_stringify_keys
|
35
|
+
if self.is_a? Hash
|
36
|
+
self.reduce({}) {|memo,(k,v)| memo[k.to_s] = v.deep_stringify_keys; memo }
|
37
|
+
elsif self.is_a? Array
|
38
|
+
self.reduce([]) {|memo,v | memo << v.deep_stringify_keys; memo }
|
39
|
+
else
|
40
|
+
self
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def read_blocks( path )
|
47
|
+
txt = File.open( path, 'r:utf-8' ).read
|
48
|
+
|
49
|
+
blocks = []
|
50
|
+
buf = String.new('')
|
51
|
+
txt.each_line do |line|
|
52
|
+
if line =~ /^[ ]*
|
53
|
+
([>]{3,} |
|
54
|
+
[<]{3,})
|
55
|
+
[ ]*
|
56
|
+
$/x ## three or more markers
|
57
|
+
blocks << buf
|
58
|
+
buf = String.new('')
|
59
|
+
else
|
60
|
+
buf << line
|
61
|
+
end
|
62
|
+
end
|
63
|
+
blocks << buf
|
64
|
+
blocks
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def parse_json( str )
|
69
|
+
## note: allow empty string; fall back to empty hash
|
70
|
+
if str.strip.empty?
|
71
|
+
{}
|
72
|
+
else
|
73
|
+
JSON.parse( str )
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def read_test( path )
|
78
|
+
blocks = read_blocks( "../football.txt/#{path}" )
|
79
|
+
|
80
|
+
if blocks.size == 2
|
81
|
+
[blocks[0], parse_json( blocks[1] )]
|
82
|
+
elsif blocks.size == 3
|
83
|
+
## note: returned in different order
|
84
|
+
## optional option block that comes first returned last!
|
85
|
+
[blocks[1], parse_json( blocks[2] ), blocks[0]]
|
86
|
+
else
|
87
|
+
puts "!! ERROR: expected two or three text blocks in >#{path}<; got #{blocks.size}"
|
88
|
+
exit 1
|
89
|
+
end
|
90
|
+
end
|
data/test/test_clubs.rb
CHANGED
@@ -11,14 +11,14 @@ class TestClubs < MiniTest::Test
|
|
11
11
|
|
12
12
|
Club = SportDb::Import::Club
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
|
15
|
+
def test_new
|
16
|
+
club = Club.new( name: 'Rapid Wien' )
|
16
17
|
|
17
18
|
assert_equal 'Rapid Wien', club.name
|
18
19
|
assert_equal ['Rapid Wien'], club.names
|
19
20
|
end
|
20
21
|
|
21
|
-
|
22
22
|
def test_duplicates
|
23
23
|
club = Club.new
|
24
24
|
club.name = 'Rapid Wien'
|
data/test/test_conf.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
###
|
4
|
+
# to run use
|
5
|
+
# ruby -I ./lib -I ./test test/test_conf.rb
|
6
|
+
|
7
|
+
|
8
|
+
require 'helper'
|
9
|
+
|
10
|
+
|
11
|
+
class TestConf < MiniTest::Test
|
12
|
+
|
13
|
+
COUNTRY_RE = SportDb::ConfParser::COUNTRY_RE
|
14
|
+
TABLE_RE = SportDb::ConfParser::TABLE_RE
|
15
|
+
|
16
|
+
def test_re
|
17
|
+
m=COUNTRY_RE.match( 'Manchester United › ENG' )
|
18
|
+
pp m
|
19
|
+
pp m[0]
|
20
|
+
assert_equal 'ENG', m[:country]
|
21
|
+
|
22
|
+
m=COUNTRY_RE.match( 'Manchester United›ENG' )
|
23
|
+
pp m
|
24
|
+
pp m[0]
|
25
|
+
assert_equal 'ENG', m[:country]
|
26
|
+
|
27
|
+
|
28
|
+
m=TABLE_RE.match( '1 Manchester City 38 32 4 2 106-27 100' )
|
29
|
+
pp m
|
30
|
+
assert_equal 'Manchester City', m[:team]
|
31
|
+
|
32
|
+
m=TABLE_RE.match( '1. Manchester City 38 32 4 2 106:27 100' )
|
33
|
+
pp m
|
34
|
+
assert_equal 'Manchester City', m[:team]
|
35
|
+
|
36
|
+
m=TABLE_RE.match( '- Manchester City 38 32 4 2 106 - 27 100' )
|
37
|
+
pp m
|
38
|
+
assert_equal 'Manchester City', m[:team]
|
39
|
+
|
40
|
+
|
41
|
+
m=TABLE_RE.match( '1. 1. FC Mainz 38 32 4 2 106-27 100 [-7]' )
|
42
|
+
pp m
|
43
|
+
assert_equal '1. FC Mainz', m[:team]
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def test_conf
|
48
|
+
%w[conf/at_cup.txt
|
49
|
+
conf/at_reg.txt
|
50
|
+
conf/at_champs.txt
|
51
|
+
conf/eng.txt
|
52
|
+
conf/champs.txt
|
53
|
+
].each do |path|
|
54
|
+
txt, exp = read_test( path )
|
55
|
+
|
56
|
+
puts "testing conf #{path}..."
|
57
|
+
teams = parse_conf( txt )
|
58
|
+
|
59
|
+
## note: json always returns hash tables with string keys (not symbols),
|
60
|
+
## thus, always stringify keys before comparing!!!!
|
61
|
+
assert_equal exp, teams.deep_stringify_keys
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end # class TestConf
|
data/test/test_datafile.rb
CHANGED
@@ -10,54 +10,45 @@ require 'helper'
|
|
10
10
|
|
11
11
|
class TestDatafile < MiniTest::Test
|
12
12
|
|
13
|
+
|
13
14
|
def test_exclude
|
14
|
-
assert Datafile.match_exclude( '.build/' )
|
15
|
-
assert Datafile.match_exclude( '.git/' )
|
15
|
+
assert Datafile::Package.match_exclude?( '.build/' )
|
16
|
+
assert Datafile::Package.match_exclude?( '.git/' )
|
17
|
+
assert Datafile::Package.exclude?( '.build/' )
|
18
|
+
assert Datafile::Package.exclude?( '.git/' )
|
16
19
|
|
17
|
-
assert Datafile.match_exclude( '/.build/' )
|
18
|
-
assert Datafile.match_exclude( '/.git/' )
|
19
20
|
|
20
|
-
assert Datafile.match_exclude( '
|
21
|
-
assert Datafile.match_exclude( '
|
21
|
+
assert Datafile::Package.match_exclude?( '/.build/' )
|
22
|
+
assert Datafile::Package.match_exclude?( '/.git/' )
|
22
23
|
|
23
|
-
assert Datafile.match_exclude( '
|
24
|
-
assert Datafile.match_exclude( '
|
25
|
-
end
|
24
|
+
assert Datafile::Package.match_exclude?( '.build/leagues.txt' )
|
25
|
+
assert Datafile::Package.match_exclude?( '.git/leagues.txt' )
|
26
26
|
|
27
|
+
assert Datafile::Package.match_exclude?( '/.build/leagues.txt' )
|
28
|
+
assert Datafile::Package.match_exclude?( '/.git/leagues.txt' )
|
29
|
+
end
|
27
30
|
|
28
31
|
|
29
32
|
CLUBS_DIR = '../../../openfootball/clubs' ## source repo directory path
|
30
33
|
LEAGUES_DIR = '../../../openfootball/leagues'
|
31
|
-
AUSTRIA_DIR = '../../../openfootball/austria'
|
32
|
-
|
33
|
-
def test_find
|
34
|
-
datafiles = Datafile.find_clubs( CLUBS_DIR )
|
35
|
-
pp datafiles
|
36
|
-
|
37
|
-
datafiles = Datafile.find_clubs_wiki( CLUBS_DIR )
|
38
|
-
pp datafiles
|
39
|
-
|
40
|
-
datafiles = Datafile.find_leagues( LEAGUES_DIR )
|
41
|
-
pp datafiles
|
42
|
-
|
43
|
-
datafiles = Datafile.find_conf( AUSTRIA_DIR )
|
44
|
-
pp datafiles
|
45
|
-
end
|
46
|
-
|
47
34
|
|
48
35
|
def test_bundle
|
49
|
-
datafiles =
|
36
|
+
datafiles = SportDb::Package.find_clubs( CLUBS_DIR )
|
50
37
|
pp datafiles
|
51
38
|
|
52
|
-
Datafile.
|
53
|
-
|
54
|
-
|
39
|
+
## todo/fix: turn into Datafile::Bundle.new and Bundle#write/save -why? why not?
|
40
|
+
bundle = Datafile::Bundle.new( './tmp/clubs.txt' )
|
41
|
+
bundle.write <<TXT
|
55
42
|
##########################################
|
56
43
|
# auto-generated all-in-one single datafile clubs.txt bundle
|
57
44
|
# on #{Time.now} from #{datafiles.size} datafile(s)
|
58
45
|
TXT
|
46
|
+
bundle.write datafiles
|
47
|
+
bundle.close
|
48
|
+
end
|
59
49
|
|
60
|
-
|
50
|
+
def test_bundle_old
|
51
|
+
datafiles = SportDb::Package.find_leagues( LEAGUES_DIR )
|
61
52
|
pp datafiles
|
62
53
|
|
63
54
|
Datafile.write_bundle( './tmp/leagues.txt',
|
data/test/test_match.rb
CHANGED
@@ -25,12 +25,6 @@ class TestMatch < MiniTest::Test
|
|
25
25
|
m.update( round: 4 )
|
26
26
|
pp m
|
27
27
|
assert_equal 4, m.round
|
28
|
-
|
29
|
-
m = Match.create( team1: 'Team 1',
|
30
|
-
team2: 'Team 2',
|
31
|
-
round: 5 )
|
32
|
-
pp m
|
33
|
-
assert_equal 5, m.round
|
34
28
|
end # method test_round
|
35
29
|
|
36
30
|
end # class TestMatch
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
###
|
4
|
+
# to run use
|
5
|
+
# ruby -I ./lib -I ./test test/test_match_auto.rb
|
6
|
+
|
7
|
+
|
8
|
+
require 'helper'
|
9
|
+
|
10
|
+
|
11
|
+
class TestMatchAuto < MiniTest::Test
|
12
|
+
|
13
|
+
def test_pt
|
14
|
+
txt, exp = read_test( 'match_auto/pt/br.txt' )
|
15
|
+
|
16
|
+
teams, rounds = parse_auto_conf( txt, lang: 'pt' )
|
17
|
+
|
18
|
+
assert_equal exp['teams'], teams.deep_stringify_keys
|
19
|
+
assert_equal exp['rounds'], rounds.deep_stringify_keys
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def test_de
|
24
|
+
txt, exp = read_test( 'match_auto/de/at.txt' )
|
25
|
+
|
26
|
+
teams, rounds = parse_auto_conf( txt, lang: 'de' )
|
27
|
+
|
28
|
+
assert_equal exp['teams'], teams.deep_stringify_keys
|
29
|
+
assert_equal exp['rounds'], rounds.deep_stringify_keys
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_es
|
33
|
+
%w[match_auto/es/es.txt
|
34
|
+
match_auto/es/mx.txt
|
35
|
+
].each do |path|
|
36
|
+
txt, exp = read_test( path )
|
37
|
+
|
38
|
+
puts "testing match auto conf #{path}..."
|
39
|
+
teams, rounds = parse_auto_conf( txt, lang: 'es' )
|
40
|
+
|
41
|
+
assert_equal exp['teams'], teams.deep_stringify_keys
|
42
|
+
assert_equal exp['rounds'], rounds.deep_stringify_keys
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def test_fr
|
48
|
+
txt, exp = read_test( 'match_auto/fr/fr.txt' )
|
49
|
+
|
50
|
+
teams, rounds = parse_auto_conf( txt, lang: 'fr' )
|
51
|
+
|
52
|
+
assert_equal exp['teams'], teams.deep_stringify_keys
|
53
|
+
assert_equal exp['rounds'], rounds.deep_stringify_keys
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
def test_en
|
58
|
+
%w[match_auto/eng.txt
|
59
|
+
match_auto/eng_ii.txt
|
60
|
+
match_auto/mu.txt
|
61
|
+
].each do |path|
|
62
|
+
txt, exp = read_test( path )
|
63
|
+
|
64
|
+
puts "testing match auto conf #{path}..."
|
65
|
+
teams, rounds = parse_auto_conf( txt )
|
66
|
+
|
67
|
+
assert_equal exp['teams'], teams.deep_stringify_keys
|
68
|
+
assert_equal exp['rounds'], rounds.deep_stringify_keys
|
69
|
+
end
|
70
|
+
end # method test_parse
|
71
|
+
|
72
|
+
end # class TestMatchAuto
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
###
|
4
|
+
# to run use
|
5
|
+
# ruby -I ./lib -I ./test test/test_match_auto_champs.rb
|
6
|
+
|
7
|
+
|
8
|
+
require 'helper'
|
9
|
+
|
10
|
+
|
11
|
+
class TestMatchAutoChamps < MiniTest::Test
|
12
|
+
|
13
|
+
def test_champs_group
|
14
|
+
txt, exp = read_test( 'match_auto/champs_group.txt')
|
15
|
+
|
16
|
+
teams, rounds, groups, round_defs, group_defs = parse_auto_conf( txt, lang: 'en' )
|
17
|
+
|
18
|
+
assert_equal exp['teams'], teams.deep_stringify_keys
|
19
|
+
assert_equal exp['rounds'], rounds.deep_stringify_keys
|
20
|
+
assert_equal exp['groups'], groups.deep_stringify_keys
|
21
|
+
|
22
|
+
puts "teams:"
|
23
|
+
pp teams
|
24
|
+
puts "rounds:"
|
25
|
+
pp rounds
|
26
|
+
puts "groups:"
|
27
|
+
pp groups
|
28
|
+
puts "round defs:"
|
29
|
+
pp round_defs
|
30
|
+
puts "group defs:"
|
31
|
+
pp group_defs
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_champs_finals
|
35
|
+
txt, exp = read_test( 'match_auto/champs_finals.txt')
|
36
|
+
|
37
|
+
teams, rounds = parse_auto_conf( txt, lang: 'en' )
|
38
|
+
|
39
|
+
assert_equal exp['teams'], teams.deep_stringify_keys
|
40
|
+
assert_equal exp['rounds'], rounds.deep_stringify_keys
|
41
|
+
|
42
|
+
pp teams
|
43
|
+
pp rounds
|
44
|
+
end
|
45
|
+
end # class TestMatchAutChamps
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
###
|
4
|
+
# to run use
|
5
|
+
# ruby -I ./lib -I ./test test/test_match_auto_euro.rb
|
6
|
+
|
7
|
+
|
8
|
+
require 'helper'
|
9
|
+
|
10
|
+
|
11
|
+
class TestMatchAutoEuro < MiniTest::Test
|
12
|
+
|
13
|
+
def test_euro_2016
|
14
|
+
txt, exp = read_test( 'match_auto/euro_2016.txt')
|
15
|
+
|
16
|
+
teams, rounds, groups, round_defs, group_defs = parse_auto_conf( txt, lang: 'en' )
|
17
|
+
|
18
|
+
# puts JSON.pretty_generate( { teams: teams,
|
19
|
+
# rounds: rounds,
|
20
|
+
# groups: groups } )
|
21
|
+
|
22
|
+
assert_equal exp['teams'], teams.deep_stringify_keys
|
23
|
+
assert_equal exp['rounds'], rounds.deep_stringify_keys
|
24
|
+
assert_equal exp['groups'], groups.deep_stringify_keys
|
25
|
+
|
26
|
+
puts "teams:"
|
27
|
+
pp teams
|
28
|
+
puts "rounds:"
|
29
|
+
pp rounds
|
30
|
+
puts "groups:"
|
31
|
+
pp groups
|
32
|
+
puts "round defs:"
|
33
|
+
pp round_defs
|
34
|
+
puts "group defs:"
|
35
|
+
pp group_defs
|
36
|
+
end
|
37
|
+
end # class TestMatchAutoEuro
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
###
|
4
|
+
# to run use
|
5
|
+
# ruby -I ./lib -I ./test test/test_match_auto_worldcup.rb
|
6
|
+
|
7
|
+
|
8
|
+
require 'helper'
|
9
|
+
|
10
|
+
|
11
|
+
class TestMatchAutoWorldCup < MiniTest::Test
|
12
|
+
|
13
|
+
def test_2018
|
14
|
+
txt, exp = read_test( 'match_auto/worldcup_2018.txt')
|
15
|
+
|
16
|
+
start = Date.new( 2018, 1, 1 )
|
17
|
+
|
18
|
+
teams, rounds, groups, round_defs, group_defs = parse_auto_conf( txt, lang: 'en', start: start )
|
19
|
+
|
20
|
+
# puts JSON.pretty_generate( { teams: teams,
|
21
|
+
# rounds: rounds,
|
22
|
+
# groups: groups } )
|
23
|
+
|
24
|
+
assert_equal exp['teams'], teams.deep_stringify_keys
|
25
|
+
assert_equal exp['groups'], groups.deep_stringify_keys
|
26
|
+
|
27
|
+
puts "teams:"
|
28
|
+
pp teams
|
29
|
+
puts "rounds:"
|
30
|
+
pp rounds
|
31
|
+
puts "groups:"
|
32
|
+
pp groups
|
33
|
+
puts "round defs:"
|
34
|
+
pp round_defs
|
35
|
+
puts "group defs:"
|
36
|
+
pp group_defs
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_2018_finals
|
40
|
+
txt, exp = read_test( 'match_auto/worldcup_2018_finals.txt')
|
41
|
+
|
42
|
+
start = Date.new( 2018, 1, 1 )
|
43
|
+
|
44
|
+
teams, rounds, groups, round_defs, group_defs = parse_auto_conf( txt, lang: 'en', start: start )
|
45
|
+
|
46
|
+
assert_equal exp['teams'], teams.deep_stringify_keys
|
47
|
+
assert_equal exp['rounds'], rounds.deep_stringify_keys
|
48
|
+
|
49
|
+
puts "teams:"
|
50
|
+
pp teams
|
51
|
+
puts "rounds:"
|
52
|
+
pp rounds
|
53
|
+
puts "groups:"
|
54
|
+
pp groups
|
55
|
+
puts "round defs:"
|
56
|
+
pp round_defs
|
57
|
+
puts "group defs:"
|
58
|
+
pp group_defs
|
59
|
+
end
|
60
|
+
|
61
|
+
end # class TestMatchAutoWorldCup
|