fifadat-convert 0.0.1 → 0.1.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/CHANGELOG.md +1 -0
- data/Manifest.txt +15 -11
- data/lib/fifadat/convert/convert-reports.rb +49 -67
- data/lib/fifadat/convert/convert.rb +67 -96
- data/lib/fifadat/convert/helper-date.rb +12 -0
- data/lib/fifadat/convert/helper-score.rb +104 -61
- data/lib/fifadat/convert/reader.rb +55 -0
- data/lib/fifadat/convert/tool.rb +1 -1
- data/lib/fifadat/convert/version.rb +2 -2
- data/lib/fifadat/convert.rb +54 -14
- data/lib/fifadat/{convert/goals.rb → models/goal.rb} +49 -18
- data/lib/fifadat/models/match.rb +218 -0
- data/lib/fifadat/models/match_report.rb +205 -0
- data/lib/fifadat/{convert/officials.rb → models/official.rb} +58 -20
- data/lib/fifadat/{convert/penalties.rb → models/penalty.rb} +50 -16
- data/lib/fifadat/models/player.rb +218 -0
- data/lib/fifadat/models/stadium.rb +98 -0
- data/lib/fifadat/models/stage.rb +99 -0
- data/lib/fifadat/{convert/substitutions.rb → models/substitution.rb} +84 -9
- data/lib/fifadat/models/team.rb +85 -0
- data/lib/fifadat/tables/players.rb +140 -0
- data/lib/fifadat/tables/stadiums.rb +71 -0
- data/lib/fifadat/tables/stages.rb +58 -0
- data/lib/fifadat/tables/teams.rb +57 -0
- metadata +17 -13
- data/lib/fifadat/convert/build_match.rb +0 -105
- data/lib/fifadat/convert/build_report.rb +0 -135
- data/lib/fifadat/convert/goals-calc_score.rb +0 -58
- data/lib/fifadat/convert/players.rb +0 -329
- data/lib/fifadat/convert/stadiums.rb +0 -99
- data/lib/fifadat/convert/stages.rb +0 -119
- data/lib/fifadat/convert/teams.rb +0 -91
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 72f197ccce455bdc5de862831d320aabaa06f5ed2665e8496ec324573135398c
|
|
4
|
+
data.tar.gz: 6e2d54b61c281bcbc8d812e8d7a7bc562811a4deb6663d6e3cf6a73c68cc0b60
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1c5aca3857ba0409c4070845fcb03dd812cbabb011689108437776ffe24e5d3934dc9145b55fb5895db47f26b17f2f6189f67ef4828a41a9fde799e01c2d0a2e
|
|
7
|
+
data.tar.gz: 340cbd14fd0b74db8af3144426b6ca857b1acf2d79911495e33e82589dd28c48e6ba9c659bffae4799c93df0debd271d70dd0e9dd9bd97e97af6bfd5ad144c9b
|
data/CHANGELOG.md
CHANGED
data/Manifest.txt
CHANGED
|
@@ -4,24 +4,28 @@ README.md
|
|
|
4
4
|
Rakefile
|
|
5
5
|
bin/fifadat
|
|
6
6
|
lib/fifadat/convert.rb
|
|
7
|
-
lib/fifadat/convert/build_match.rb
|
|
8
|
-
lib/fifadat/convert/build_report.rb
|
|
9
7
|
lib/fifadat/convert/convert-reports.rb
|
|
10
8
|
lib/fifadat/convert/convert.rb
|
|
11
9
|
lib/fifadat/convert/errata.rb
|
|
12
|
-
lib/fifadat/convert/goals-calc_score.rb
|
|
13
|
-
lib/fifadat/convert/goals.rb
|
|
14
10
|
lib/fifadat/convert/helper-date.rb
|
|
15
11
|
lib/fifadat/convert/helper-minute.rb
|
|
16
12
|
lib/fifadat/convert/helper-score.rb
|
|
17
13
|
lib/fifadat/convert/norm.rb
|
|
18
|
-
lib/fifadat/convert/
|
|
19
|
-
lib/fifadat/convert/penalties.rb
|
|
20
|
-
lib/fifadat/convert/players.rb
|
|
21
|
-
lib/fifadat/convert/stadiums.rb
|
|
22
|
-
lib/fifadat/convert/stages.rb
|
|
23
|
-
lib/fifadat/convert/substitutions.rb
|
|
24
|
-
lib/fifadat/convert/teams.rb
|
|
14
|
+
lib/fifadat/convert/reader.rb
|
|
25
15
|
lib/fifadat/convert/tool.rb
|
|
26
16
|
lib/fifadat/convert/version.rb
|
|
17
|
+
lib/fifadat/models/goal.rb
|
|
18
|
+
lib/fifadat/models/match.rb
|
|
19
|
+
lib/fifadat/models/match_report.rb
|
|
20
|
+
lib/fifadat/models/official.rb
|
|
21
|
+
lib/fifadat/models/penalty.rb
|
|
22
|
+
lib/fifadat/models/player.rb
|
|
23
|
+
lib/fifadat/models/stadium.rb
|
|
24
|
+
lib/fifadat/models/stage.rb
|
|
25
|
+
lib/fifadat/models/substitution.rb
|
|
26
|
+
lib/fifadat/models/team.rb
|
|
27
|
+
lib/fifadat/tables/players.rb
|
|
28
|
+
lib/fifadat/tables/stadiums.rb
|
|
29
|
+
lib/fifadat/tables/stages.rb
|
|
30
|
+
lib/fifadat/tables/teams.rb
|
|
27
31
|
lib/fifadata-convert.rb
|
|
@@ -3,84 +3,54 @@
|
|
|
3
3
|
##
|
|
4
4
|
## read & build match report
|
|
5
5
|
|
|
6
|
-
## use mk/build_report_basename - why? why not?
|
|
7
|
-
## fix-fix-fix - change to _match_basename !!!
|
|
8
|
-
## use by (match)report and (match)timeline !!!
|
|
9
|
-
def _report_basename( m )
|
|
10
|
-
### get match (live) details
|
|
11
|
-
team1_code = m['Home']['Abbreviation']
|
|
12
|
-
team2_code = m['Away']['Abbreviation']
|
|
13
|
-
localDateTime = parse_date_utc( m['LocalDate'] )
|
|
14
|
-
|
|
15
|
-
## e.g. 2020-06-24_RAP-AUS__54545454
|
|
16
|
-
basename = String.new
|
|
17
|
-
basename += localDateTime.strftime('%Y-%m-%d') ## i) date
|
|
18
|
-
basename += "_#{team1_code}-#{team2_code}" ## ii) team1 v team2
|
|
19
|
-
|
|
20
|
-
basename
|
|
21
|
-
end
|
|
22
6
|
|
|
7
|
+
def convert_reports( slug:, season:,
|
|
8
|
+
indir: '.',
|
|
9
|
+
outdir: './tmp' )
|
|
23
10
|
|
|
11
|
+
season = Season(season)
|
|
24
12
|
|
|
25
|
-
|
|
26
|
-
|
|
13
|
+
data = read_json_v2( "#{indir}/#{slug}/#{season.to_path}_matches.json" )
|
|
14
|
+
matches = data['Results'] ## only use results (match) array
|
|
15
|
+
puts "==> convert reports - #{matches.size} match(es) in #{slug} #{season}"
|
|
27
16
|
|
|
28
|
-
basename = _report_basename( m )
|
|
29
|
-
basename += "__#{m['IdMatch']}"
|
|
30
17
|
|
|
31
|
-
|
|
18
|
+
## read in stages
|
|
19
|
+
## incl. SequenceOrder, StageLevel (optional)
|
|
20
|
+
stages = Stages.read( "#{indir}/#{slug}/misc/#{season.to_path}_stages.json" )
|
|
21
|
+
stages.add_matches( matches )
|
|
32
22
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
timeline = read_json_v2( path )
|
|
36
|
-
timeline
|
|
37
|
-
else
|
|
38
|
-
nil
|
|
39
|
-
end
|
|
40
|
-
end
|
|
23
|
+
teams = Teams.new
|
|
24
|
+
teams.add_matches( matches )
|
|
41
25
|
|
|
42
|
-
|
|
43
|
-
|
|
26
|
+
stadiums = Stadiums.new
|
|
27
|
+
stadiums.add_matches( matches )
|
|
44
28
|
|
|
45
|
-
## e.g. 2020-06-24_RAP-AUS__54545454
|
|
46
|
-
# note - add match id for "raw" match reports!!!
|
|
47
|
-
basename = _report_basename( m )
|
|
48
|
-
basename += "__#{m['IdMatch']}"
|
|
49
|
-
|
|
50
|
-
## #{indir}/#{slug}/matches/#{season.to_path}
|
|
51
|
-
path = "#{report_dir}/#{basename}.json"
|
|
52
|
-
|
|
53
|
-
## note - skip if no match report available!!!
|
|
54
|
-
if File.file?( path )
|
|
55
|
-
live = read_json_v2( path )
|
|
56
|
-
live
|
|
57
|
-
else
|
|
58
|
-
nil
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
29
|
|
|
62
30
|
|
|
63
31
|
|
|
32
|
+
report_dir = "#{indir}/#{slug}/matches/#{season.to_path}"
|
|
33
|
+
timeline_dir = "#{indir}/#{slug}/timelines/#{season.to_path}"
|
|
64
34
|
|
|
65
35
|
|
|
66
36
|
|
|
67
|
-
|
|
68
|
-
indir: '.',
|
|
69
|
-
outdir: './tmp' )
|
|
70
|
-
|
|
71
|
-
season = Season(season)
|
|
37
|
+
matches.each_with_index do |m, i|
|
|
72
38
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
puts " #{matches.size} match(es) in season #{season}"
|
|
39
|
+
print "."
|
|
40
|
+
print i+1 if (i+1) %10 == 0
|
|
76
41
|
|
|
77
42
|
|
|
78
|
-
|
|
79
|
-
|
|
43
|
+
## note skip if SCHEDULED == 1
|
|
44
|
+
## 0 => FINISHED/complete (OK)
|
|
45
|
+
## 1 => SCHEDULED/not yet played
|
|
46
|
+
## 2 => LIVE
|
|
47
|
+
## 7 => POSTPONED
|
|
80
48
|
|
|
49
|
+
next if m['MatchStatus'] == 1 ||
|
|
50
|
+
m['MatchStatus'] == 2 ||
|
|
51
|
+
m['MatchStatus'] == 7
|
|
81
52
|
|
|
82
53
|
|
|
83
|
-
matches.each_with_index do |m, i|
|
|
84
54
|
live = _read_report( m, report_dir: report_dir )
|
|
85
55
|
|
|
86
56
|
## no report found; continue
|
|
@@ -89,26 +59,38 @@ def convert_reports( slug:, season:,
|
|
|
89
59
|
## check for optional timeline
|
|
90
60
|
timeline = _read_timeline( m, timeline_dir: timeline_dir )
|
|
91
61
|
|
|
92
|
-
|
|
62
|
+
|
|
63
|
+
rec = Match.build( live, teams: teams,
|
|
64
|
+
stadiums: stadiums,
|
|
65
|
+
stages: stages )
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
## try update of score via goals from (match) report
|
|
69
|
+
score_more = _build_report_score( live, timeline )
|
|
70
|
+
if score_more
|
|
71
|
+
rec.score = {}.merge( rec.score||{}, score_more )
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
report = MatchReport.build( live, timeline )
|
|
76
|
+
|
|
77
|
+
data = {
|
|
93
78
|
meta: {
|
|
94
79
|
name: desc(live['SeasonName']),
|
|
95
80
|
slug: slug,
|
|
96
81
|
season: season.to_s,
|
|
97
82
|
generated: Time.now.to_s,
|
|
98
83
|
}
|
|
99
|
-
}
|
|
100
|
-
_build_report( live, timeline ))
|
|
84
|
+
}
|
|
101
85
|
|
|
102
|
-
|
|
103
|
-
score_more = _build_report_score( live, timeline )
|
|
104
|
-
if score_more
|
|
105
|
-
rec[:score] = rec[:score].merge( score_more )
|
|
106
|
-
end
|
|
86
|
+
data = data.merge( rec.as_json, report.as_json )
|
|
107
87
|
|
|
108
88
|
|
|
109
89
|
## build basename e.g 2026-07-15_ARG-ENG
|
|
110
90
|
basename = _report_basename( m )
|
|
111
91
|
outpath = "#{outdir}/#{season.to_path}/#{slug}/#{basename}.json"
|
|
112
|
-
write_json( outpath,
|
|
92
|
+
write_json( outpath, data )
|
|
113
93
|
end
|
|
94
|
+
|
|
95
|
+
print "DONE\n"
|
|
114
96
|
end
|
|
@@ -5,44 +5,49 @@ def convert( slug:, season:,
|
|
|
5
5
|
indir: '.',
|
|
6
6
|
outdir: './tmp' )
|
|
7
7
|
|
|
8
|
-
|
|
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
|
-
}
|
|
8
|
+
season = Season(season)
|
|
18
9
|
|
|
19
10
|
|
|
11
|
+
### fix-fix-fix change to read_json_results or ??? - why? why not?
|
|
20
12
|
matches = read_json_v2( "#{indir}/#{slug}/#{season.to_path}_matches.json" )
|
|
21
13
|
matches = matches['Results'] ## only use results (match) array
|
|
22
14
|
|
|
23
15
|
## pp matches
|
|
24
|
-
puts "
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
## read in stages
|
|
28
|
-
## incl. SequenceOrder, StageLevel (optional)
|
|
29
|
-
stages = Stages.read( "#{indir}/#{slug}/misc/#{season.to_path}_stages.json" )
|
|
16
|
+
puts "==> convert - #{matches.size} match(es) in #{slug} #{season}"
|
|
30
17
|
|
|
31
18
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
19
|
+
## read in stages
|
|
20
|
+
## incl. SequenceOrder, StageLevel (optional)
|
|
21
|
+
stages = Stages.read( "#{indir}/#{slug}/misc/#{season.to_path}_stages.json" )
|
|
22
|
+
stages.add_matches( matches )
|
|
35
23
|
|
|
36
24
|
teams = Teams.new
|
|
37
25
|
teams.add_matches( matches )
|
|
38
|
-
data[:teams] = teams.as_json
|
|
39
|
-
|
|
40
26
|
|
|
41
27
|
stadiums = Stadiums.new
|
|
42
28
|
stadiums.add_matches( matches )
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
data = {}
|
|
33
|
+
|
|
34
|
+
## add slug & seasons (add name to be done!!)
|
|
35
|
+
data[:meta] = { slug: slug,
|
|
36
|
+
season: season.to_s,
|
|
37
|
+
generated: Time.now.to_s,
|
|
38
|
+
version: FifadatConvert::VERSION,
|
|
39
|
+
teams: teams.size,
|
|
40
|
+
matches: matches.size,
|
|
41
|
+
stages: stages.size,
|
|
42
|
+
stadiums: stadiums.size,
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
data[:stages] = stages.as_json
|
|
46
|
+
data[:teams] = teams.as_json
|
|
43
47
|
data[:stadiums] = stadiums.as_json
|
|
44
48
|
|
|
45
49
|
|
|
50
|
+
|
|
46
51
|
## for match-by-match live reports
|
|
47
52
|
report_dir = "#{indir}/#{slug}/matches/#{season.to_path}"
|
|
48
53
|
timeline_dir = "#{indir}/#{slug}/timelines/#{season.to_path}"
|
|
@@ -56,112 +61,78 @@ def convert( slug:, season:,
|
|
|
56
61
|
|
|
57
62
|
|
|
58
63
|
## add/fill-up match basic
|
|
59
|
-
rec =
|
|
60
|
-
|
|
64
|
+
rec = Match.build( m, teams: teams,
|
|
65
|
+
stadiums: stadiums,
|
|
66
|
+
stages: stages )
|
|
61
67
|
|
|
62
|
-
### get match (live) details
|
|
63
68
|
###
|
|
64
|
-
## check
|
|
65
|
-
##
|
|
69
|
+
## note - skip check for match events / goals etc.
|
|
70
|
+
## if not yet played!!!
|
|
71
|
+
# 1-scheduled and
|
|
72
|
+
# 2-live
|
|
73
|
+
# 7-postponed (too)
|
|
74
|
+
# return empty score!!!
|
|
75
|
+
if !(m['MatchStatus'] == 1 ||
|
|
76
|
+
m['MatchStatus'] == 2 ||
|
|
77
|
+
m['MatchStatus'] == 7)
|
|
78
|
+
|
|
66
79
|
|
|
67
|
-
live = _read_report( m, report_dir: report_dir )
|
|
68
80
|
|
|
81
|
+
### get match (live) details
|
|
82
|
+
###
|
|
83
|
+
## check if match report & timeline exits
|
|
84
|
+
## optional for now!!
|
|
85
|
+
|
|
86
|
+
live = _read_report( m, report_dir: report_dir )
|
|
87
|
+
timeline = _read_timeline( m, timeline_dir: timeline_dir )
|
|
69
88
|
|
|
70
89
|
## if live.nil?
|
|
71
90
|
## puts "warn no match report for #{_report_basename(m)}"
|
|
72
91
|
## end
|
|
73
92
|
|
|
74
93
|
|
|
75
|
-
###
|
|
76
|
-
## note - skip check for match events / goals etc.
|
|
77
|
-
## if not yet played!!!
|
|
78
|
-
|
|
79
|
-
if live && !(rec[:status] == 'TIMED' ||
|
|
80
|
-
rec[:status] == 'SCHED' || rec[:status] == 'SCHEDULED' ||
|
|
81
|
-
rec[:status] == 'LIVE')
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
## check for timeline
|
|
85
|
-
timeline = _read_timeline( m, timeline_dir: timeline_dir )
|
|
86
|
-
## reuse generated output from report
|
|
87
|
-
report = _build_report( live, timeline )
|
|
88
|
-
|
|
89
94
|
## try update of score via goals from (match) report
|
|
90
95
|
score_more = _build_report_score( live, timeline )
|
|
91
96
|
if score_more
|
|
92
|
-
rec
|
|
97
|
+
rec.score = {}.merge( rec.score||{}, score_more )
|
|
93
98
|
end
|
|
94
99
|
|
|
95
100
|
|
|
101
|
+
## reuse generated output from report
|
|
102
|
+
report = MatchReport.build( live, timeline )
|
|
96
103
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
104
|
+
############
|
|
105
|
+
## add goals
|
|
100
106
|
|
|
101
|
-
if goals1.empty? && goals2.empty?
|
|
107
|
+
if report.goals1.empty? && report.goals2.empty?
|
|
102
108
|
## skip if no goals
|
|
103
109
|
else
|
|
104
|
-
rec
|
|
105
|
-
rec
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
110
|
+
rec.goals1 = report.goals1
|
|
111
|
+
rec.goals2 = report.goals2
|
|
109
112
|
end
|
|
110
113
|
|
|
111
114
|
|
|
112
115
|
#########
|
|
113
|
-
##
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
sentoff1 = (report[:red1]||[]) + (report[:yellowred1]||[])
|
|
119
|
-
sentoff2 = (report[:red2]||[]) + (report[:yellowred2]||[])
|
|
120
|
-
|
|
121
|
-
## sort by minute
|
|
122
|
-
sentoff1 = sentoff1.sort { |l,r| l[:minute] <=> r[:minute] }
|
|
123
|
-
sentoff2 = sentoff2.sort { |l,r| l[:minute] <=> r[:minute] }
|
|
116
|
+
## add penalties
|
|
117
|
+
rec.penalties = report.penalties if report.penalties &&
|
|
118
|
+
!report.penalties.empty?
|
|
124
119
|
|
|
125
|
-
rec[:sentoff1] = sentoff1 unless sentoff1.empty?
|
|
126
|
-
rec[:sentoff2] = sentoff2 unless sentoff2.empty?
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
=begin
|
|
132
|
-
"Officials":
|
|
133
|
-
[{"IdCountry": "BRA",
|
|
134
|
-
"OfficialId": "361561",
|
|
135
|
-
"NameShort": [{"Locale": "en-GB", "Description": "Wilton SAMPAIO"}],
|
|
136
|
-
"Name": [{"Locale": "en-GB", "Description": "Wilton SAMPAIO"}],
|
|
137
|
-
"OfficialType": 1,
|
|
138
|
-
"TypeLocalized": [{"Locale": "en-GB", "Description": "Referee"}]},
|
|
139
|
-
{"IdCountry": "PAR",
|
|
140
|
-
"OfficialId": "416159",
|
|
141
|
-
"NameShort":
|
|
142
|
-
[{"Locale": "en-GB", "Description": "Juan Gabriel BENITEZ"}],
|
|
143
|
-
"Name": [{"Locale": "en-GB", "Description": "Juan Gabriel Benítez"}],
|
|
144
|
-
"OfficialType": 4,
|
|
145
|
-
"TypeLocalized":
|
|
146
|
-
[{"Locale": "en-GB", "Description": "Fourth official"}]}],
|
|
147
|
-
=end
|
|
148
|
-
|
|
149
|
-
###
|
|
150
|
-
## add referees
|
|
151
|
-
officials = build_officials( m['Officials'], id: false )
|
|
152
|
-
|
|
153
|
-
if officials.empty?
|
|
154
|
-
## puts "!! WARN no refs / officials found"
|
|
155
|
-
else
|
|
156
|
-
rec[:referees] = officials
|
|
157
|
-
end
|
|
158
120
|
|
|
121
|
+
sentoff1 = report.sentoff1
|
|
122
|
+
sentoff2 = report.sentoff2
|
|
123
|
+
rec.sentoff1 = sentoff1 unless sentoff1.empty?
|
|
124
|
+
rec.sentoff2 = sentoff2 unless sentoff2.empty?
|
|
159
125
|
|
|
126
|
+
###
|
|
127
|
+
## add referees
|
|
128
|
+
rec.officials = report.officials if report.officials && !report.officials.empty?
|
|
129
|
+
end
|
|
160
130
|
|
|
161
131
|
|
|
162
132
|
recs << rec
|
|
163
133
|
end
|
|
164
|
-
data[:matches] = recs
|
|
134
|
+
data[:matches] = recs.as_json
|
|
135
|
+
|
|
165
136
|
|
|
166
137
|
|
|
167
138
|
outpath = "#{outdir}/#{season.to_path}/#{slug}.json"
|
|
@@ -11,3 +11,15 @@ def _fmt_date_local( date_utc, date_local )
|
|
|
11
11
|
## use 20:30 UTC+1 or 20:30 UTC-3
|
|
12
12
|
"#{date_local.strftime( '%Y-%m-%d %H:%M' )} UTC%+d" % diff_in_hours
|
|
13
13
|
end
|
|
14
|
+
|
|
15
|
+
def _fmt_time_local( date_utc, date_local )
|
|
16
|
+
|
|
17
|
+
## note: returns Rational (e.g. 3/1 or 1/4 etc.) use to_f/to_i to convert
|
|
18
|
+
diff_in_hours = ((date_local - date_utc) * 24).to_f
|
|
19
|
+
diff_in_days = date_local.jd - date_utc.jd
|
|
20
|
+
## pp [diff_in_hours, diff_in_days]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
## use 20:30 UTC+1 or 20:30 UTC-3
|
|
24
|
+
"#{date_local.strftime( '%H:%M' )} UTC%+d" % diff_in_hours
|
|
25
|
+
end
|
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
|
|
2
|
+
|
|
3
|
+
def _parse_score( m )
|
|
4
|
+
h = { }
|
|
5
|
+
|
|
6
|
+
###
|
|
7
|
+
# note: for match status
|
|
8
|
+
# 1-scheduled and
|
|
9
|
+
# 2-live
|
|
10
|
+
# 7-postponed
|
|
11
|
+
# return empty score!!!
|
|
12
|
+
|
|
13
|
+
return h if m['MatchStatus'] == 1 ||
|
|
14
|
+
m['MatchStatus'] == 2 ||
|
|
15
|
+
m['MatchStatus'] == 7
|
|
16
|
+
|
|
17
|
+
|
|
2
18
|
#
|
|
3
19
|
# add quick fix for club world cup?!
|
|
4
20
|
# elsif resultType == 1 || ## assume 1 - regular (90 mins+stoppage/injury time)
|
|
@@ -6,14 +22,13 @@
|
|
|
6
22
|
# m['IdMatch'] == '400019191' ## fix for pachuca vs salzburg !!!
|
|
7
23
|
# has resultType == 0!!!
|
|
8
24
|
|
|
9
|
-
|
|
10
|
-
def _parse_score( m )
|
|
11
|
-
h = { }
|
|
12
|
-
|
|
13
25
|
m = errata_autofix_score( m )
|
|
14
26
|
|
|
15
27
|
|
|
16
28
|
resultType = m['ResultType']
|
|
29
|
+
## add score[:type] - why? why not?
|
|
30
|
+
h[:type] = RESULT_TYPE[resultType] || "???-#{resultType}"
|
|
31
|
+
|
|
17
32
|
|
|
18
33
|
score = if m['HomeTeam'] && m['AwayTeam'] ## assume inside (match) report
|
|
19
34
|
[m['HomeTeam']['Score'], m['AwayTeam']['Score']].compact
|
|
@@ -72,68 +87,96 @@ end
|
|
|
72
87
|
|
|
73
88
|
|
|
74
89
|
|
|
75
|
-
def
|
|
90
|
+
def _build_report_score( live, timeline=nil )
|
|
76
91
|
|
|
77
|
-
|
|
92
|
+
_scores = _build_score_from_goals( live )
|
|
78
93
|
|
|
79
|
-
## m = (full) match hash incl. IdMatch, etc.
|
|
80
|
-
## returns string e.g. 4-4 or 4-3 a.e.t etc
|
|
81
94
|
|
|
82
|
-
|
|
95
|
+
score = nil
|
|
83
96
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
m['AwayTeamScore']
|
|
105
|
-
""
|
|
106
|
-
else
|
|
107
|
-
raise ArgumentError, "unknown/unexpected result type #{resultType}"
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
score
|
|
111
|
-
end
|
|
97
|
+
case live['ResultType']
|
|
98
|
+
when 1,4
|
|
99
|
+
## 1 => 'REGULAR',
|
|
100
|
+
## 4 => 'REGULAR/AGG', ## aggregate (1st/2nd leg) - regular
|
|
101
|
+
## add ht
|
|
102
|
+
## assert ft match
|
|
103
|
+
score = { ht: _scores[:ht][:score],
|
|
104
|
+
ft: _scores[:ft][:score]
|
|
105
|
+
}
|
|
106
|
+
when 3,5,8
|
|
107
|
+
score = { ht: _scores[:ht][:score],
|
|
108
|
+
ft: _scores[:ft][:score],
|
|
109
|
+
et: _scores[:et][:score],
|
|
110
|
+
}
|
|
111
|
+
when 2
|
|
112
|
+
## todo/fix - pull in timeline check too to check
|
|
113
|
+
## if any events recorded for extra time!!
|
|
114
|
+
score = { ht: _scores[:ht][:score],
|
|
115
|
+
ft: _scores[:ft][:score],
|
|
116
|
+
}
|
|
112
117
|
|
|
118
|
+
## note - only incl. extra-time (et) if a goal scored in extra time
|
|
119
|
+
score[:et] = _scores[:et][:score] unless _scores[:et][:minutes].empty?
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
score
|
|
123
|
+
end
|
|
113
124
|
|
|
114
125
|
|
|
115
126
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
127
|
+
def _build_score_from_goals( m )
|
|
128
|
+
##
|
|
129
|
+
## 5 periods - 3 (1ST_HALF), 5 (2ND_HALF),
|
|
130
|
+
## 7 (EXTRA_TIME_1ST_HALF), 9 (EXTRA_TIME_2ND_HALF),
|
|
131
|
+
## 11 (PENALTY_SHOOTOUT) possibly
|
|
132
|
+
##
|
|
133
|
+
goals = {
|
|
134
|
+
count: 0,
|
|
135
|
+
score: [0,0],
|
|
136
|
+
ht: { score: [0,0], minutes: [] },
|
|
137
|
+
ft: { score: [0,0], minutes: [] },
|
|
138
|
+
et: { score: [0,0], minutes: [] },
|
|
139
|
+
p: { score: [0,0], minutes: [] },
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
## note - quick fix
|
|
143
|
+
## add period 2 for USA v Belgium (PKO) - worldcup
|
|
144
|
+
|
|
145
|
+
## note - i is 0|1 - array index for team
|
|
146
|
+
[m['HomeTeam']['Goals'],
|
|
147
|
+
m['AwayTeam']['Goals']].each_with_index do |recs,i|
|
|
148
|
+
recs.each do |h|
|
|
149
|
+
|
|
150
|
+
h = errata_autofix_goal( h )
|
|
151
|
+
|
|
152
|
+
period = h['Period']
|
|
153
|
+
## include penalty shootout (11) - why? why not?
|
|
154
|
+
assert( [3,5,7,9,11].include?(period),
|
|
155
|
+
"goal in period 3/5/7/9/11 expected; got #{h.pretty_inspect} in match #{m.pretty_inspect}" )
|
|
156
|
+
|
|
157
|
+
minute = h['Minute']
|
|
158
|
+
key = case period
|
|
159
|
+
when 3 then :ht
|
|
160
|
+
when 5 then :ft
|
|
161
|
+
when 7, 9 then :et
|
|
162
|
+
when 11 then :p
|
|
163
|
+
else
|
|
164
|
+
raise ArgumentError,
|
|
165
|
+
"goal in period 3/5/7/9/11 expected; got #{h.pretty_inspect}"
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
goals[:count] += 1
|
|
169
|
+
goals[:score][i] += 1 unless key == :p
|
|
170
|
+
goals[key][:score][i] += 1
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
## use/calc cummulative score (BUT not for penalties)
|
|
175
|
+
goals[:ft][:score][0] += goals[:ht][:score][0]
|
|
176
|
+
goals[:ft][:score][1] += goals[:ht][:score][1]
|
|
177
|
+
|
|
178
|
+
goals[:et][:score][0] += goals[:ft][:score][0]
|
|
179
|
+
goals[:et][:score][1] += goals[:ft][:score][1]
|
|
180
|
+
|
|
181
|
+
goals
|
|
182
|
+
end
|