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,81 @@
|
|
|
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
|
|
@@ -0,0 +1,139 @@
|
|
|
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
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
|
@@ -0,0 +1,86 @@
|
|
|
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
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
|
|
2
|
+
=begin
|
|
3
|
+
{"EventId": "120171",
|
|
4
|
+
"IdTeam": "43942",
|
|
5
|
+
"IdPlayer": "95982",
|
|
6
|
+
"Timestamp": "2022-11-14T10:47:50.8028496Z",
|
|
7
|
+
"MatchMinute": "120'",
|
|
8
|
+
"Period": 11,
|
|
9
|
+
"HomeGoals": 2,
|
|
10
|
+
"AwayGoals": 2,
|
|
11
|
+
"Type": 60,
|
|
12
|
+
"Qualifiers": [],
|
|
13
|
+
"TypeLocalized": [{"Locale": "en-GB", "Description": "Penalty missed"}],
|
|
14
|
+
"HomePenaltyGoals": 4,
|
|
15
|
+
"AwayPenaltyGoals": 3,
|
|
16
|
+
"EventDescription":
|
|
17
|
+
[{"Locale": "en-GB",
|
|
18
|
+
"Description":
|
|
19
|
+
"David BATTY (England) misses from the penalty spot!"}]}],
|
|
20
|
+
"Properties": {},
|
|
21
|
+
"IsUpdateable": null}
|
|
22
|
+
=end
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def build_penalty( h, players:,
|
|
26
|
+
team1_id:, team2_id: )
|
|
27
|
+
|
|
28
|
+
## note - do NOT care about minutes in penalty shootout
|
|
29
|
+
## check for period == 11 (penalty shotout!!)
|
|
30
|
+
## period = h['Period']
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
##########
|
|
34
|
+
## 0 - goal (when penalty awared used before)
|
|
35
|
+
## 41 - penalty goal
|
|
36
|
+
## 46 - penalty missed
|
|
37
|
+
## Dragan STOJKOVIC (Yugoslavia) rattles the crossbar from the spot!
|
|
38
|
+
## 51 - penalty missed
|
|
39
|
+
## JULIO CESAR (Brazil) hits the post from the spot!
|
|
40
|
+
## 60 - penalty missed
|
|
41
|
+
## COMAN (France) sees his penalty saved by the goalkeeper.
|
|
42
|
+
## Maxime BOSSIS (France) misses from the penalty spot! and many more
|
|
43
|
+
## 65 - penalty missed
|
|
44
|
+
## TCHOUAMENI (France) misses from the penalty spot!
|
|
45
|
+
|
|
46
|
+
type = h['Type'] ## (timeline) event type
|
|
47
|
+
|
|
48
|
+
assert( [0,41,46,51,60,65].include?(type),
|
|
49
|
+
"event type 0/41/46/51/60/65 expected; got #{type}")
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
team = if h['IdTeam'] == team1_id
|
|
53
|
+
1
|
|
54
|
+
elsif h['IdTeam'] == team2_id
|
|
55
|
+
2
|
|
56
|
+
else
|
|
57
|
+
assert( false, "team1/2_id #{team1_id/team2_id} expected; got #{h.pretty_inspect}")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
rec = { team: team, ## 1|2
|
|
61
|
+
score: [h['HomePenaltyGoals'],
|
|
62
|
+
h['AwayPenaltyGoals']],
|
|
63
|
+
scored: [0,41].include?( type ) ? true : false,
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
idPlayer = h['IdPlayer']
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
=begin
|
|
70
|
+
-- try IdSubPlayer - why? why not?
|
|
71
|
+
IdSubPlayer is goalkeeper!!!
|
|
72
|
+
## what is SubPlayer/SubTeam in event??
|
|
73
|
+
!! no idPlayer for penaltyl!
|
|
74
|
+
{"EventId"=>"17807200001266",
|
|
75
|
+
"IdTeam"=>"1884426",
|
|
76
|
+
"IdSubPlayer"=>"408948",
|
|
77
|
+
"IdSubTeam"=>"1897032",
|
|
78
|
+
=end
|
|
79
|
+
|
|
80
|
+
if idPlayer.nil?
|
|
81
|
+
puts "!! no idPlayer for penalty!"
|
|
82
|
+
pp h
|
|
83
|
+
##exit 1
|
|
84
|
+
## use 'N.N.'
|
|
85
|
+
|
|
86
|
+
rec[ :name ] = 'N.N.'
|
|
87
|
+
|
|
88
|
+
else
|
|
89
|
+
rec[ :name ] = players.find!( idPlayer )[:name]
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
rec[:meta] = { type: type,
|
|
93
|
+
desc: desc(h['EventDescription']) ## add event desc too - why? why not?
|
|
94
|
+
}
|
|
95
|
+
rec
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def build_penalties( recs, players:,
|
|
102
|
+
team1_id:, team2_id: )
|
|
103
|
+
################
|
|
104
|
+
## type:
|
|
105
|
+
## check for "old/legacy" format used where?
|
|
106
|
+
## not using period 11 ???
|
|
107
|
+
## incl. weirdo format with
|
|
108
|
+
## 6 - penalty awarded
|
|
109
|
+
## 0 - goal or 60 - penalty missed!
|
|
110
|
+
##
|
|
111
|
+
## 2 - yellow card
|
|
112
|
+
## 3 - red card
|
|
113
|
+
## 7 - start time
|
|
114
|
+
## 8 - end time
|
|
115
|
+
|
|
116
|
+
recs = recs.select do |h|
|
|
117
|
+
if h['Period'] == 11 ## penalty shoot-out
|
|
118
|
+
assert( [0,2,3,6,7,8,41,46,51,60,65].include?( h['Type'] ),
|
|
119
|
+
"expected event type 2/3/7/8/41/46/51/60/65 for pens; got #{h.pretty_inspect}"
|
|
120
|
+
)
|
|
121
|
+
[0,41,46,51,60,65].include?( h['Type'] ) ? true : false
|
|
122
|
+
else
|
|
123
|
+
false
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
recs = recs.map { |h| build_penalty( h, players: players,
|
|
129
|
+
team1_id: team1_id,
|
|
130
|
+
team2_id: team2_id ) }
|
|
131
|
+
recs
|
|
132
|
+
end
|