fifadat 0.0.1
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 +7 -0
- data/CHANGELOG.md +4 -0
- data/Manifest.txt +91 -0
- data/README.md +24 -0
- data/Rakefile +32 -0
- data/bin/fifadat +14 -0
- data/lib/fifadat/api-config.rb +120 -0
- data/lib/fifadat/api.rb +110 -0
- data/lib/fifadat/config/codes_club-europe.csv +59 -0
- data/lib/fifadat/config/codes_club.csv +41 -0
- data/lib/fifadat/config/codes_nati.csv +6 -0
- data/lib/fifadat/config/seasons/ar.csv +7 -0
- data/lib/fifadat/config/seasons/at.csv +7 -0
- data/lib/fifadat/config/seasons/at.cup.csv +5 -0
- data/lib/fifadat/config/seasons/au.csv +7 -0
- data/lib/fifadat/config/seasons/be.csv +7 -0
- data/lib/fifadat/config/seasons/br.csv +6 -0
- data/lib/fifadat/config/seasons/ch.csv +7 -0
- data/lib/fifadat/config/seasons/clubworldcup.csv +2 -0
- data/lib/fifadat/config/seasons/cn.csv +7 -0
- data/lib/fifadat/config/seasons/co.csv +7 -0
- data/lib/fifadat/config/seasons/copa.l.csv +7 -0
- data/lib/fifadat/config/seasons/copa.s.csv +7 -0
- data/lib/fifadat/config/seasons/cz.csv +7 -0
- data/lib/fifadat/config/seasons/de.2.csv +6 -0
- data/lib/fifadat/config/seasons/de.csv +7 -0
- data/lib/fifadat/config/seasons/de.cup.csv +6 -0
- data/lib/fifadat/config/seasons/eg.csv +6 -0
- data/lib/fifadat/config/seasons/eng.2.csv +7 -0
- data/lib/fifadat/config/seasons/eng.csv +7 -0
- data/lib/fifadat/config/seasons/eng.facup.csv +6 -0
- data/lib/fifadat/config/seasons/es.csv +6 -0
- data/lib/fifadat/config/seasons/fr.csv +6 -0
- data/lib/fifadat/config/seasons/gr.csv +7 -0
- data/lib/fifadat/config/seasons/hu.csv +6 -0
- data/lib/fifadat/config/seasons/ie.csv +6 -0
- data/lib/fifadat/config/seasons/il.csv +6 -0
- data/lib/fifadat/config/seasons/interconticup.csv +24 -0
- data/lib/fifadat/config/seasons/is.csv +6 -0
- data/lib/fifadat/config/seasons/it.csv +7 -0
- data/lib/fifadat/config/seasons/it.cup.csv +5 -0
- data/lib/fifadat/config/seasons/jp.csv +7 -0
- data/lib/fifadat/config/seasons/kr.csv +7 -0
- data/lib/fifadat/config/seasons/lu.csv +3 -0
- data/lib/fifadat/config/seasons/ma.csv +3 -0
- data/lib/fifadat/config/seasons/mls.csv +6 -0
- data/lib/fifadat/config/seasons/mx.2.csv +5 -0
- data/lib/fifadat/config/seasons/mx.csv +6 -0
- data/lib/fifadat/config/seasons/mx.cup.csv +3 -0
- data/lib/fifadat/config/seasons/nir.csv +6 -0
- data/lib/fifadat/config/seasons/nl.csv +7 -0
- data/lib/fifadat/config/seasons/no.csv +6 -0
- data/lib/fifadat/config/seasons/pl.csv +6 -0
- data/lib/fifadat/config/seasons/pt.csv +7 -0
- data/lib/fifadat/config/seasons/sa.csv +7 -0
- data/lib/fifadat/config/seasons/sco.csv +7 -0
- data/lib/fifadat/config/seasons/se.csv +7 -0
- data/lib/fifadat/config/seasons/tn.csv +6 -0
- data/lib/fifadat/config/seasons/tr.csv +7 -0
- data/lib/fifadat/config/seasons/uefa.cl.csv +7 -0
- data/lib/fifadat/config/seasons/uefa.con.csv +6 -0
- data/lib/fifadat/config/seasons/uefa.europa.csv +6 -0
- data/lib/fifadat/config/seasons/uy.csv +6 -0
- data/lib/fifadat/config/seasons/wal.csv +6 -0
- data/lib/fifadat/config/seasons/worldcup.csv +24 -0
- data/lib/fifadat/config/seasons/za.csv +6 -0
- data/lib/fifadat/errata.rb +59 -0
- data/lib/fifadat/helper.rb +46 -0
- data/lib/fifadat/json.rb +113 -0
- data/lib/fifadat/pp/build_match.rb +105 -0
- data/lib/fifadat/pp/build_report.rb +135 -0
- data/lib/fifadat/pp/convert-reports.rb +114 -0
- data/lib/fifadat/pp/convert.rb +163 -0
- data/lib/fifadat/pp/goals-calc_score.rb +58 -0
- data/lib/fifadat/pp/goals.rb +89 -0
- data/lib/fifadat/pp/helper-date.rb +13 -0
- data/lib/fifadat/pp/helper-minute.rb +81 -0
- data/lib/fifadat/pp/helper-score.rb +139 -0
- data/lib/fifadat/pp/norm.rb +34 -0
- data/lib/fifadat/pp/officials.rb +86 -0
- data/lib/fifadat/pp/penalties.rb +132 -0
- data/lib/fifadat/pp/players.rb +323 -0
- data/lib/fifadat/pp/stadiums.rb +99 -0
- data/lib/fifadat/pp/stages.rb +119 -0
- data/lib/fifadat/pp/substitutions.rb +444 -0
- data/lib/fifadat/pp/teams.rb +91 -0
- data/lib/fifadat/ppdebug.rb +128 -0
- data/lib/fifadat/ppmatch.rb +78 -0
- data/lib/fifadat/prepare.rb +117 -0
- data/lib/fifadat/tool.rb +184 -0
- data/lib/fifadat/types.rb +166 -0
- data/lib/fifadat.rb +54 -0
- metadata +215 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
## todo/check:
|
|
4
|
+
## use: fomat: full/fuller, short/long or such - why? why not?
|
|
5
|
+
def pp_match( m, season: false )
|
|
6
|
+
|
|
7
|
+
competitionName = desc( m['CompetitionName'])
|
|
8
|
+
seasonName = desc( m['SeasonName'])
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
idCompetition = m['IdCompetition']
|
|
12
|
+
idSeason = m['IdSeason']
|
|
13
|
+
idStage = m['IdStage']
|
|
14
|
+
idMatch = m['IdMatch']
|
|
15
|
+
|
|
16
|
+
stageName = desc( m['StageName'] )
|
|
17
|
+
groupName = desc( m['GroupName'] ) # optional
|
|
18
|
+
matchDay = m['MatchDay'] # optional
|
|
19
|
+
|
|
20
|
+
matchNumber = m['MatchNumber'] # optional
|
|
21
|
+
|
|
22
|
+
team1 = m['Home'] ? { name: desc( m['Home']['TeamName'] ),
|
|
23
|
+
abbrev: m['Home']['Abbreviation'],
|
|
24
|
+
country: m['Home']['IdCountry'],
|
|
25
|
+
}
|
|
26
|
+
: { name: '?', abbrev: '?', country: '?' }
|
|
27
|
+
|
|
28
|
+
team2 = m['Away'] ? { name: desc( m['Away']['TeamName'] ),
|
|
29
|
+
abbrev: m['Away']['Abbreviation'],
|
|
30
|
+
country: m['Away']['IdCountry'],
|
|
31
|
+
}
|
|
32
|
+
: { name: '?', abbrev: '?', country: '?' }
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
matchStatus = m['MatchStatus']
|
|
36
|
+
resultType = m['ResultType']
|
|
37
|
+
|
|
38
|
+
## add aggregate score too
|
|
39
|
+
score = [m['HomeTeamScore'], m['AwayTeamScore']].compact
|
|
40
|
+
penScore = [m['HomeTeamPenaltyScore'], m['AwayTeamPenaltyScore']].compact
|
|
41
|
+
aggScore = [m['AggregateHomeTeamScore'],m['AggregateAwayTeamScore']].compact
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
buf = String.new
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
if season
|
|
49
|
+
## beautify
|
|
50
|
+
## possible rm competitionName from season
|
|
51
|
+
|
|
52
|
+
seasonNameAlt = seasonName.sub( competitionName, '').gsub( /[ ]{2,}/,' ').strip
|
|
53
|
+
buf << "== #{competitionName}"
|
|
54
|
+
buf << " | #{seasonNameAlt}"
|
|
55
|
+
buf << "\n"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
buf << "#{matchStatus}-#{MATCH_STATUS[matchStatus]||'??'} "
|
|
60
|
+
buf << " ▪ #{stageName}"
|
|
61
|
+
buf << ", #{groupName}" if groupName
|
|
62
|
+
buf << " - #{matchDay}" if matchDay
|
|
63
|
+
buf << " (#{matchNumber})" if matchNumber
|
|
64
|
+
|
|
65
|
+
buf << " #{team1[:name]} | #{team1[:abbrev]} (#{team1[:country]})"
|
|
66
|
+
buf << " v "
|
|
67
|
+
buf << "#{team2[:name]} | #{team2[:abbrev]} (#{team2[:country]}) "
|
|
68
|
+
buf << "\n"
|
|
69
|
+
|
|
70
|
+
buf << " "
|
|
71
|
+
buf << " (#{resultType}-#{RESULT_TYPE[resultType]||'??'})"
|
|
72
|
+
buf << " score: #{score.inspect}" unless score.empty?
|
|
73
|
+
buf << " pen: #{penScore.inspect}" unless penScore.empty?
|
|
74
|
+
buf << " agg: #{aggScore.inspect}" unless aggScore.empty?
|
|
75
|
+
buf << "\n"
|
|
76
|
+
|
|
77
|
+
buf
|
|
78
|
+
end
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
###
|
|
2
|
+
# get matches and stages per season
|
|
3
|
+
##
|
|
4
|
+
## download / prepare (fill-up local) cache
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def prepare( name:,
|
|
8
|
+
season:,
|
|
9
|
+
outdir: '.',
|
|
10
|
+
force: false )
|
|
11
|
+
|
|
12
|
+
###
|
|
13
|
+
### rename name to slug or such
|
|
14
|
+
## e.g. worldcup, clubworldcup, interconticup or such expected!!!
|
|
15
|
+
|
|
16
|
+
season = Season(season)
|
|
17
|
+
|
|
18
|
+
idComp = Fifa._idComp_by!( name: name )
|
|
19
|
+
|
|
20
|
+
idSeason = Fifa._idSeason_by!( name: name, season: season )
|
|
21
|
+
|
|
22
|
+
fetch_json_if( Fifa::Metal.matches_url( idSeason: idSeason ),
|
|
23
|
+
"#{outdir}/#{name}/#{season.to_path}_matches.json", force: force )
|
|
24
|
+
|
|
25
|
+
fetch_json_if( Fifa::Metal.stages_url( idSeason: idSeason ),
|
|
26
|
+
"#{outdir}/#{name}/misc/#{season.to_path}_stages.json", force: force )
|
|
27
|
+
|
|
28
|
+
fetch_json_if( Fifa::Metal.squads_url( idCompetition: idComp,
|
|
29
|
+
idSeason: idSeason ),
|
|
30
|
+
"#{outdir}/#{name}/misc/#{season.to_path}_squads.json", force: force )
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def prepare_reports( name:,
|
|
37
|
+
season:,
|
|
38
|
+
outdir: '.',
|
|
39
|
+
force: false )
|
|
40
|
+
|
|
41
|
+
## download match reports (via live/football)
|
|
42
|
+
season = Season(season)
|
|
43
|
+
|
|
44
|
+
data = read_json( "#{outdir}/#{name}/#{season.to_path}_matches.json" )
|
|
45
|
+
matches = data['Results']
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
puts " #{matches.size} match(es) in season #{season}"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
matches.each_with_index do |m, i|
|
|
52
|
+
idCompetition = m['IdCompetition']
|
|
53
|
+
idSeason = m['IdSeason']
|
|
54
|
+
idStage = m['IdStage']
|
|
55
|
+
idMatch = m['IdMatch']
|
|
56
|
+
|
|
57
|
+
stageName = desc( m['StageName'] )
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
## note - skip if teams not yet know
|
|
61
|
+
## e.g. Home & Away is null
|
|
62
|
+
## e.g. "Home": null,
|
|
63
|
+
## "Away": null,
|
|
64
|
+
|
|
65
|
+
## todo/fix - check for MatchStatus and ResultType too
|
|
66
|
+
## e.g. MatchStatus = 1 -- future
|
|
67
|
+
## ResultType = 0 -- not played yet
|
|
68
|
+
|
|
69
|
+
if m['Home'].nil? || m['Away'].nil?
|
|
70
|
+
puts "[#{i+1}/#{matches.size}] ?? ??, #{stageName} (SKIPPED - TO BE DONE)"
|
|
71
|
+
next
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
dateTime = parse_date( m['Date'] ) ## utc
|
|
76
|
+
localDateTime = parse_date( m['LocalDate'] )
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
## pp m['Home']
|
|
80
|
+
teamName1 = desc( m['Home']['TeamName'] )
|
|
81
|
+
teamCode1 = m['Home']['Abbreviation']
|
|
82
|
+
|
|
83
|
+
## pp m['Away']
|
|
84
|
+
teamName2 = desc( m['Away']['TeamName'] )
|
|
85
|
+
teamCode2 = m['Away']['Abbreviation']
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
puts "[#{i+1}/#{matches.size}] #{teamName1} #{teamName2}, #{stageName}, #{localDateTime}"
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
outpath = "#{outdir}/#{name}/matches/#{season.to_path}/#{localDateTime.strftime('%Y-%m-%d')}_#{teamCode1}-#{teamCode2}__#{idMatch}.json"
|
|
92
|
+
|
|
93
|
+
url = Fifa::Metal.live_url( idCompetition: idCompetition,
|
|
94
|
+
idSeason: idSeason,
|
|
95
|
+
idStage: idStage,
|
|
96
|
+
idMatch: idMatch )
|
|
97
|
+
|
|
98
|
+
fetch_json_if( url, outpath, force: force )
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
###
|
|
102
|
+
## add timeline (only) if score incl. penalty shoot-out
|
|
103
|
+
resultType = m['ResultType']
|
|
104
|
+
if resultType == 2 ## (aet??) win on pens
|
|
105
|
+
|
|
106
|
+
## download timeline
|
|
107
|
+
outpath = "#{outdir}/#{name}/timelines/#{season.to_path}/#{localDateTime.strftime('%Y-%m-%d')}_#{teamCode1}-#{teamCode2}__#{idMatch}.json"
|
|
108
|
+
|
|
109
|
+
url = Fifa::Metal.timeline_url( idCompetition: idCompetition,
|
|
110
|
+
idSeason: idSeason,
|
|
111
|
+
idStage: idStage,
|
|
112
|
+
idMatch: idMatch )
|
|
113
|
+
|
|
114
|
+
fetch_json_if( url, outpath, force: force )
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
data/lib/fifadat/tool.rb
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
module Fifadat
|
|
4
|
+
|
|
5
|
+
def self.main( args=ARGV )
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
opts = {
|
|
9
|
+
season: nil,
|
|
10
|
+
file: nil,
|
|
11
|
+
force: false,
|
|
12
|
+
offline: false,
|
|
13
|
+
reports: true,
|
|
14
|
+
|
|
15
|
+
cache_dir: '/sports/cache.fifadat',
|
|
16
|
+
convert_dir: '/sports/cache.api.fifa',
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
parser = OptionParser.new do |parser|
|
|
21
|
+
parser.banner = "Usage: #{$PROGRAM_NAME} [options] NAME"
|
|
22
|
+
## add options here
|
|
23
|
+
parser.on( "--season=SEASON",
|
|
24
|
+
"season" ) do |season|
|
|
25
|
+
opts[:season] = season
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
parser.on( "--cache", "--cached", "--offline",
|
|
30
|
+
"always (and only) use cached data in >#{opts[:cache_dir]}< - default is (#{opts[:offline]})" ) do |offline|
|
|
31
|
+
opts[:offline] = offline
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
parser.on( "--force",
|
|
35
|
+
"always (force) download fresh copy & overwrite - default is (#{opts[:force]})" ) do |force|
|
|
36
|
+
opts[:force] = force
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
parser.on( "--[no-]reports",
|
|
40
|
+
"incl. one-by-one (detailed) match reports - default is (#{opts[:reports]})" ) do |reports|
|
|
41
|
+
opts[:reports] = reports
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
parser.on( "-f FILE", "--file FILE",
|
|
47
|
+
"read leagues (and seasons) via .csv file") do |file|
|
|
48
|
+
opts[:file] = file
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
parser.parse!( args )
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
puts "OPTS:"
|
|
58
|
+
pp opts
|
|
59
|
+
puts "ARGV:"
|
|
60
|
+
pp args
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
cache_dir = opts[:cache_dir]
|
|
64
|
+
convert_dir = opts[:convert_dir]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
if opts[:file]
|
|
69
|
+
recs = read_csv( opts[:file] )
|
|
70
|
+
else
|
|
71
|
+
|
|
72
|
+
## otherwise
|
|
73
|
+
## build rec(ord)s from scratch (from command-line args)
|
|
74
|
+
if args.size == 0
|
|
75
|
+
puts " NAME argument (plus season opt) required; use:"
|
|
76
|
+
Fifa::CODES.each do |code, h|
|
|
77
|
+
idCompetition = h[:idCompetition]
|
|
78
|
+
comp = Fifa::COMPETITIONS[idCompetition]
|
|
79
|
+
seasons = comp.values.map { |c| c[:season] }
|
|
80
|
+
puts " #{code} (#{seasons.size}) #{seasons.join(',')}"
|
|
81
|
+
end
|
|
82
|
+
exit 1
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
##
|
|
87
|
+
## note - all args other than first ignored for now; issue warn - why? why not?
|
|
88
|
+
rec = {}
|
|
89
|
+
rec['league'] = args[0].downcase
|
|
90
|
+
rec['seasons'] = Season.parse(opts[:season]).to_s
|
|
91
|
+
recs = [rec]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
pp recs
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
################
|
|
98
|
+
## step 0) validate slugs & seasons
|
|
99
|
+
recs.each do |rec|
|
|
100
|
+
slug = rec['league']
|
|
101
|
+
seasons = Season.parse_line( rec['seasons'] )
|
|
102
|
+
seasons.each do |season|
|
|
103
|
+
pp Fifa._idSeason_by!( name: slug, season: season )
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
if opts[:offline] == false
|
|
109
|
+
## step 1a) prepare
|
|
110
|
+
recs.each do |rec|
|
|
111
|
+
slug = rec['league']
|
|
112
|
+
seasons = Season.parse_line( rec['seasons'] )
|
|
113
|
+
seasons.each do |season|
|
|
114
|
+
|
|
115
|
+
prepare( name: slug,
|
|
116
|
+
season: season,
|
|
117
|
+
outdir: cache_dir,
|
|
118
|
+
force: opts[:force] ) ## note - autoadd slug (name) e..g ./eng !!
|
|
119
|
+
|
|
120
|
+
=begin
|
|
121
|
+
###
|
|
122
|
+
## add debug
|
|
123
|
+
page = String.new
|
|
124
|
+
page << "= #{slug} #{season}\n"
|
|
125
|
+
page << "# generated on #{Time.now}\n"
|
|
126
|
+
page << "\n"
|
|
127
|
+
|
|
128
|
+
buf = pp_debug( slug: slug, season: season,
|
|
129
|
+
indir: cache_dir )
|
|
130
|
+
|
|
131
|
+
page << buf
|
|
132
|
+
puts page
|
|
133
|
+
|
|
134
|
+
outpath = "#{convert_dir}/#{season.to_path}_#{slug}-debug.txt"
|
|
135
|
+
|
|
136
|
+
write_text( outpath, page )
|
|
137
|
+
puts " written to >#{outpath}<"
|
|
138
|
+
=end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
if opts[:reports]
|
|
143
|
+
## step 1b) prepare details
|
|
144
|
+
recs.each do |rec|
|
|
145
|
+
slug = rec['league']
|
|
146
|
+
seasons = Season.parse_line( rec['seasons'] )
|
|
147
|
+
seasons.each do |season|
|
|
148
|
+
## match (reports) one-by-one
|
|
149
|
+
prepare_reports( name: slug,
|
|
150
|
+
season: season,
|
|
151
|
+
outdir: cache_dir, ## note - autoadd slug (name) e..g ./eng !!
|
|
152
|
+
force: opts[:force] )
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end # if reports
|
|
156
|
+
end ## if online (offline==false)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
## step 2) convert
|
|
162
|
+
recs.each do |rec|
|
|
163
|
+
slug = rec['league']
|
|
164
|
+
seasons = Season.parse_line( rec['seasons'] )
|
|
165
|
+
seasons.each do |season|
|
|
166
|
+
|
|
167
|
+
convert( slug: slug, season: season,
|
|
168
|
+
indir: cache_dir,
|
|
169
|
+
outdir: convert_dir )
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
## convert all match reports one-by-one
|
|
173
|
+
convert_reports( slug: slug, season: season,
|
|
174
|
+
indir: cache_dir,
|
|
175
|
+
outdir: convert_dir )
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
puts "bye"
|
|
180
|
+
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
end # module Fifadat
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
|
|
2
|
+
##
|
|
3
|
+
## help - yes, you can.
|
|
4
|
+
## if you have any more info about the fifa types,
|
|
5
|
+
## please tell and help fill-in the details.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
MATCH_STATUS = {
|
|
10
|
+
0 => 'FIN', # finished
|
|
11
|
+
1 => 'SCHED', # scheduled (with or without time - see timed flag)
|
|
12
|
+
2 => 'LIVE',
|
|
13
|
+
|
|
14
|
+
## ???
|
|
15
|
+
|
|
16
|
+
7 => 'POSTPONED', # postponed
|
|
17
|
+
|
|
18
|
+
9 => 'AWD', # awarded !!!
|
|
19
|
+
# check if 9/0 is possibly cancelled/annulled (if no score)
|
|
20
|
+
# 9/12 (AWD 3-0 or such)
|
|
21
|
+
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
## "MatchStatus"=>9, cancelled!!!!
|
|
27
|
+
##
|
|
28
|
+
## "ResultType"=>12,
|
|
29
|
+
## 21:30 CD Independiente Medellín (COL) v CR Flamengo (BRA) [cancelled]
|
|
30
|
+
##
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
## Result: Al Duhail awarded a 3–0 walkover victory.
|
|
34
|
+
## Reason: Auckland City FC withdrew from the tournament
|
|
35
|
+
## due to strict COVID-19 pandemic quarantine and isolation measures
|
|
36
|
+
## enforced by New Zealand authorities.
|
|
37
|
+
|
|
38
|
+
##
|
|
39
|
+
## check 2 is only win on pens!!!
|
|
40
|
+
## might be WITHOUT extra time e.g. copa liber.
|
|
41
|
+
## [28/142] 0-FIN 3rd Round Sporting Cristal | SCL (PER) v Carabobo FC | CRB (VEN)
|
|
42
|
+
## (2-AET_WIN_ON_PENS) score: [1, 2] pen: [3, 2] agg: [2, 2]
|
|
43
|
+
## and others!!!
|
|
44
|
+
##
|
|
45
|
+
## how to check if extra time was played?? (use period??)
|
|
46
|
+
|
|
47
|
+
# resultType
|
|
48
|
+
# 0 => no result / not played yet
|
|
49
|
+
# 1 => regular (90 mins)
|
|
50
|
+
# 2 => aet (120 mins), win on pens
|
|
51
|
+
# 3 => aet (120 mins)
|
|
52
|
+
# 8 => same as 3? -aet with golden goal/silver goal in 1998 FRA-PAR
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
RESULT_TYPE = {
|
|
57
|
+
0 => 'NO',
|
|
58
|
+
1 => 'REGULAR',
|
|
59
|
+
## note - cannot tell if
|
|
60
|
+
## win on penalties
|
|
61
|
+
## is after extra-time!!!
|
|
62
|
+
## used many times in copa libertadores
|
|
63
|
+
## check gold cup too
|
|
64
|
+
2 => 'AET_WIN_ON_PENS', ## or REG_WIN_ON_PENS or AGG_WIN_ON_PENS !!!!!!
|
|
65
|
+
3 => 'AET',
|
|
66
|
+
##
|
|
67
|
+
## note - agg - used for 1st & 2nd leg
|
|
68
|
+
4 => 'REGULAR/AGG', ## aggregate (1st/2nd leg) - regular
|
|
69
|
+
5 => 'AET/AGG', ## aggregate - after extra-time
|
|
70
|
+
## e.g.
|
|
71
|
+
## 2nd LegFeb 25, 2026 Juventus 3–2 (AET) Galatasaray
|
|
72
|
+
##
|
|
73
|
+
8 => 'AET/GG', ## after extra-time/golden goal !!!
|
|
74
|
+
|
|
75
|
+
12 => 'AWD', ## AWARDED
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
GOAL_TYPE = {
|
|
80
|
+
1 => 'PENALTY',
|
|
81
|
+
2 => 'REGULAR',
|
|
82
|
+
3 => 'OWN_GOAL',
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
PERIOD_TYPE = {
|
|
87
|
+
## "MatchMinute": "0'", "1'", "45'+2'",
|
|
88
|
+
3 => '1ST_HALF',
|
|
89
|
+
## "MatchMinute": "46'", "90'+2'",
|
|
90
|
+
5 => '2ND_HALF',
|
|
91
|
+
## "MatchMinute": "91'", "105'+2'",
|
|
92
|
+
7 => 'EXTRA_TIME_1ST_HALF',
|
|
93
|
+
## "MatchMinute": "106'", "120'+2'",
|
|
94
|
+
9 => 'EXTRA_TIME_2ND_HALF',
|
|
95
|
+
## "MatchMinute": "120'", "121'", "122'", "123'",
|
|
96
|
+
11 => 'PENALTY_SHOOTOUT',
|
|
97
|
+
## "MatchMinute": "127'", "130'",
|
|
98
|
+
10 => 'MATCH_END'
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
=begin
|
|
102
|
+
"MatchMinute": "1'",
|
|
103
|
+
"Period": 0, !!!!
|
|
104
|
+
"MatchMinute": "91'",
|
|
105
|
+
"Period": 0, !!!
|
|
106
|
+
=end
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
EVENT_TYPE = {
|
|
110
|
+
0 => 'Goal!', ## e.g. DI MARÍA (Argentina) scores!!
|
|
111
|
+
1 => 'Assist', ## e.g. Assisted by MAC ALLISTER.
|
|
112
|
+
2 => 'Yellow card', ## e.g. FERNÁNDEZ (Argentina) is booked by the referee.
|
|
113
|
+
3 => 'Red card', ## e.g. Zinedine ZIDANE (France) is sent off
|
|
114
|
+
|
|
115
|
+
5 => 'Substitution', ## e.g. ACUÑA (in) comes off the bench to replace DI MARÍA (out) (Argentina)
|
|
116
|
+
6 => 'Penalty Awarded',
|
|
117
|
+
7 => 'Start Time', ## e.g. The referee signals the start of the first period.
|
|
118
|
+
8 => 'End Time', ## e.g. 'The referee brings the first period to an end.
|
|
119
|
+
|
|
120
|
+
12 => 'Attempt at Goal',
|
|
121
|
+
|
|
122
|
+
15 => 'Offside',
|
|
123
|
+
16 => 'Corner',
|
|
124
|
+
18 => 'Foul',
|
|
125
|
+
19 => 'Coin Toss',
|
|
126
|
+
|
|
127
|
+
23 => 'Dropped Ball',
|
|
128
|
+
24 => 'Throw In',
|
|
129
|
+
25 => 'Clearance',
|
|
130
|
+
26 => 'Match end',
|
|
131
|
+
27 => 'Aerial Duel',
|
|
132
|
+
|
|
133
|
+
41 => 'Penalty Goal',
|
|
134
|
+
46 => 'Penalty missed', ## David TREZEGUET (France) rattles the crossbar from the spot!
|
|
135
|
+
51 => 'Penalty missed', ## JULIO CESAR (Brazil) hits the post from the spot!
|
|
136
|
+
60 => 'Penalty missed', ## COMAN (France) sees his penalty saved by the goalkeeper.
|
|
137
|
+
65 => 'Penalty missed', ## TCHOUAMENI (France) misses from the penalty spot!
|
|
138
|
+
## Michel PLATINI (France) misses from the penalty spot!
|
|
139
|
+
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
=begin
|
|
145
|
+
|
|
146
|
+
note - matchStatus for 12-AWD should also be 9-AWD!!!
|
|
147
|
+
|
|
148
|
+
resultType 12
|
|
149
|
+
The Clausura 2022 match between Querétaro and Atlas on March 5, 2022,
|
|
150
|
+
was officially suspended in the 62nd minute
|
|
151
|
+
and later recorded as a 3–0 victory for Atlas
|
|
152
|
+
: Atlas was leading 1–0 at the time of suspension.
|
|
153
|
+
Forfeit Victory: Atlas was officially awarded a 3–0 walkover win.
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
0 => no result / not played yet
|
|
157
|
+
1 => regular (90 mins)
|
|
158
|
+
2 => aet (120 mins), win on pens
|
|
159
|
+
3 => aet (120 mins)
|
|
160
|
+
|
|
161
|
+
8 => same as 3? -aet with golden goal/silver goal in 1998 FRA-PAR
|
|
162
|
+
|
|
163
|
+
4 => aggregate leg 1/2 ?? e.g.
|
|
164
|
+
"AggregateHomeTeamScore": 2,
|
|
165
|
+
"AggregateAwayTeamScore": 4,
|
|
166
|
+
=end
|
data/lib/fifadat.rb
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'cocos' ## check if incl webclient already?
|
|
2
|
+
require 'webclient'
|
|
3
|
+
|
|
4
|
+
require 'season-formats'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
require_relative 'fifadat/json' ## read_json_v2, fetch_json, fetch_json_if, etc.
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
###
|
|
14
|
+
## our own code
|
|
15
|
+
|
|
16
|
+
require_relative 'fifadat/api-config' ## base
|
|
17
|
+
require_relative 'fifadat/api' ## base
|
|
18
|
+
require_relative 'fifadat/helper'
|
|
19
|
+
require_relative 'fifadat/prepare' ## "all-in-one" prepare (download cache) helpers etc.
|
|
20
|
+
|
|
21
|
+
require_relative 'fifadat/ppdebug'
|
|
22
|
+
require_relative 'fifadat/ppmatch'
|
|
23
|
+
|
|
24
|
+
require_relative 'fifadat/types'
|
|
25
|
+
require_relative 'fifadat/errata'
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
#####
|
|
29
|
+
## more
|
|
30
|
+
require_relative 'fifadat/pp/norm'
|
|
31
|
+
|
|
32
|
+
require_relative 'fifadat/pp/stages'
|
|
33
|
+
require_relative 'fifadat/pp/teams'
|
|
34
|
+
require_relative 'fifadat/pp/stadiums'
|
|
35
|
+
require_relative 'fifadat/pp/players'
|
|
36
|
+
|
|
37
|
+
require_relative 'fifadat/pp/officials' ## aka referees
|
|
38
|
+
require_relative 'fifadat/pp/goals'
|
|
39
|
+
require_relative 'fifadat/pp/goals-calc_score'
|
|
40
|
+
require_relative 'fifadat/pp/penalties'
|
|
41
|
+
require_relative 'fifadat/pp/substitutions'
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
require_relative 'fifadat/pp/build_match'
|
|
45
|
+
require_relative 'fifadat/pp/build_report'
|
|
46
|
+
require_relative 'fifadat/pp/convert'
|
|
47
|
+
require_relative 'fifadat/pp/convert-reports'
|
|
48
|
+
|
|
49
|
+
require_relative 'fifadat/pp/helper-date'
|
|
50
|
+
require_relative 'fifadat/pp/helper-score'
|
|
51
|
+
require_relative 'fifadat/pp/helper-minute'
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
require_relative 'fifadat/tool' ## fifadat command-line tool
|