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
|
@@ -33,7 +33,10 @@
|
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
class Sub ## Substitution/SubOnOff Event
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def self._build_sub_minute( h )
|
|
37
40
|
|
|
38
41
|
## split into minute
|
|
39
42
|
## and offset (stoppage/injury/added time)
|
|
@@ -69,39 +72,111 @@ def _build_sub_minute( h )
|
|
|
69
72
|
end
|
|
70
73
|
|
|
71
74
|
|
|
72
|
-
|
|
73
|
-
def build_sub( h, players: )
|
|
75
|
+
def self.build( h, players: )
|
|
74
76
|
|
|
75
77
|
minute = _build_sub_minute( h )
|
|
76
78
|
|
|
77
79
|
playerOff = players.find( h['IdPlayerOff'] )
|
|
78
80
|
playerOn = players.find( h['IdPlayerOn'] )
|
|
79
81
|
|
|
82
|
+
## fix-fix-fix
|
|
83
|
+
## report warning if playerON nil!!!
|
|
80
84
|
## use N.N. for nil - why? why not?
|
|
81
|
-
playerOn =
|
|
85
|
+
playerOn = Player::PLAYER_NIL if playerOn.nil?
|
|
82
86
|
|
|
83
87
|
assert( playerOff && playerOn,
|
|
84
88
|
"playerOff and/or playerOn is NIL in #{h.pretty_inspect}")
|
|
85
89
|
|
|
86
|
-
rec = { off: playerOff
|
|
87
|
-
on: playerOn
|
|
90
|
+
rec = { off: playerOff,
|
|
91
|
+
on: playerOn,
|
|
88
92
|
minute: minute
|
|
89
93
|
}
|
|
90
94
|
|
|
91
|
-
rec
|
|
95
|
+
new( **rec )
|
|
92
96
|
end
|
|
93
97
|
|
|
94
98
|
|
|
95
99
|
|
|
96
|
-
def
|
|
97
|
-
recs = recs.map { |h|
|
|
100
|
+
def self._build_ary( recs, players: )
|
|
101
|
+
recs = recs.map { |h| build( h, players: players ) }
|
|
98
102
|
recs
|
|
99
103
|
end
|
|
100
104
|
|
|
101
105
|
|
|
106
|
+
|
|
107
|
+
attr_reader :off, :on, :minute
|
|
108
|
+
|
|
109
|
+
def initialize( off:, on:, minute: )
|
|
110
|
+
@off = off
|
|
111
|
+
@on = on
|
|
112
|
+
@minute = minute
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def as_json(*)
|
|
116
|
+
h = {
|
|
117
|
+
'off' => off.name,
|
|
118
|
+
'on' => on.name,
|
|
119
|
+
'minute' => minute
|
|
120
|
+
}
|
|
121
|
+
h
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
end ## class Sub(stitution)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
|
|
102
130
|
__END__
|
|
103
131
|
|
|
104
132
|
|
|
133
|
+
|
|
134
|
+
=begin
|
|
135
|
+
def add_subs( subs )
|
|
136
|
+
subs.each do |sub|
|
|
137
|
+
|
|
138
|
+
idPlayerOff = sub['IdPlayerOff']
|
|
139
|
+
idPlayerOn = sub['IdPlayerOn']
|
|
140
|
+
|
|
141
|
+
## note - parse & reformat minute for keep same format
|
|
142
|
+
minute = _build_sub_minute( sub )
|
|
143
|
+
|
|
144
|
+
player_off = @recs[ idPlayerOff ]
|
|
145
|
+
player_on = @recs[ idPlayerOn ]
|
|
146
|
+
|
|
147
|
+
##
|
|
148
|
+
## note - skip special case for now
|
|
149
|
+
## with NO PLAYER ON (e.g. idPlayerOn is nil!!)
|
|
150
|
+
## next if idPlayerOn.nil?
|
|
151
|
+
## todo/fix - report/log warning!!!
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
if player_off.nil?
|
|
155
|
+
puts "!! player_off >#{idPlayerOff}< not found in:"
|
|
156
|
+
pp sub
|
|
157
|
+
puts "---"
|
|
158
|
+
pp @recs.values
|
|
159
|
+
exit 1
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
if player_on.nil?
|
|
163
|
+
puts "!! player_on >#{idPlayerOn}< not found in:"
|
|
164
|
+
pp sub
|
|
165
|
+
puts "---"
|
|
166
|
+
pp @recs.values
|
|
167
|
+
exit 1
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
assert( player_off && player_on,
|
|
171
|
+
"subs player_off or player_on not found; sorry" )
|
|
172
|
+
|
|
173
|
+
player_off[ :sub ] = { minute: minute,
|
|
174
|
+
player_ref: player_on }
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
=end
|
|
178
|
+
|
|
179
|
+
|
|
105
180
|
!! ASSERT FAILED - playerOff and/or playerOn is NIL in {"IdEvent"=>nil,
|
|
106
181
|
"Period"=>5,
|
|
107
182
|
"Reason"=>0,
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
class Team
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def self.build( h )
|
|
7
|
+
if h
|
|
8
|
+
name = desc( h['TeamName'] )
|
|
9
|
+
## name = norm_team( name )
|
|
10
|
+
|
|
11
|
+
new( id: h['IdTeam'],
|
|
12
|
+
name: name,
|
|
13
|
+
code: h['Abbreviation'],
|
|
14
|
+
country: h['IdCountry'] ## change to cc (country code) - why? why not?
|
|
15
|
+
)
|
|
16
|
+
else ## assume nil - dummy record
|
|
17
|
+
TEAM_NIL
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
attr_reader :id, :name, :code, :country
|
|
24
|
+
|
|
25
|
+
attr_accessor :count
|
|
26
|
+
|
|
27
|
+
def initialize( name:,
|
|
28
|
+
id: nil,
|
|
29
|
+
code: nil, country: nil )
|
|
30
|
+
@name = name
|
|
31
|
+
@id = id
|
|
32
|
+
@code = code
|
|
33
|
+
@country = country
|
|
34
|
+
|
|
35
|
+
@count = Hash.new(0) ## match (reference/usage) count(er) by stage (name)!!
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
## shared dummy/nil record
|
|
40
|
+
TEAM_NIL = self.new( id: '<nil>',
|
|
41
|
+
name: '?',
|
|
42
|
+
code: '?', ## use nil - why? why not?
|
|
43
|
+
country: '?' ) ## use nil - why? why not?
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
=begin
|
|
48
|
+
!! ASSERT FAILED - team records NOT matching -
|
|
49
|
+
{:id=>"44129",
|
|
50
|
+
:name=>"Vasco da Gama",
|
|
51
|
+
:code=>"VDG",
|
|
52
|
+
:country=>"BRA",
|
|
53
|
+
:count=>7}
|
|
54
|
+
!=
|
|
55
|
+
{:id=>"44129",
|
|
56
|
+
:name=>"Vasco da Gama",
|
|
57
|
+
:code=>"VAS",
|
|
58
|
+
:country=>"BRA"}
|
|
59
|
+
=end
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def ==(other)
|
|
63
|
+
return false unless other.is_a?(Team)
|
|
64
|
+
|
|
65
|
+
## check code too - why? why not?
|
|
66
|
+
## note - ignore code for now
|
|
67
|
+
self.id == other.id &&
|
|
68
|
+
self.name == other.name &&
|
|
69
|
+
self.country == other.country
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def as_json(*)
|
|
74
|
+
h = {
|
|
75
|
+
'name' => name,
|
|
76
|
+
'code' => code,
|
|
77
|
+
'country' => country,
|
|
78
|
+
'count' => count,
|
|
79
|
+
'id' => id
|
|
80
|
+
}
|
|
81
|
+
h
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
end # class Team
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#
|
|
2
|
+
# note - players here are for lineup (subs+bookings) and incl. starter/bench AND pos etc.
|
|
3
|
+
# do NOT use for team squads
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Players
|
|
9
|
+
def initialize
|
|
10
|
+
@recs = {}
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def add( recs ) ## rename to collect - why? why not?
|
|
14
|
+
recs.each do |rec|
|
|
15
|
+
raise ArgumentError,
|
|
16
|
+
"player (obj) expected; got #{rec.class.name} - #{rec.inspect}" unless rec.is_a?( Player )
|
|
17
|
+
|
|
18
|
+
rec = _add( rec )
|
|
19
|
+
rec.count += 1 ## track usage - why? why not?
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _add( new_rec )
|
|
25
|
+
rec = @recs[ new_rec.id ]
|
|
26
|
+
|
|
27
|
+
if rec.nil?
|
|
28
|
+
rec = new_rec
|
|
29
|
+
@recs[ new_rec.id ] = new_rec
|
|
30
|
+
else
|
|
31
|
+
## assert attributes equal - why? why not?
|
|
32
|
+
assert( new_rec == rec,
|
|
33
|
+
"player records NOT matching - #{rec.pretty_inspect} != #{new_rec.pretty_inspect}")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
rec
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def find( id_player )
|
|
42
|
+
rec = @recs[ id_player ]
|
|
43
|
+
rec
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def find!( id_player )
|
|
47
|
+
rec = @recs[ id_player ]
|
|
48
|
+
raise ArgumentError, "no player w/ id >#{id_player}< found; sorry" if rec.nil?
|
|
49
|
+
rec
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
###
|
|
56
|
+
## todo/check
|
|
57
|
+
## add alias (or rename) starter ??
|
|
58
|
+
## add new subs to status == 2 - why? why not?
|
|
59
|
+
def lineup
|
|
60
|
+
@recs.values.select { |rec| rec.starter? }
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def bench
|
|
64
|
+
@recs.values.select { |rec| rec.bench? }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def redcards
|
|
69
|
+
@recs.values.select { |rec| rec.red? }
|
|
70
|
+
.map { |rec| rec.r }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def yellowcards
|
|
74
|
+
@recs.values.select { |rec| rec.yellow? }
|
|
75
|
+
.map { |rec| rec.y }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def yellowredcards
|
|
79
|
+
@recs.values.select { |rec| rec.yellowred? }
|
|
80
|
+
.map { |rec| rec.yr }
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def add_bookings( bookings ) ## yellow/red cards
|
|
87
|
+
bookings.each do |b|
|
|
88
|
+
|
|
89
|
+
card = b['Card']
|
|
90
|
+
assert( [0,1,2,3].include?( card ), "card 0/1/2/3 expected; got #{b.pretty_inspect}")
|
|
91
|
+
|
|
92
|
+
##
|
|
93
|
+
## what is card 0? ignore for now
|
|
94
|
+
## Palmeiras v FC Porto 0-0 - 2025-06-15T18:00:00+00:00
|
|
95
|
+
## !! ASSERT FAILED - card 1/2/3 expected; got {"Card"=>0,
|
|
96
|
+
## "Period"=>5,
|
|
97
|
+
## "IdEvent"=>nil,
|
|
98
|
+
## "EventNumber"=>nil,
|
|
99
|
+
## "IdPlayer"=>"495048",
|
|
100
|
+
## "IdCoach"=>nil,
|
|
101
|
+
## "IdTeam"=>"1884426",
|
|
102
|
+
## "Minute"=>"72'",
|
|
103
|
+
## "Reason"=>nil}
|
|
104
|
+
next if card == 0
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
idPlayer = b['IdPlayer']
|
|
108
|
+
|
|
109
|
+
## booking (card) for coach or stuff!!!!
|
|
110
|
+
## skip for now
|
|
111
|
+
next if idPlayer.nil? && (b['IdCoach'] || b['IdStaff'])
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
player = @recs[ idPlayer ]
|
|
115
|
+
assert( player, "booking player not found; sorry - #{b.pretty_inspect}" )
|
|
116
|
+
|
|
117
|
+
## note - parse & reformat minute for keep same format
|
|
118
|
+
## _fmt_minute( *_parse_minute( b['Minute'] ))
|
|
119
|
+
minute = _build_minute( b )
|
|
120
|
+
|
|
121
|
+
if card == 1 ## yellow
|
|
122
|
+
player.y = Player::Card.new( player: player, type: 'Y', minute: minute )
|
|
123
|
+
elsif card == 2 ## red
|
|
124
|
+
player.r = Player::Card.new( player: player, type: 'R', minute: minute )
|
|
125
|
+
elsif card == 3 ## yellow/red
|
|
126
|
+
player.yr = Player::Card.new( player: player, type: 'YR', minute: minute )
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def dump
|
|
134
|
+
pp @recs.values
|
|
135
|
+
puts " #{@recs.size} player(s)"
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def size() @recs.size; end
|
|
139
|
+
|
|
140
|
+
end # class Players
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Stadiums
|
|
5
|
+
def initialize
|
|
6
|
+
@recs = {}
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def add_matches( matches ) ## rename to add_matches - why? why not?
|
|
10
|
+
matches.each_with_index do |m|
|
|
11
|
+
stadium = Stadium.build( m['Stadium'] )
|
|
12
|
+
rec = _add( stadium )
|
|
13
|
+
|
|
14
|
+
## update match counter by team
|
|
15
|
+
team_name = desc(m['Home']['TeamName'])
|
|
16
|
+
rec.count[ team_name ] += 1
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _add( new_rec )
|
|
23
|
+
rec = @recs[ new_rec.id ]
|
|
24
|
+
if rec.nil?
|
|
25
|
+
rec = new_rec
|
|
26
|
+
@recs[ new_rec.id] = new_rec
|
|
27
|
+
else
|
|
28
|
+
## assert attributes equal - why? why not?
|
|
29
|
+
assert( new_rec == rec,
|
|
30
|
+
"stadium records NOT matching - #{rec.pretty_inspect} != #{new_rec.pretty_inspect}")
|
|
31
|
+
end
|
|
32
|
+
rec
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def find!( h )
|
|
38
|
+
if h
|
|
39
|
+
name = desc( h['Name'] )
|
|
40
|
+
city = desc( h['CityName'] )
|
|
41
|
+
## auto-generate id
|
|
42
|
+
## use slug of name plus id_city
|
|
43
|
+
## add city name
|
|
44
|
+
## fix- add 0-9 & dash(-) to name too - why? why not?
|
|
45
|
+
id = name.downcase.gsub( /[^a-z]/, '' )
|
|
46
|
+
id += "_" + city.downcase.gsub( /[^a-z]/, '' )
|
|
47
|
+
else
|
|
48
|
+
puts "warn: empty stadium lookup:"
|
|
49
|
+
pp h
|
|
50
|
+
id = '<nil>'
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
## check for nil - why? why not?
|
|
54
|
+
rec = @recs[ id ]
|
|
55
|
+
if rec.nil?
|
|
56
|
+
puts "#{@recs.size} stadiums:"
|
|
57
|
+
pp @recs.keys
|
|
58
|
+
raise ArgumentError, "stadium not found using >#{id}< - #{h.pretty_inspect}"
|
|
59
|
+
end
|
|
60
|
+
rec
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def as_json( id: false ) ## note ignore remove id for now
|
|
66
|
+
@recs.values.as_json
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def size() @recs.size; end
|
|
70
|
+
|
|
71
|
+
end # class Stadiums
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Stages
|
|
5
|
+
|
|
6
|
+
def self.read( path )
|
|
7
|
+
data = read_json_v2( path )
|
|
8
|
+
obj = new
|
|
9
|
+
obj.add( data['Results'] )
|
|
10
|
+
obj
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def initialize
|
|
15
|
+
@recs = {}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def add( recs ) ## rename to collect - why? why not?
|
|
19
|
+
recs.each { |h| _add( Stage.build(h)) }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _add( new_rec )
|
|
24
|
+
rec = @recs[ new_rec.name ]
|
|
25
|
+
if rec.nil?
|
|
26
|
+
@recs[ new_rec.name ] = new_rec
|
|
27
|
+
else
|
|
28
|
+
raise ArgumentError, "duplicate stage entry: #{new_rec.pretty_inspect}"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
## add match stats
|
|
34
|
+
def add_matches( matches )
|
|
35
|
+
matches.each do |m|
|
|
36
|
+
name = desc( m['StageName'] )
|
|
37
|
+
rec = find!( name )
|
|
38
|
+
rec.count += 1
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def find!( name )
|
|
44
|
+
rec = @recs[ name ]
|
|
45
|
+
raise ArgumentError, "no stage w/ name >#{name}< found; sorry" if rec.nil?
|
|
46
|
+
rec
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def as_json(*)
|
|
50
|
+
## note - sort by seq
|
|
51
|
+
@recs.values.sort do |l,r|
|
|
52
|
+
l.seq <=> r.seq
|
|
53
|
+
end.as_json
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def size() @recs.size; end
|
|
57
|
+
|
|
58
|
+
end # class Stages
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Teams ## use/change to TeamsRegistry, TeamsLookup, etc
|
|
5
|
+
def initialize
|
|
6
|
+
@recs = {}
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def add_matches( matches )
|
|
10
|
+
## note - if team nil - will (auto-)add nil team (<nil>,?,?,?)
|
|
11
|
+
matches.each do |m|
|
|
12
|
+
rec1 = _add( Team.build( m['Home'] ) )
|
|
13
|
+
rec2 = _add( Team.build( m['Away'] ) )
|
|
14
|
+
|
|
15
|
+
stage_name = desc(m['StageName'])
|
|
16
|
+
rec1.count[stage_name] += 1
|
|
17
|
+
rec2.count[stage_name] += 1
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _add( new_rec )
|
|
24
|
+
rec = @recs[ new_rec.id ]
|
|
25
|
+
if rec.nil?
|
|
26
|
+
rec = new_rec
|
|
27
|
+
@recs[ new_rec.id ] = new_rec
|
|
28
|
+
else
|
|
29
|
+
## assert attributes equal - why? why not?
|
|
30
|
+
assert( new_rec == rec,
|
|
31
|
+
"team records NOT matching - #{rec.pretty_inspect} != #{new_rec.pretty_inspect}")
|
|
32
|
+
end
|
|
33
|
+
rec
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def find!( h )
|
|
38
|
+
## team1 = teams.find( m['HomeTeam'] )
|
|
39
|
+
## team2 = teams.find( m['AwayTeam'] )
|
|
40
|
+
## use lookup by "IdTeam": "33161" for now - why? why not?
|
|
41
|
+
|
|
42
|
+
## check for nil - why? why not?
|
|
43
|
+
rec = @recs[ h['IdTeam'] ]
|
|
44
|
+
raise ArgumentError, "team not found using #{h.pretty_inspect} " if rec.nil?
|
|
45
|
+
rec
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def as_json( id: false ) ## note ignore remove id for now
|
|
52
|
+
@recs.values.as_json
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def size() @recs.size; end
|
|
56
|
+
|
|
57
|
+
end # class Teams
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fifadat-convert
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0
|
|
4
|
+
version: 0.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Gerald Bauer
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: fifadat
|
|
@@ -74,26 +74,30 @@ files:
|
|
|
74
74
|
- Rakefile
|
|
75
75
|
- bin/fifadat
|
|
76
76
|
- lib/fifadat/convert.rb
|
|
77
|
-
- lib/fifadat/convert/build_match.rb
|
|
78
|
-
- lib/fifadat/convert/build_report.rb
|
|
79
77
|
- lib/fifadat/convert/convert-reports.rb
|
|
80
78
|
- lib/fifadat/convert/convert.rb
|
|
81
79
|
- lib/fifadat/convert/errata.rb
|
|
82
|
-
- lib/fifadat/convert/goals-calc_score.rb
|
|
83
|
-
- lib/fifadat/convert/goals.rb
|
|
84
80
|
- lib/fifadat/convert/helper-date.rb
|
|
85
81
|
- lib/fifadat/convert/helper-minute.rb
|
|
86
82
|
- lib/fifadat/convert/helper-score.rb
|
|
87
83
|
- lib/fifadat/convert/norm.rb
|
|
88
|
-
- lib/fifadat/convert/
|
|
89
|
-
- lib/fifadat/convert/penalties.rb
|
|
90
|
-
- lib/fifadat/convert/players.rb
|
|
91
|
-
- lib/fifadat/convert/stadiums.rb
|
|
92
|
-
- lib/fifadat/convert/stages.rb
|
|
93
|
-
- lib/fifadat/convert/substitutions.rb
|
|
94
|
-
- lib/fifadat/convert/teams.rb
|
|
84
|
+
- lib/fifadat/convert/reader.rb
|
|
95
85
|
- lib/fifadat/convert/tool.rb
|
|
96
86
|
- lib/fifadat/convert/version.rb
|
|
87
|
+
- lib/fifadat/models/goal.rb
|
|
88
|
+
- lib/fifadat/models/match.rb
|
|
89
|
+
- lib/fifadat/models/match_report.rb
|
|
90
|
+
- lib/fifadat/models/official.rb
|
|
91
|
+
- lib/fifadat/models/penalty.rb
|
|
92
|
+
- lib/fifadat/models/player.rb
|
|
93
|
+
- lib/fifadat/models/stadium.rb
|
|
94
|
+
- lib/fifadat/models/stage.rb
|
|
95
|
+
- lib/fifadat/models/substitution.rb
|
|
96
|
+
- lib/fifadat/models/team.rb
|
|
97
|
+
- lib/fifadat/tables/players.rb
|
|
98
|
+
- lib/fifadat/tables/stadiums.rb
|
|
99
|
+
- lib/fifadat/tables/stages.rb
|
|
100
|
+
- lib/fifadat/tables/teams.rb
|
|
97
101
|
- lib/fifadata-convert.rb
|
|
98
102
|
homepage: https://github.com/sportdb/sport.db
|
|
99
103
|
licenses:
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def _build_match( m ) ## use _fill/build_match_basics() or such ???
|
|
5
|
-
rec = {}
|
|
6
|
-
|
|
7
|
-
## 0 => FINISHED/complete (OK)
|
|
8
|
-
## 1 => SCHEDULED/not yet played
|
|
9
|
-
status = m['MatchStatus']
|
|
10
|
-
timed = m['TimeDefined']
|
|
11
|
-
|
|
12
|
-
if status == 1 && timed ## note: use TIMED (instead of SCHEDULED)
|
|
13
|
-
rec[:status] = 'TIMED'
|
|
14
|
-
else
|
|
15
|
-
rec[:status] = MATCH_STATUS[ status ] || "#{status}-???"
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
rec[:stage] = desc( m['StageName'] )
|
|
21
|
-
|
|
22
|
-
## check optional group, matchday, (match) num
|
|
23
|
-
## note - matchday is a string!! (check if always a number)
|
|
24
|
-
## ## convert to int if str - why? why not??
|
|
25
|
-
group = desc( m['GroupName'] )
|
|
26
|
-
rec[:group] = group if group
|
|
27
|
-
|
|
28
|
-
matchday = m['MatchDay']
|
|
29
|
-
rec[:matchday] = matchday.to_i(10) if matchday
|
|
30
|
-
|
|
31
|
-
num = m['MatchNumber']
|
|
32
|
-
rec[:num] = num if num
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
dateTime = parse_date_utc( m['Date'] )
|
|
36
|
-
localDateTime = parse_date_utc( m['LocalDate'] )
|
|
37
|
-
|
|
38
|
-
if timed
|
|
39
|
-
## pass along as is for now - why? why not
|
|
40
|
-
## note - Date is date_utc and
|
|
41
|
-
## LocalDate is date_local (also in utc BUT different HH:MM or possible day)
|
|
42
|
-
## note - also in utc, that is, timezone is Z (not +03:00 or such!!!)
|
|
43
|
-
|
|
44
|
-
## note - use datetime - why? why not?
|
|
45
|
-
##
|
|
46
|
-
## note - cut-off/remove seconds
|
|
47
|
-
rec[:datetime_utc] = dateTime.strftime( '%Y-%m-%dT%H:%MZ' )
|
|
48
|
-
|
|
49
|
-
## note - use 20:30 UTC+1 or 20:30 UTC-3 for timezone format for now
|
|
50
|
-
rec[:datetime_local] = _fmt_date_local( dateTime, localDateTime )
|
|
51
|
-
else
|
|
52
|
-
rec[:date] = dateTime.strftime( '%Y-%m-%d' )
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if m['HomeTeam'] && m['AwayTeam'] ## assume match reports
|
|
58
|
-
team1 = build_team( m['HomeTeam'] )
|
|
59
|
-
team2 = build_team( m['AwayTeam'] )
|
|
60
|
-
## use full team details here (via lookup)
|
|
61
|
-
## when report (mode) - why? why not?
|
|
62
|
-
rec[:team1] = team1[:name]
|
|
63
|
-
rec[:team2] = team2[:name]
|
|
64
|
-
else
|
|
65
|
-
team1 = build_team( m['Home'] )
|
|
66
|
-
team2 = build_team( m['Away'] )
|
|
67
|
-
rec[:team1] = team1[:name]
|
|
68
|
-
rec[:team2] = team2[:name]
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
#####
|
|
74
|
-
# handle score
|
|
75
|
-
## m = (full) match hash incl. IdMatch, etc.
|
|
76
|
-
## returns string e.g. 4-4 or 4-3 a.e.t etc
|
|
77
|
-
|
|
78
|
-
score = _parse_score( m )
|
|
79
|
-
rec[:score] = score unless score.empty?
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
## check - never in use?
|
|
83
|
-
rec[:home] = true if m['IsHome']
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
## add country to stadium too - why? why not?
|
|
87
|
-
stadium = build_stadium( m['Stadium'] )
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if m['HomeTeam'] && m['AwayTeam'] ## assume match reports
|
|
91
|
-
rec[:stadium] = { name: stadium[:name],
|
|
92
|
-
city: stadium[:city],
|
|
93
|
-
street: stadium[:street],
|
|
94
|
-
country: stadium[:country] }
|
|
95
|
-
else
|
|
96
|
-
rec[:stadium] = { name: stadium[:name],
|
|
97
|
-
city: stadium[:city] }
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
attendance = m['Attendance']
|
|
101
|
-
rec[:attendance] = attendance.to_i(10) if attendance
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
rec
|
|
105
|
-
end
|