Class: Sportradar::Api::Football::Game

Inherits:
Data
  • Object
show all
Defined in:
lib/sportradar/api/football/game.rb

Direct Known Subclasses

Ncaafb::Game, Nfl::Game

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Data

#all_attributes, #attributes, #create_data, #parse_into_array, #parse_into_array_with_options, #parse_out_hashes, #structure_links, #update_data

Constructor Details

#initialize(data, **opts) ⇒ Game

Returns a new instance of Game.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/sportradar/api/football/game.rb', line 9

def initialize(data, **opts)
  @response = data
  @api      = opts[:api]
  # @week     = opts[:week]

  @scoring_raw = Scoring.new(data, game: self)
  @home          = team_class.new({}, api: api, game: self)
  @away          = team_class.new({}, api: api, game: self)

  @updates  = {}
  @changes  = {}

  @teams_hash = {}
  @team_stats = {}
  @player_stats = StatsShim.new(self)

  @quarters_hash = {}
  @drives_hash = {}
  @score = {}

  update(data, **opts)
end

Instance Attribute Details

#apiObject

Returns the value of attribute api.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def api
  @api
end

#attendanceObject

Returns the value of attribute attendance.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def attendance
  @attendance
end

#away_idObject

Returns the value of attribute away_id.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def away_id
  @away_id
end

#broadcastObject

Returns the value of attribute broadcast.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def broadcast
  @broadcast
end

#changesObject

Returns the value of attribute changes.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def changes
  @changes
end

#clockObject

Returns the value of attribute clock.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def clock
  @clock
end

#coverageObject

Returns the value of attribute coverage.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def coverage
  @coverage
end

#durationObject

Returns the value of attribute duration.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def duration
  @duration
end

#home_idObject

Returns the value of attribute home_id.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def home_id
  @home_id
end

#idObject

Returns the value of attribute id.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def id
  @id
end

#lineupObject

Returns the value of attribute lineup.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def lineup
  @lineup
end

#player_statsObject

Returns the value of attribute player_stats.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def player_stats
  @player_stats
end

#quarterObject

Returns the value of attribute quarter.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def quarter
  @quarter
end

#responseObject

Returns the value of attribute response.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def response
  @response
end

#scheduledObject

Returns the value of attribute scheduled.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def scheduled
  @scheduled
end

#scoreObject

Returns the value of attribute score.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def score
  @score
end

#statusObject

Returns the value of attribute status.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def status
  @status
end

#team_statsObject

Returns the value of attribute team_stats.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def team_stats
  @team_stats
end

#titleObject

Returns the value of attribute title.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def title
  @title
end

#typeObject (readonly)

Returns the value of attribute type.



7
8
9
# File 'lib/sportradar/api/football/game.rb', line 7

def type
  @type
end

#venueObject

Returns the value of attribute venue.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def venue
  @venue
end

#weekObject

Returns the value of attribute week.



5
6
7
# File 'lib/sportradar/api/football/game.rb', line 5

def week
  @week
end

#week_numberObject (readonly)

Returns the value of attribute week_number.



7
8
9
# File 'lib/sportradar/api/football/game.rb', line 7

def week_number
  @week_number
end

#yearObject (readonly)

Returns the value of attribute year.



7
8
9
# File 'lib/sportradar/api/football/game.rb', line 7

def year
  @year
end

Instance Method Details

#assign_away(team) ⇒ Object



196
197
198
199
# File 'lib/sportradar/api/football/game.rb', line 196

def assign_away(team)
  @away_id = team.id
  @teams_hash[team.id] = team
end

#assign_home(team) ⇒ Object



191
192
193
194
# File 'lib/sportradar/api/football/game.rb', line 191

def assign_home(team)
  @home_id = team.id
  @teams_hash[team.id] = team
end

#awayObject



144
145
146
# File 'lib/sportradar/api/football/game.rb', line 144

def away
  @teams_hash[@away_id] || @away
end

#away_aliasObject



148
149
150
# File 'lib/sportradar/api/football/game.rb', line 148

def away_alias
  @away_alias || @away&.alias
end

#boxObject



201
202
203
# File 'lib/sportradar/api/football/game.rb', line 201

def box
  @box ||= get_box
end

#cancelled?Boolean

Returns:

  • (Boolean)


298
299
300
# File 'lib/sportradar/api/football/game.rb', line 298

def cancelled?
  ['unnecessary', 'postponed'].include? status
end

#changed?(key) ⇒ Boolean

Returns:

  • (Boolean)


249
250
251
# File 'lib/sportradar/api/football/game.rb', line 249

def changed?(key)
  @changes[key]
end

#check_newness(key, new_object) ⇒ Object



253
254
255
256
# File 'lib/sportradar/api/football/game.rb', line 253

def check_newness(key, new_object)
  @changes[key] = !not_updated?(key, new_object)
  remember(key, new_object)
end

#clock_displayObject



275
276
277
278
279
# File 'lib/sportradar/api/football/game.rb', line 275

def clock_display
  if clock && quarter
    "#{clock} #{quarter_display}"
  end
end

#closed?Boolean

Returns:

  • (Boolean)


326
327
328
# File 'lib/sportradar/api/football/game.rb', line 326

def closed?
  'closed' == status
end

#completed?Boolean

Returns:

  • (Boolean)


322
323
324
# File 'lib/sportradar/api/football/game.rb', line 322

def completed?
  'complete' == status
end

#current_possession_team_idObject



175
176
177
# File 'lib/sportradar/api/football/game.rb', line 175

def current_possession_team_id
  drives.last&.team_id
end

#delayed?Boolean

Returns:

  • (Boolean)


302
303
304
# File 'lib/sportradar/api/football/game.rb', line 302

def delayed?
  'delayed' == status
end

#drivesObject



216
217
218
# File 'lib/sportradar/api/football/game.rb', line 216

def drives
  drives_with_events.grep(Sportradar::Api::Football::Drive)
end

#drives_with_eventsObject



212
213
214
# File 'lib/sportradar/api/football/game.rb', line 212

def drives_with_events
  @drives_hash.values
end

#eventsObject



225
226
227
# File 'lib/sportradar/api/football/game.rb', line 225

def events
  drives.flat_map(&:events).compact
end

#finished?Boolean

Returns:

  • (Boolean)


318
319
320
# File 'lib/sportradar/api/football/game.rb', line 318

def finished?
  ['complete', 'closed'].include? status
end

#future?Boolean

Returns:

  • (Boolean)


306
307
308
# File 'lib/sportradar/api/football/game.rb', line 306

def future?
  ['scheduled', 'created', 'time-tbd'].include? status
end

#generate_titleObject



111
112
113
# File 'lib/sportradar/api/football/game.rb', line 111

def generate_title
  (home && away && "#{home.full_name} vs #{away.full_name}")
end

#get_boxObject

data retrieval



352
353
354
355
# File 'lib/sportradar/api/football/game.rb', line 352

def get_box
  data = api.get_data(path_box).to_h
  ingest_box(data)
end

#get_pbpObject



371
372
373
374
# File 'lib/sportradar/api/football/game.rb', line 371

def get_pbp
  data = api.get_data(path_pbp).to_h
  ingest_pbp(data)
end

#get_statisticsObject



392
393
394
395
# File 'lib/sportradar/api/football/game.rb', line 392

def get_statistics
  data = api.get_data(path_statistics).to_h
  ingest_statistics(data)
end

#get_summaryObject



397
398
399
# File 'lib/sportradar/api/football/game.rb', line 397

def get_summary
  get_statistics
end

#half_quartersObject



236
237
238
# File 'lib/sportradar/api/football/game.rb', line 236

def half_quarters
  quarters.flat_map(&:half_quarters)
end

#halftime?Boolean

Returns:

  • (Boolean)


314
315
316
# File 'lib/sportradar/api/football/game.rb', line 314

def halftime?
  'halftime' == status
end

#homeObject

def update_from_team(id, data) end



136
137
138
# File 'lib/sportradar/api/football/game.rb', line 136

def home
  @teams_hash[@home_id] || @home
end

#home_aliasObject



140
141
142
# File 'lib/sportradar/api/football/game.rb', line 140

def home_alias
  @home_alias || @home&.alias
end

#ingest_box(data) ⇒ Object



357
358
359
360
361
362
363
364
# File 'lib/sportradar/api/football/game.rb', line 357

def ingest_box(data)
  data = data
  update(data, source: :box)
  check_newness(:box, @clock)
  data
# rescue => e
#   binding.pry
end

#ingest_pbp(data) ⇒ Object



376
377
378
379
380
381
382
383
384
385
386
# File 'lib/sportradar/api/football/game.rb', line 376

def ingest_pbp(data)
  data = data
  update(data, source: :pbp)
  create_data(@quarters_hash, data[period_key], klass: quarter_class, identifier: quarter_class.period_index, api: api, game: self) if data[period_key]
  check_newness(:pbp, plays.last&.description)
  check_newness(:score, @score)
  @pbp = @quarters_hash.values
  data
# rescue => e
#   binding.pry
end

#ingest_statistics(data) ⇒ Object



406
407
408
409
410
411
412
# File 'lib/sportradar/api/football/game.rb', line 406

def ingest_statistics(data)
  update(data, source: :statistics)
  check_newness(:statistics, @clock)
  data
# rescue => e
#   binding.pry
end

#leading_teamObject



171
172
173
# File 'lib/sportradar/api/football/game.rb', line 171

def leading_team
  @teams_hash[leading_team_id] || (@away_id == leading_team_id && away) || (@home_id == leading_team_id && home)
end

#leading_team_idObject



166
167
168
169
# File 'lib/sportradar/api/football/game.rb', line 166

def leading_team_id
  return nil if tied?
  score.max_by(&:last).first
end

#next_possession_team_idObject



179
180
181
# File 'lib/sportradar/api/football/game.rb', line 179

def next_possession_team_id
  (@teams_hash.keys - [current_possession_team_id]).first || (@away_id == current_possession_team_id && @home_id) || (@home_id == current_possession_team_id && @away_id)
end

#not_updated?(key, object) ⇒ Boolean

Returns:

  • (Boolean)


245
246
247
# File 'lib/sportradar/api/football/game.rb', line 245

def not_updated?(key, object)
  @updates[key] == object
end

#parse_score(data) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/sportradar/api/football/game.rb', line 54

def parse_score(data)
  # home_id = data.dig('home', 'id')
  # away_id = data.dig('away', 'id')
  # rhe = {
  #   'runs'    => { home_id => data.dig('home', 'runs'), away_id => data.dig('away', 'runs')},
  #   'hits'    => { home_id => data.dig('home', 'hits'), away_id => data.dig('away', 'hits')},
  #   'errors'  => { home_id => data.dig('home', 'errors'), away_id => data.dig('away', 'errors')},
  # }
  # @scoring_raw.update(rhe, source: :rhe)
  # update_score(home_id => data.dig('home', 'runs'))
  # update_score(away_id => data.dig('away', 'runs'))
end

#path_boxObject

url path helpers



331
332
333
# File 'lib/sportradar/api/football/game.rb', line 331

def path_box
  "#{ path_base }/boxscore"
end

#path_extended_boxObject



334
335
336
# File 'lib/sportradar/api/football/game.rb', line 334

def path_extended_box
  "#{ path_base }/extended-boxscore"
end

#path_pbpObject



337
338
339
# File 'lib/sportradar/api/football/game.rb', line 337

def path_pbp
  "#{ path_base }/pbp"
end

#path_rosterObject



340
341
342
# File 'lib/sportradar/api/football/game.rb', line 340

def path_roster
  "#{ path_base }/roster"
end

#path_statisticsObject



343
344
345
# File 'lib/sportradar/api/football/game.rb', line 343

def path_statistics
  "#{ path_base }/statistics"
end

#path_summaryObject



346
347
348
# File 'lib/sportradar/api/football/game.rb', line 346

def path_summary
  "#{ path_base }/summary"
end

#pbpObject



205
206
207
208
209
210
# File 'lib/sportradar/api/football/game.rb', line 205

def pbp
  if !future? && quarters.empty?
    get_pbp
  end
  @pbp ||= quarters
end

#periodObject



36
37
38
# File 'lib/sportradar/api/football/game.rb', line 36

def period
  quarter
end

#period_keyObject



388
389
390
# File 'lib/sportradar/api/football/game.rb', line 388

def period_key
  'quarters'
end

#playsObject



221
222
223
# File 'lib/sportradar/api/football/game.rb', line 221

def plays
  drives.flat_map(&:plays).compact
end

#postponed?Boolean

Returns:

  • (Boolean)


290
291
292
# File 'lib/sportradar/api/football/game.rb', line 290

def postponed?
  'postponed' == status
end

#quarter_classObject



414
415
416
# File 'lib/sportradar/api/football/game.rb', line 414

def quarter_class
  Sportradar::Api::Football::Quarter
end

#quarter_displayObject



280
281
282
283
284
285
286
287
288
# File 'lib/sportradar/api/football/game.rb', line 280

def quarter_display
  if quarter > 5
    "#{quarter - 4}OT"
  elsif quarter == 5
    'OT'
  else
    "#{quarter}Q"
  end
end

#quartersObject

def summary

@summary ||= get_summary

end



233
234
235
# File 'lib/sportradar/api/football/game.rb', line 233

def quarters
  @quarters_hash.values
end

#queue_pbpObject



366
367
368
369
# File 'lib/sportradar/api/football/game.rb', line 366

def queue_pbp
  url, headers, options, timeout = api.get_request_info(path_pbp)
  {url: url, headers: headers, params: options, timeout: timeout, callback: method(:ingest_pbp)}
end

#queue_statisticsObject



401
402
403
404
# File 'lib/sportradar/api/football/game.rb', line 401

def queue_statistics
  url, headers, options, timeout = api.get_request_info(path_statistics)
  {url: url, headers: headers, params: options, timeout: timeout, callback: method(:ingest_statistics)}
end

#realtime_stateObject

status helpers



259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/sportradar/api/football/game.rb', line 259

def realtime_state
  if future?
    'Scheduled'
  elsif delayed?
    'Delayed'
  elsif finished?
    'Final'
  elsif postponed?
    'Postponed'
  elsif halftime?
    'Half'
  else
    clock_display
  end
end

#remember(key, object) ⇒ Object

tracking updates



241
242
243
# File 'lib/sportradar/api/football/game.rb', line 241

def remember(key, object)
  @updates[key] = object&.dup
end

#scoringObject



155
156
157
# File 'lib/sportradar/api/football/game.rb', line 155

def scoring
  @scoring_raw.scores
end

#sim!Object



422
423
424
425
# File 'lib/sportradar/api/football/game.rb', line 422

def sim!
  @api = api.sim!
  self
end

#started?Boolean

Returns:

  • (Boolean)


310
311
312
# File 'lib/sportradar/api/football/game.rb', line 310

def started?
  ['inprogress', 'halftime', 'wdelay', 'delayed'].include? status
end

#stats(team_id) ⇒ Object



43
44
45
# File 'lib/sportradar/api/football/game.rb', line 43

def stats(team_id)
  team_id.is_a?(Symbol) ? @team_stats[@team_ids[team_id]] : @team_stats[team_id]
end

#summary_stat(team_id, stat_name) ⇒ Object



40
41
42
# File 'lib/sportradar/api/football/game.rb', line 40

def summary_stat(team_id, stat_name)
  scoring.dig(team_id, stat_name)
end

#team(team_id) ⇒ Object



187
188
189
# File 'lib/sportradar/api/football/game.rb', line 187

def team(team_id)
  @teams_hash[team_id]
end

#team_classObject



418
419
420
# File 'lib/sportradar/api/football/game.rb', line 418

def team_class
  Team
end

#team_idsObject



183
184
185
# File 'lib/sportradar/api/football/game.rb', line 183

def team_ids
  @teams_hash.keys
end

#tied?Boolean

Returns:

  • (Boolean)


152
153
154
# File 'lib/sportradar/api/football/game.rb', line 152

def tied?
  @score[away_id].to_i == @score[home_id].to_i
end

#timeoutsObject



32
33
34
# File 'lib/sportradar/api/football/game.rb', line 32

def timeouts
  @teams_hash.map { |t_id, team| [t_id, team.timeouts] }.to_h
end

#unnecessary?Boolean

Returns:

  • (Boolean)


294
295
296
# File 'lib/sportradar/api/football/game.rb', line 294

def unnecessary?
  'unnecessary' == status
end

#update(data, source: nil, **opts) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/sportradar/api/football/game.rb', line 67

def update(data, source: nil, **opts)
  @id           = data['id'] || @id
  # @year          = data['year'] || @week&.season.year
  # @type          = data['type'] || @week&.season.type
  # @week_number   = data['week'] || @week&.sequence

  @week_number = data['week_number']  || week&.number || opts[:week]&.number  || @week_number
  @year        = data['year']         || week&.year   || opts[:week]&.year    || @year
  @type        = data['type']         || week&.type   || opts[:week]&.type    || @type


  @coverage      = data['coverage']
  @scheduled     = Time.parse(data["scheduled"]) if data["scheduled"]
  update_teams(data)
  @status        = data['status']  || @status
  @clock         = data['clock']   || @clock
  @quarter       = data['quarter'] || @quarter
  @home_rotation = data['home_rotation']
  @away_rotation = data['away_rotation']
  @neutral_site  = data['neutral_site']
  @home_points   = data['home_points']
  @away_points   = data['away_points']
  @venue         = Venue.new(data["venue"]) if data["venue"]
  @weather       = data['weather']
  @broadcast     = Broadcast.new(data['broadcast']) if !data['broadcast'].to_h.empty?
  @attendance    = data['attendance']
  @title        = data['title'] || @title || generate_title

  # @links         = data['links'] ? structure_links(data['links']) : {}

  @teams_hash    = { @home.id => @home, @away.id => @away } if @home.id && @away.id
  @team_ids      = { home: (@home&.id || home_alias), away: (@away&.id || away_alias) }

  @scoring_raw.update(data, source: source)
  if data['statistics']
    @home.update({ 'statistics' => data.dig('statistics', 'home')}, game: self)
    @away.update({ 'statistics' => data.dig('statistics', 'away')}, game: self)
  end

  create_data(@teams_hash, data['team'], klass: team_class, api: api, game: self) if data['team']

  self
end

#update_drives(data, **opts) ⇒ Object



162
163
164
# File 'lib/sportradar/api/football/game.rb', line 162

def update_drives(data, **opts)
  create_data(@drives_hash, data, klass: drive_class, api: api, game: self, **opts)
end

#update_player_stats(player, stats) ⇒ Object



50
51
52
# File 'lib/sportradar/api/football/game.rb', line 50

def update_player_stats(player, stats)
  @player_stats.merge!(player.id => stats.merge!(player: player))
end

#update_score(score) ⇒ Object



158
159
160
# File 'lib/sportradar/api/football/game.rb', line 158

def update_score(score)
  @score.merge!(score)
end

#update_stats(team, stats) ⇒ Object



47
48
49
# File 'lib/sportradar/api/football/game.rb', line 47

def update_stats(team, stats)
  @team_stats.merge!(team.id => stats)
end

#update_teams(data) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/sportradar/api/football/game.rb', line 115

def update_teams(data)
  if data['summary']
    @home.update(data.dig('summary', 'home'), game: self)
    @away.update(data.dig('summary', 'away'), game: self)
  else
    @home.update(data['home_team'], game: self) if data['home_team'].is_a?(Hash)
    @away.update(data['away_team'], game: self) if data['away_team'].is_a?(Hash)
    if data['home'].is_a?(String) # this might actually be team ID and not alias. check in NFL
      @home_alias    = data['home']
      @home.id ||= @home_alias
    end
    if data['away'].is_a?(String) # this might actually be team ID and not alias. check in NFL
      @away_alias    = data['away']
      @away.id ||= @away_alias
    end
  end
end