fifadat 0.0.1 → 2026.9.23
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/CHANGELOG.md +1 -0
- data/Manifest.txt +60 -83
- data/Rakefile +2 -2
- data/{lib/fifadat/config → config}/seasons/at.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/at.cup.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/au.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/be.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/ch.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/cz.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/de.2.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/de.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/de.cup.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/eg.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/eng.2.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/eng.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/eng.facup.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/es.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/fr.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/gr.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/hu.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/il.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/interconticup.csv +1 -1
- data/{lib/fifadat/config → config}/seasons/is.csv +1 -1
- data/{lib/fifadat/config → config}/seasons/it.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/it.cup.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/lu.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/ma.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/mx.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/nir.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/nl.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/pl.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/pt.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/sa.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/sco.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/tn.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/tr.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/uefa.cl.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/uefa.con.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/uefa.europa.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/wal.csv +1 -0
- data/{lib/fifadat/config → config}/seasons/za.csv +1 -0
- data/lib/fifadat/{api-config.rb → config.rb} +4 -9
- data/lib/fifadat/version.rb +19 -0
- data/lib/fifadat.rb +8 -36
- metadata +63 -87
- data/bin/fifadat +0 -14
- data/lib/fifadat/errata.rb +0 -59
- data/lib/fifadat/helper.rb +0 -46
- data/lib/fifadat/pp/build_match.rb +0 -105
- data/lib/fifadat/pp/build_report.rb +0 -135
- data/lib/fifadat/pp/convert-reports.rb +0 -114
- data/lib/fifadat/pp/convert.rb +0 -163
- data/lib/fifadat/pp/goals-calc_score.rb +0 -58
- data/lib/fifadat/pp/goals.rb +0 -89
- data/lib/fifadat/pp/helper-date.rb +0 -13
- data/lib/fifadat/pp/helper-minute.rb +0 -81
- data/lib/fifadat/pp/helper-score.rb +0 -139
- data/lib/fifadat/pp/norm.rb +0 -34
- data/lib/fifadat/pp/officials.rb +0 -86
- data/lib/fifadat/pp/penalties.rb +0 -132
- data/lib/fifadat/pp/players.rb +0 -323
- data/lib/fifadat/pp/stadiums.rb +0 -99
- data/lib/fifadat/pp/stages.rb +0 -119
- data/lib/fifadat/pp/substitutions.rb +0 -444
- data/lib/fifadat/pp/teams.rb +0 -91
- data/lib/fifadat/ppdebug.rb +0 -128
- data/lib/fifadat/ppmatch.rb +0 -78
- data/lib/fifadat/tool.rb +0 -184
- data/lib/fifadat/types.rb +0 -166
- /data/{lib/fifadat/config → config}/codes_club-europe.csv +0 -0
- /data/{lib/fifadat/config → config}/codes_club.csv +0 -0
- /data/{lib/fifadat/config → config}/codes_nati.csv +0 -0
- /data/{lib/fifadat/config → config}/seasons/ar.csv +0 -0
- /data/{lib/fifadat/config → config}/seasons/br.csv +0 -0
- /data/{lib/fifadat/config → config}/seasons/clubworldcup.csv +0 -0
- /data/{lib/fifadat/config → config}/seasons/cn.csv +0 -0
- /data/{lib/fifadat/config → config}/seasons/co.csv +0 -0
- /data/{lib/fifadat/config → config}/seasons/copa.l.csv +0 -0
- /data/{lib/fifadat/config → config}/seasons/copa.s.csv +0 -0
- /data/{lib/fifadat/config → config}/seasons/ie.csv +0 -0
- /data/{lib/fifadat/config → config}/seasons/jp.csv +0 -0
- /data/{lib/fifadat/config → config}/seasons/kr.csv +0 -0
- /data/{lib/fifadat/config → config}/seasons/mls.csv +0 -0
- /data/{lib/fifadat/config → config}/seasons/mx.2.csv +0 -0
- /data/{lib/fifadat/config → config}/seasons/mx.cup.csv +0 -0
- /data/{lib/fifadat/config → config}/seasons/no.csv +0 -0
- /data/{lib/fifadat/config → config}/seasons/se.csv +0 -0
- /data/{lib/fifadat/config → config}/seasons/uy.csv +0 -0
- /data/{lib/fifadat/config → config}/seasons/worldcup.csv +0 -0
data/lib/fifadat/pp/convert.rb
DELETED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def convert( slug:, season:,
|
|
5
|
-
indir: '.',
|
|
6
|
-
outdir: './tmp' )
|
|
7
|
-
|
|
8
|
-
season = Season(season)
|
|
9
|
-
|
|
10
|
-
## fix - change data to top or ??? - why? why not?
|
|
11
|
-
data = {}
|
|
12
|
-
|
|
13
|
-
## add slug & seasons (add name to be done!!)
|
|
14
|
-
data[:meta] = { slug: slug,
|
|
15
|
-
season: season.to_s,
|
|
16
|
-
generated: Time.now.to_s,
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
matches = read_json_v2( "#{indir}/#{slug}/#{season.to_path}_matches.json" )
|
|
21
|
-
matches = matches['Results'] ## only use results (match) array
|
|
22
|
-
|
|
23
|
-
## pp matches
|
|
24
|
-
puts " #{matches.size} match(es) in season #{season}"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
## read in stages
|
|
28
|
-
## incl. SequenceOrder, StageLevel (optional)
|
|
29
|
-
stages = Stages.read( "#{indir}/#{slug}/misc/#{season.to_path}_stages.json" )
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
stages.add_matches( matches )
|
|
33
|
-
data[:stages] = stages.as_json
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
teams = Teams.new
|
|
37
|
-
teams.add_matches( matches )
|
|
38
|
-
data[:teams] = teams.as_json
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
stadiums = Stadiums.new
|
|
42
|
-
stadiums.add_matches( matches )
|
|
43
|
-
data[:stadiums] = stadiums.as_json
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
## for match-by-match live reports
|
|
47
|
-
report_dir = "#{indir}/#{slug}/matches/#{season.to_path}"
|
|
48
|
-
timeline_dir = "#{indir}/#{slug}/timelines/#{season.to_path}"
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
recs = []
|
|
52
|
-
matches.each_with_index do |m, i|
|
|
53
|
-
|
|
54
|
-
## add/track id too - why? why not?
|
|
55
|
-
## rec[:id] = m['IdMatch']
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
## add/fill-up match basic
|
|
59
|
-
rec = _build_match( m )
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
### get match (live) details
|
|
63
|
-
###
|
|
64
|
-
## check if match report exits
|
|
65
|
-
## optional for now!!
|
|
66
|
-
|
|
67
|
-
live = _read_report( m, report_dir: report_dir )
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
## if live.nil?
|
|
71
|
-
## puts "warn no match report for #{_report_basename(m)}"
|
|
72
|
-
## end
|
|
73
|
-
|
|
74
|
-
if live
|
|
75
|
-
## check for timeline
|
|
76
|
-
timeline = _read_timeline( m, timeline_dir: timeline_dir )
|
|
77
|
-
## reuse generated output from report
|
|
78
|
-
report = _build_report( live, timeline )
|
|
79
|
-
|
|
80
|
-
## try update of score via goals from (match) report
|
|
81
|
-
score_more = _build_report_score( live, timeline )
|
|
82
|
-
if score_more
|
|
83
|
-
rec[:score] = rec[:score].merge( score_more )
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
goals1 = report[:goals1]
|
|
89
|
-
goals2 = report[:goals2]
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if goals1.empty? && goals2.empty?
|
|
93
|
-
## skip if no goals
|
|
94
|
-
else
|
|
95
|
-
rec[:goals1] = goals1
|
|
96
|
-
rec[:goals2] = goals2
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
#########
|
|
104
|
-
## add penalties
|
|
105
|
-
penalties = report[:penalties]
|
|
106
|
-
rec[:penalties] = penalties if penalties && !penalties.empty?
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
sentoff1 = (report[:red1]||[]) + (report[:yellowred1]||[])
|
|
110
|
-
sentoff2 = (report[:red2]||[]) + (report[:yellowred2]||[])
|
|
111
|
-
|
|
112
|
-
## sort by minute
|
|
113
|
-
sentoff1 = sentoff1.sort { |l,r| l[:minute] <=> r[:minute] }
|
|
114
|
-
sentoff2 = sentoff2.sort { |l,r| l[:minute] <=> r[:minute] }
|
|
115
|
-
|
|
116
|
-
rec[:sentoff1] = sentoff1 unless sentoff1.empty?
|
|
117
|
-
rec[:sentoff2] = sentoff2 unless sentoff2.empty?
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
=begin
|
|
123
|
-
"Officials":
|
|
124
|
-
[{"IdCountry": "BRA",
|
|
125
|
-
"OfficialId": "361561",
|
|
126
|
-
"NameShort": [{"Locale": "en-GB", "Description": "Wilton SAMPAIO"}],
|
|
127
|
-
"Name": [{"Locale": "en-GB", "Description": "Wilton SAMPAIO"}],
|
|
128
|
-
"OfficialType": 1,
|
|
129
|
-
"TypeLocalized": [{"Locale": "en-GB", "Description": "Referee"}]},
|
|
130
|
-
{"IdCountry": "PAR",
|
|
131
|
-
"OfficialId": "416159",
|
|
132
|
-
"NameShort":
|
|
133
|
-
[{"Locale": "en-GB", "Description": "Juan Gabriel BENITEZ"}],
|
|
134
|
-
"Name": [{"Locale": "en-GB", "Description": "Juan Gabriel Benítez"}],
|
|
135
|
-
"OfficialType": 4,
|
|
136
|
-
"TypeLocalized":
|
|
137
|
-
[{"Locale": "en-GB", "Description": "Fourth official"}]}],
|
|
138
|
-
=end
|
|
139
|
-
|
|
140
|
-
###
|
|
141
|
-
## add referees
|
|
142
|
-
officials = build_officials( m['Officials'], id: false )
|
|
143
|
-
|
|
144
|
-
if officials.empty?
|
|
145
|
-
## puts "!! WARN no refs / officials found"
|
|
146
|
-
else
|
|
147
|
-
rec[:referees] = officials
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
recs << rec
|
|
154
|
-
end
|
|
155
|
-
data[:matches] = recs
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
outpath = "#{outdir}/#{season.to_path}/#{slug}.json"
|
|
159
|
-
write_json( outpath, data)
|
|
160
|
-
puts " written to >#{outpath}<"
|
|
161
|
-
|
|
162
|
-
true
|
|
163
|
-
end
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
def _build_score_from_goals( m )
|
|
4
|
-
##
|
|
5
|
-
## 5 periods - 3 (1ST_HALF), 5 (2ND_HALF),
|
|
6
|
-
## 7 (EXTRA_TIME_1ST_HALF), 9 (EXTRA_TIME_2ND_HALF),
|
|
7
|
-
## 11 (PENALTY_SHOOTOUT) possibly
|
|
8
|
-
##
|
|
9
|
-
goals = {
|
|
10
|
-
count: 0,
|
|
11
|
-
score: [0,0],
|
|
12
|
-
ht: { score: [0,0], minutes: [] },
|
|
13
|
-
ft: { score: [0,0], minutes: [] },
|
|
14
|
-
et: { score: [0,0], minutes: [] },
|
|
15
|
-
p: { score: [0,0], minutes: [] },
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
## note - quick fix
|
|
19
|
-
## add period 2 for USA v Belgium (PKO) - worldcup
|
|
20
|
-
|
|
21
|
-
## note - i is 0|1 - array index for team
|
|
22
|
-
[m['HomeTeam']['Goals'],
|
|
23
|
-
m['AwayTeam']['Goals']].each_with_index do |recs,i|
|
|
24
|
-
recs.each do |h|
|
|
25
|
-
|
|
26
|
-
h = errata_autofix_goal( h )
|
|
27
|
-
|
|
28
|
-
period = h['Period']
|
|
29
|
-
## include penalty shootout (11) - why? why not?
|
|
30
|
-
assert( [3,5,7,9,11].include?(period),
|
|
31
|
-
"goal in period 3/5/7/9/11 expected; got #{h.pretty_inspect} in match #{m.pretty_inspect}" )
|
|
32
|
-
|
|
33
|
-
minute = h['Minute']
|
|
34
|
-
key = case period
|
|
35
|
-
when 3 then :ht
|
|
36
|
-
when 5 then :ft
|
|
37
|
-
when 7, 9 then :et
|
|
38
|
-
when 11 then :p
|
|
39
|
-
else
|
|
40
|
-
raise ArgumentError,
|
|
41
|
-
"goal in period 3/5/7/9/11 expected; got #{h.pretty_inspect}"
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
goals[:count] += 1
|
|
45
|
-
goals[:score][i] += 1 unless key == :p
|
|
46
|
-
goals[key][:score][i] += 1
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
## use/calc cummulative score (BUT not for penalties)
|
|
51
|
-
goals[:ft][:score][0] += goals[:ht][:score][0]
|
|
52
|
-
goals[:ft][:score][1] += goals[:ht][:score][1]
|
|
53
|
-
|
|
54
|
-
goals[:et][:score][0] += goals[:ft][:score][0]
|
|
55
|
-
goals[:et][:score][1] += goals[:ft][:score][1]
|
|
56
|
-
|
|
57
|
-
goals
|
|
58
|
-
end
|
data/lib/fifadat/pp/goals.rb
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
def build_goal( h, players: )
|
|
6
|
-
|
|
7
|
-
## split into minute
|
|
8
|
-
## and offset (stoppage/injury time)
|
|
9
|
-
## e.g. 90'+11'
|
|
10
|
-
|
|
11
|
-
h = errata_autofix_goal( h )
|
|
12
|
-
|
|
13
|
-
minute_str = h['Minute']
|
|
14
|
-
|
|
15
|
-
period = h['Period']
|
|
16
|
-
|
|
17
|
-
## note - penalty shootout gets excluded upstream!!
|
|
18
|
-
## include penalty shootout (11) - why? why not?
|
|
19
|
-
## assert( [3,5,7,9].include?(period),
|
|
20
|
-
## "goal in period 3/5/7/9 expected; got #{h.pretty_inspect}" )
|
|
21
|
-
|
|
22
|
-
## quick fix:
|
|
23
|
-
## check for weird minute 0 e.g.
|
|
24
|
-
## Germany-Austria 1934
|
|
25
|
-
if minute_str == "0'"
|
|
26
|
-
h['Minute'] = "1'"
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
if minute_str.nil? || minute_str.empty?
|
|
30
|
-
puts "!! minute in goal is nil or empty:"
|
|
31
|
-
pp h
|
|
32
|
-
exit 1
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
minute = _build_minute( h )
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
rec = {}
|
|
39
|
-
|
|
40
|
-
idPlayer = h['IdPlayer']
|
|
41
|
-
|
|
42
|
-
if idPlayer.nil?
|
|
43
|
-
puts "!! no idPlayer for goal!"
|
|
44
|
-
pp h
|
|
45
|
-
##exit 1
|
|
46
|
-
## use 'N.N.'
|
|
47
|
-
|
|
48
|
-
rec[ :name ] = 'N.N.'
|
|
49
|
-
|
|
50
|
-
else
|
|
51
|
-
player = players.find!( idPlayer )
|
|
52
|
-
rec[ :name ] = player[ :name ]
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
rec[ :minute] = minute
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
## check for goal type (og) or (p)
|
|
59
|
-
## 1 - "penalty"
|
|
60
|
-
## 2 - "regular"
|
|
61
|
-
## 3 - "own goal"
|
|
62
|
-
|
|
63
|
-
type = h['Type']
|
|
64
|
-
rec[ :pen ] = true if type == 1
|
|
65
|
-
rec[ :og ] = true if type == 3
|
|
66
|
-
|
|
67
|
-
rec
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def build_goals( recs, players:, penalties: false )
|
|
74
|
-
|
|
75
|
-
## note - filter out penalties (from shoot-out)!!
|
|
76
|
-
## min > 120 (e.g. 121, etc.)
|
|
77
|
-
## note - use period (more reliable)
|
|
78
|
-
## period 11 is PENALTY_SHOOTOUT!!
|
|
79
|
-
if penalties == false
|
|
80
|
-
recs = recs.select { |rec| rec['Period'] != 11 }
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
recs = recs.map { |h| build_goal( h, players: players ) }
|
|
85
|
-
|
|
86
|
-
## note - sort by minutes; goals may not be sorted
|
|
87
|
-
recs = recs.sort { |l,r| l[:minute] <=> r[:minute] }
|
|
88
|
-
recs
|
|
89
|
-
end
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
def _fmt_date_local( date_utc, date_local )
|
|
4
|
-
|
|
5
|
-
## note: returns Rational (e.g. 3/1 or 1/4 etc.) use to_f/to_i to convert
|
|
6
|
-
diff_in_hours = ((date_local - date_utc) * 24).to_f
|
|
7
|
-
diff_in_days = date_local.jd - date_utc.jd
|
|
8
|
-
## pp [diff_in_hours, diff_in_days]
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
## use 20:30 UTC+1 or 20:30 UTC-3
|
|
12
|
-
"#{date_local.strftime( '%Y-%m-%d %H:%M' )} UTC%+d" % diff_in_hours
|
|
13
|
-
end
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
##
|
|
4
|
-
## note - check if m(inute) might be unknown e.g. '??' or such
|
|
5
|
-
##
|
|
6
|
-
## offset (aka stoppage/injury/added time)
|
|
7
|
-
|
|
8
|
-
Minute = Struct.new( :m, :offset, :period) do
|
|
9
|
-
def as_json(*) to_s; end
|
|
10
|
-
|
|
11
|
-
## note - format minute WITHOUT minute marker/quote (')
|
|
12
|
-
def to_s
|
|
13
|
-
buf = String.new
|
|
14
|
-
buf << "#{m}"
|
|
15
|
-
buf << "+#{offset}" if offset
|
|
16
|
-
buf
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
## add compare (for sort)
|
|
20
|
-
def <=>( other )
|
|
21
|
-
res = self.m <=> other.m
|
|
22
|
-
res = (self.offset||0) <=> (other.offset||0) if res == 0
|
|
23
|
-
res
|
|
24
|
-
end
|
|
25
|
-
end ## struct (class) Minute
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
def _build_minute( h )
|
|
30
|
-
|
|
31
|
-
## split into minute
|
|
32
|
-
## and offset (stoppage/injury/added time)
|
|
33
|
-
## e.g. 90'+11'
|
|
34
|
-
|
|
35
|
-
minute_str = h['Minute']
|
|
36
|
-
if minute_str.nil? || minute_str.empty?
|
|
37
|
-
puts "!! minute is nil or empty:"
|
|
38
|
-
pp h
|
|
39
|
-
exit 1
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
minute, offset = _parse_minute( minute_str )
|
|
43
|
-
|
|
44
|
-
Minute.new( m: minute,
|
|
45
|
-
offset: offset,
|
|
46
|
-
period: h['Period'] )
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
MINUTE_RE = %r{ \A
|
|
51
|
-
(?<minute>\d{1,3}) '
|
|
52
|
-
( \+
|
|
53
|
-
(?<offset>\d{1,2}) '
|
|
54
|
-
)?
|
|
55
|
-
\z
|
|
56
|
-
}x
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def _parse_minute( str )
|
|
60
|
-
|
|
61
|
-
## support weirdo 120'+-30' -- remove minuts
|
|
62
|
-
str = str.gsub( '-', '' )
|
|
63
|
-
|
|
64
|
-
m = MINUTE_RE.match( str )
|
|
65
|
-
raise ArgumentError, "unknown goal minute format in #{str.inspect}" if m.nil?
|
|
66
|
-
|
|
67
|
-
minute = m[:minute].to_i(10)
|
|
68
|
-
offset = m[:offset] ? m[:offset].to_i(10) : nil
|
|
69
|
-
|
|
70
|
-
[minute,offset]
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def _fmt_minute( minute, offset )
|
|
74
|
-
## pp [minute,offset]
|
|
75
|
-
|
|
76
|
-
buf = String.new
|
|
77
|
-
buf << "#{minute}"
|
|
78
|
-
buf << "+#{offset}" if offset
|
|
79
|
-
buf << "'"
|
|
80
|
-
buf
|
|
81
|
-
end
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
#
|
|
3
|
-
# add quick fix for club world cup?!
|
|
4
|
-
# elsif resultType == 1 || ## assume 1 - regular (90 mins+stoppage/injury time)
|
|
5
|
-
# resultType == 4 ||
|
|
6
|
-
# m['IdMatch'] == '400019191' ## fix for pachuca vs salzburg !!!
|
|
7
|
-
# has resultType == 0!!!
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def _parse_score( m )
|
|
11
|
-
h = { }
|
|
12
|
-
|
|
13
|
-
m = errata_autofix_score( m )
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
resultType = m['ResultType']
|
|
17
|
-
|
|
18
|
-
score = if m['HomeTeam'] && m['AwayTeam'] ## assume inside (match) report
|
|
19
|
-
[m['HomeTeam']['Score'], m['AwayTeam']['Score']].compact
|
|
20
|
-
else ## assume (seasons) matches list
|
|
21
|
-
## note - report has no "inline/flat" HomeTeamScore/AwayTeamScore
|
|
22
|
-
[m['HomeTeamScore'], m['AwayTeamScore']].compact
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
## is score after extra-time or not?
|
|
27
|
-
## note - CANNOT tell for resultType 2!!!
|
|
28
|
-
|
|
29
|
-
if score.empty?
|
|
30
|
-
## do nothing
|
|
31
|
-
else
|
|
32
|
-
if [1,4].include?( resultType )
|
|
33
|
-
## 1 - regular - 90min
|
|
34
|
-
## 4 - regular - 90min (on aggregate)
|
|
35
|
-
h[:ft] = score
|
|
36
|
-
elsif [3,5,8].include?( resultType )
|
|
37
|
-
## 3 - aet (for sure)
|
|
38
|
-
## 5 - aet [on aggregate] (for sure)
|
|
39
|
-
## 8 - golden goal in extra time (aet/gg)
|
|
40
|
-
## fix/fix/fix - add gold_goal flag for 8!!!
|
|
41
|
-
h[:et] = score ## assume after extra-time !!!
|
|
42
|
-
elsif resultType == 2
|
|
43
|
-
### note - 2 win on pens
|
|
44
|
-
## 2 - win on pens (with or WITHOUT aet!!)
|
|
45
|
-
|
|
46
|
-
## check for competition for now
|
|
47
|
-
## incl. south american
|
|
48
|
-
if false ## add some competitions here
|
|
49
|
-
h[:ft] = score
|
|
50
|
-
else
|
|
51
|
-
h[:et] = score
|
|
52
|
-
end
|
|
53
|
-
else
|
|
54
|
-
h[:score] = score
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
penScore = [m['HomeTeamPenaltyScore'], m['AwayTeamPenaltyScore']].compact
|
|
60
|
-
aggScore = [m['AggregateHomeTeamScore'],m['AggregateAwayTeamScore']].compact
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
## note - worldcup has penScore [0,0] for all matches, for example!!!
|
|
64
|
-
if penScore.empty? || penScore == [0,0]
|
|
65
|
-
else
|
|
66
|
-
h[:p] = penScore
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
h[:agg] = aggScore if !aggScore.empty?
|
|
70
|
-
h
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
def _fmt_score( m )
|
|
76
|
-
|
|
77
|
-
m = errata_autofix_score( m )
|
|
78
|
-
|
|
79
|
-
## m = (full) match hash incl. IdMatch, etc.
|
|
80
|
-
## returns string e.g. 4-4 or 4-3 a.e.t etc
|
|
81
|
-
|
|
82
|
-
resultType = m['ResultType']
|
|
83
|
-
|
|
84
|
-
# resultType
|
|
85
|
-
# 0 => no result / not played yet
|
|
86
|
-
# 1 => regular (90 mins)
|
|
87
|
-
# 2 => aet (120 mins), win on pens
|
|
88
|
-
# 3 => aet (120 mins)
|
|
89
|
-
# 8 => same as 3? -aet with golden goal/silver goal in 1998 FRA-PAR
|
|
90
|
-
|
|
91
|
-
score = if resultType == 2 ## aet, win on pens
|
|
92
|
-
"#{m['HomeTeamScore']}-#{m['AwayTeamScore']}" +
|
|
93
|
-
" a.e.t., #{m['HomeTeamPenaltyScore']}-#{m['AwayTeamPenaltyScore']} pen."
|
|
94
|
-
elsif resultType == 3 || resultType == 8 ## aet
|
|
95
|
-
"#{m['HomeTeamScore']}-#{m['AwayTeamScore']} a.e.t."
|
|
96
|
-
elsif resultType == 1 || ## assume 1 - regular (90 mins+stoppage/injury time)
|
|
97
|
-
resultType == 4
|
|
98
|
-
"#{m['HomeTeamScore']}-#{m['AwayTeamScore']}"
|
|
99
|
-
elsif resultType == 0
|
|
100
|
-
## double check if score present
|
|
101
|
-
## e.g. pachuca vs salzburg in cwc 2025??
|
|
102
|
-
raise ArgumentError,
|
|
103
|
-
" resultType == 0 but score present idMatch #{m['IdMatch']} #{m['HomeTeamScore']}-#{m['AwayTeamScore']}" if m['HomeTeamScore'] &&
|
|
104
|
-
m['AwayTeamScore']
|
|
105
|
-
""
|
|
106
|
-
else
|
|
107
|
-
raise ArgumentError, "unknown/unexpected result type #{resultType}"
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
score
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
__END__
|
|
117
|
-
|
|
118
|
-
score = if resultType == 2 ## aet, win on pens
|
|
119
|
-
{ et: [m['HomeTeamScore'],m['AwayTeamScore']],
|
|
120
|
-
p: [m['HomeTeamPenaltyScore'],m['AwayTeamPenaltyScore']] }
|
|
121
|
-
elsif resultType == 3 || resultType == 8 ## aet
|
|
122
|
-
{ et: [m['HomeTeamScore'], m['AwayTeamScore']] }
|
|
123
|
-
elsif resultType == 1 || ## assume 1 - regular (90 mins+stoppage/injury time)
|
|
124
|
-
resultType == 4 ||
|
|
125
|
-
m['IdMatch'] == '400019191' ## fix for pachuca vs salzburg !!!
|
|
126
|
-
{ ft: [m['HomeTeamScore'],m['AwayTeamScore']] }
|
|
127
|
-
elsif resultType == 12
|
|
128
|
-
## fix/fix/fix - check for score too
|
|
129
|
-
nil
|
|
130
|
-
elsif resultType == 0
|
|
131
|
-
## pachuca vs salzburg in cwc 2025??
|
|
132
|
-
## double check if score present
|
|
133
|
-
raise ArgumentError,
|
|
134
|
-
" resultType == 0 but score present idMatch #{m['IdMatch']} #{m['HomeTeamScore']}-#{m['AwayTeamScore']}" if m['HomeTeamScore'] &&
|
|
135
|
-
m['AwayTeamScore']
|
|
136
|
-
nil
|
|
137
|
-
else
|
|
138
|
-
raise ArgumentError, "unknown/unexpected result type #{resultType}"
|
|
139
|
-
end
|
data/lib/fifadat/pp/norm.rb
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
ALPHA_RE = %r{ \A
|
|
4
|
-
\p{L}
|
|
5
|
-
[\p{L} '.-]*
|
|
6
|
-
\z
|
|
7
|
-
}ix
|
|
8
|
-
|
|
9
|
-
##
|
|
10
|
-
## J. HARTING - note: include .
|
|
11
|
-
## Jose BUSTAMANTE-NAVA - note: include -
|
|
12
|
-
## Yannick N'Djeng - note: include '
|
|
13
|
-
## Ismail JAKOBS Ismail JAKOBS
|
|
14
|
-
|
|
15
|
-
def is_alpha?( name ) ## use is_alpha_name? or is_unialpha? or such??
|
|
16
|
-
ALPHA_RE.match( name ) ? true : false
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def pp_alpha( name )
|
|
21
|
-
##
|
|
22
|
-
## note: e is decomposed !!!! - will break lexer!!!
|
|
23
|
-
## e (101)
|
|
24
|
-
## ́ (769)
|
|
25
|
-
## vs
|
|
26
|
-
## é (233)
|
|
27
|
-
|
|
28
|
-
buf = String.new
|
|
29
|
-
buf << ">#{name}< => "
|
|
30
|
-
name.each_char do |char|
|
|
31
|
-
buf << "#{char} (#{char.ord}) | "
|
|
32
|
-
end
|
|
33
|
-
buf
|
|
34
|
-
end
|
data/lib/fifadat/pp/officials.rb
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
=begin
|
|
3
|
-
"Officials":
|
|
4
|
-
[{"IdCountry": "URU",
|
|
5
|
-
"OfficialId": "61038",
|
|
6
|
-
"NameShort": [{"Locale": "en-GB", "Description": "Domingo LOMBARDI"}],
|
|
7
|
-
"Name": [{"Locale": "en-GB", "Description": "Domingo LOMBARDI"}],
|
|
8
|
-
"OfficialType": 1,
|
|
9
|
-
"TypeLocalized": [{"Locale": "en-GB", "Description": "Referee"}]},
|
|
10
|
-
{"IdCountry": "BEL",
|
|
11
|
-
"OfficialId": "60664",
|
|
12
|
-
"NameShort": [{"Locale": "en-GB", "Description": "Henry CRISTOPHE"}],
|
|
13
|
-
"Name": [{"Locale": "en-GB", "Description": "Henry CRISTOPHE"}],
|
|
14
|
-
"OfficialType": 2,
|
|
15
|
-
"TypeLocalized":
|
|
16
|
-
[{"Locale": "en-GB", "Description": "Assistant Referee 1"}]},
|
|
17
|
-
{"IdCountry": "BRA",
|
|
18
|
-
"OfficialId": "61289",
|
|
19
|
-
"NameShort": [{"Locale": "en-GB", "Description": "Gilberto REGO"}],
|
|
20
|
-
"Name": [{"Locale": "en-GB", "Description": "Gilberto REGO"}],
|
|
21
|
-
"OfficialType": 3,
|
|
22
|
-
"TypeLocalized":
|
|
23
|
-
[{"Locale": "en-GB", "Description": "Assistant Referee 2"}]}],
|
|
24
|
-
|
|
25
|
-
=end
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
TYPE_OFFICIAL = {
|
|
29
|
-
1 => 'Referee',
|
|
30
|
-
2 => 'Assistant Referee 1',
|
|
31
|
-
3 => 'Assistant Referee 2',
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
def build_official( h, id: )
|
|
35
|
-
name = desc( h['Name'] )
|
|
36
|
-
|
|
37
|
-
## fix - use norm_official
|
|
38
|
-
## name = norm_official( name )
|
|
39
|
-
|
|
40
|
-
idCountry = h['IdCountry']
|
|
41
|
-
type = h['OfficialType']
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
assert( is_alpha?(name), "official name alpha expected; got #{pp_alpha(name)}" )
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
assert( [1,2,3,4,5,6,7,8,9,10].include?( type ), "official type 1/2/3/4/5/6/7/8/9/10 expected; got #{type}" )
|
|
49
|
-
|
|
50
|
-
rec = {}
|
|
51
|
-
rec[:id] = h['OfficialId'] if id
|
|
52
|
-
|
|
53
|
-
rec.merge!( name: name,
|
|
54
|
-
country: idCountry,
|
|
55
|
-
type: type )
|
|
56
|
-
|
|
57
|
-
rec
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def build_officials( recs, id: false ) ## use referees?
|
|
62
|
-
recs = recs.map { |h| build_official( h, id: id ) }
|
|
63
|
-
|
|
64
|
-
## skip fourth official (4) for now
|
|
65
|
-
recs = recs.select { |h| [1,2,3].include?( h[:type] ) }
|
|
66
|
-
|
|
67
|
-
## sort by type 1/2/3
|
|
68
|
-
## 1 - referee
|
|
69
|
-
## 2 - assistant referee 1
|
|
70
|
-
## 3 - assistant referee 2
|
|
71
|
-
## 4 - fourth official
|
|
72
|
-
## 5 - video assistant referee (var)
|
|
73
|
-
## 6 - reserve referee
|
|
74
|
-
## 7 - offside var
|
|
75
|
-
## 8 - assistant var
|
|
76
|
-
## 9 - support var
|
|
77
|
-
## 10 - reserve assistant referee
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
recs = recs.sort { |l,r| l[:type] <=> r[:type] }
|
|
81
|
-
|
|
82
|
-
## change type to literal string
|
|
83
|
-
recs = recs.map { |h| h[:type]=TYPE_OFFICIAL[h[:type]]; h }
|
|
84
|
-
|
|
85
|
-
recs
|
|
86
|
-
end
|