sportradar-api 0.10.55 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +28 -26
  3. data/README.md +7 -6
  4. data/lib/sportradar/api/baseball/{REAME.md → README.md} +0 -0
  5. data/lib/sportradar/api/baseball/game.rb +29 -2
  6. data/lib/sportradar/api/baseball/mlb/hierarchy.rb +1 -0
  7. data/lib/sportradar/api/baseball/record.rb +0 -4
  8. data/lib/sportradar/api/baseball/venue.rb +2 -1
  9. data/lib/sportradar/api/basketball/game.rb +2 -2
  10. data/lib/sportradar/api/basketball/record.rb +0 -4
  11. data/lib/sportradar/api/basketball/venue.rb +2 -1
  12. data/lib/sportradar/api/data.rb +3 -3
  13. data/lib/sportradar/api/football/README.md +62 -0
  14. data/lib/sportradar/api/football/drive.rb +105 -0
  15. data/lib/sportradar/api/football/event.rb +33 -0
  16. data/lib/sportradar/api/football/game.rb +389 -0
  17. data/lib/sportradar/api/football/game_stats.rb +135 -0
  18. data/lib/sportradar/api/football/ncaafb/api.rb +76 -0
  19. data/lib/sportradar/api/football/ncaafb/conference.rb +53 -0
  20. data/lib/sportradar/api/football/ncaafb/division.rb +42 -0
  21. data/lib/sportradar/api/football/ncaafb/drive.rb +16 -0
  22. data/lib/sportradar/api/football/ncaafb/game.rb +110 -0
  23. data/lib/sportradar/api/football/ncaafb/play.rb +20 -0
  24. data/lib/sportradar/api/football/ncaafb/player.rb +31 -0
  25. data/lib/sportradar/api/football/ncaafb/quarter.rb +15 -0
  26. data/lib/sportradar/api/football/ncaafb/subdivision.rb +43 -0
  27. data/lib/sportradar/api/football/ncaafb/team.rb +45 -0
  28. data/lib/sportradar/api/football/ncaafb/week.rb +24 -0
  29. data/lib/sportradar/api/football/ncaafb.rb +273 -0
  30. data/lib/sportradar/api/football/nfl/api.rb +76 -0
  31. data/lib/sportradar/api/football/nfl/conference.rb +35 -0
  32. data/lib/sportradar/api/football/nfl/division.rb +37 -0
  33. data/lib/sportradar/api/football/nfl/drive.rb +19 -0
  34. data/lib/sportradar/api/football/nfl/event.rb +19 -0
  35. data/lib/sportradar/api/football/nfl/game.rb +77 -0
  36. data/lib/sportradar/api/football/nfl/play.rb +20 -0
  37. data/lib/sportradar/api/football/nfl/player.rb +31 -0
  38. data/lib/sportradar/api/football/nfl/quarter.rb +15 -0
  39. data/lib/sportradar/api/football/nfl/team.rb +42 -0
  40. data/lib/sportradar/api/football/nfl/week.rb +24 -0
  41. data/lib/sportradar/api/football/nfl.rb +293 -0
  42. data/lib/sportradar/api/football/play.rb +93 -0
  43. data/lib/sportradar/api/football/player.rb +111 -0
  44. data/lib/sportradar/api/football/quarter.rb +42 -0
  45. data/lib/sportradar/api/football/record.rb +48 -0
  46. data/lib/sportradar/api/football/scoring.rb +92 -0
  47. data/lib/sportradar/api/football/situation.rb +20 -0
  48. data/lib/sportradar/api/football/stat_pack/defense.rb +20 -20
  49. data/lib/sportradar/api/football/stat_pack/extra_points.rb +5 -4
  50. data/lib/sportradar/api/football/stat_pack/field_goals.rb +6 -5
  51. data/lib/sportradar/api/football/stat_pack/fumbles.rb +11 -9
  52. data/lib/sportradar/api/football/stat_pack/kick_returns.rb +8 -7
  53. data/lib/sportradar/api/football/stat_pack/kickoffs.rb +9 -7
  54. data/lib/sportradar/api/football/stat_pack/misc_returns.rb +1 -1
  55. data/lib/sportradar/api/football/stat_pack/passing.rb +13 -11
  56. data/lib/sportradar/api/football/stat_pack/penalties.rb +2 -2
  57. data/lib/sportradar/api/football/stat_pack/punt_returns.rb +7 -6
  58. data/lib/sportradar/api/football/stat_pack/punts.rb +12 -10
  59. data/lib/sportradar/api/football/stat_pack/receiving.rb +10 -9
  60. data/lib/sportradar/api/football/stat_pack/rushing.rb +11 -9
  61. data/lib/sportradar/api/football/stat_pack.rb +7 -3
  62. data/lib/sportradar/api/football/team.rb +160 -0
  63. data/lib/sportradar/api/football/venue.rb +25 -0
  64. data/lib/sportradar/api/football/week.rb +57 -0
  65. data/lib/sportradar/api/football.rb +43 -0
  66. data/lib/sportradar/api/mma/venue.rb +1 -1
  67. data/lib/sportradar/api/request.rb +19 -2
  68. data/lib/sportradar/api/version.rb +1 -1
  69. data/lib/sportradar/api.rb +0 -41
  70. metadata +41 -43
  71. data/lib/sportradar/api/ncaafb/drive.rb +0 -89
  72. data/lib/sportradar/api/ncaafb/game.rb +0 -161
  73. data/lib/sportradar/api/ncaafb/play.rb +0 -39
  74. data/lib/sportradar/api/ncaafb/player.rb +0 -61
  75. data/lib/sportradar/api/ncaafb/quarter.rb +0 -37
  76. data/lib/sportradar/api/ncaafb/season.rb +0 -71
  77. data/lib/sportradar/api/ncaafb/team.rb +0 -69
  78. data/lib/sportradar/api/ncaafb/week.rb +0 -33
  79. data/lib/sportradar/api/ncaafb.rb +0 -185
  80. data/lib/sportradar/api/nfl/.play_statistics.rb.swo +0 -0
  81. data/lib/sportradar/api/nfl/broadcast.rb +0 -13
  82. data/lib/sportradar/api/nfl/changelog.rb +0 -17
  83. data/lib/sportradar/api/nfl/coach.rb +0 -17
  84. data/lib/sportradar/api/nfl/conference.rb +0 -17
  85. data/lib/sportradar/api/nfl/depth_chart.rb +0 -47
  86. data/lib/sportradar/api/nfl/division.rb +0 -16
  87. data/lib/sportradar/api/nfl/draft.rb +0 -16
  88. data/lib/sportradar/api/nfl/drive.rb +0 -73
  89. data/lib/sportradar/api/nfl/event.rb +0 -19
  90. data/lib/sportradar/api/nfl/franchise.rb +0 -14
  91. data/lib/sportradar/api/nfl/game.rb +0 -123
  92. data/lib/sportradar/api/nfl/game_statistic.rb +0 -133
  93. data/lib/sportradar/api/nfl/hierarchy.rb +0 -19
  94. data/lib/sportradar/api/nfl/injury.rb +0 -16
  95. data/lib/sportradar/api/nfl/league_depth_chart.rb +0 -26
  96. data/lib/sportradar/api/nfl/play.rb +0 -39
  97. data/lib/sportradar/api/nfl/play_statistics.rb +0 -249
  98. data/lib/sportradar/api/nfl/player.rb +0 -56
  99. data/lib/sportradar/api/nfl/position.rb +0 -14
  100. data/lib/sportradar/api/nfl/quarter.rb +0 -29
  101. data/lib/sportradar/api/nfl/scoring.rb +0 -25
  102. data/lib/sportradar/api/nfl/season.rb +0 -23
  103. data/lib/sportradar/api/nfl/situation.rb +0 -18
  104. data/lib/sportradar/api/nfl/statistic.rb +0 -28
  105. data/lib/sportradar/api/nfl/summary.rb +0 -17
  106. data/lib/sportradar/api/nfl/team.rb +0 -56
  107. data/lib/sportradar/api/nfl/team_depth_chart.rb +0 -44
  108. data/lib/sportradar/api/nfl/venue.rb +0 -22
  109. data/lib/sportradar/api/nfl/week.rb +0 -16
  110. data/lib/sportradar/api/nfl.rb +0 -211
@@ -0,0 +1,389 @@
1
+ module Sportradar
2
+ module Api
3
+ module Football
4
+ class Game < Data
5
+ attr_accessor :response, :id, :title, :home_id, :away_id, :score, :status, :coverage, :scheduled, :venue, :broadcast, :duration, :attendance, :team_stats, :player_stats, :changes, :lineup, :week, :quarter, :clock, :api
6
+
7
+ attr_reader :week_number, :year, :type
8
+
9
+ def initialize(data, **opts)
10
+ @response = data
11
+ @api = opts[:api]
12
+ # @week = opts[:week]
13
+
14
+ @scoring_raw = Scoring.new(data, game: self)
15
+ @home = team_class.new({}, api: api, game: self)
16
+ @away = team_class.new({}, api: api, game: self)
17
+
18
+ @updates = {}
19
+ @changes = {}
20
+
21
+ @teams_hash = {}
22
+ @team_stats = {}
23
+ @player_stats = {}
24
+
25
+ @quarters_hash = {}
26
+ @score = {}
27
+
28
+ update(data, **opts)
29
+ end
30
+
31
+ def timeouts
32
+ {}
33
+ end
34
+
35
+ def summary_stat(team_id, stat_name)
36
+ scoring.dig(team_id, stat_name)
37
+ end
38
+ def stats(team_id)
39
+ team_id.is_a?(Symbol) ? @team_stats[@team_ids[team_id]] : @team_stats[team_id]
40
+ end
41
+
42
+ def update_stats(team, stats)
43
+ @team_stats.merge!(team.id => stats)
44
+ end
45
+ def update_player_stats(player, stats)
46
+ @player_stats.merge!(player.id => stats.merge!(player: player))
47
+ end
48
+
49
+ def parse_score(data)
50
+ # home_id = data.dig('home', 'id')
51
+ # away_id = data.dig('away', 'id')
52
+ # rhe = {
53
+ # 'runs' => { home_id => data.dig('home', 'runs'), away_id => data.dig('away', 'runs')},
54
+ # 'hits' => { home_id => data.dig('home', 'hits'), away_id => data.dig('away', 'hits')},
55
+ # 'errors' => { home_id => data.dig('home', 'errors'), away_id => data.dig('away', 'errors')},
56
+ # }
57
+ # @scoring_raw.update(rhe, source: :rhe)
58
+ # update_score(home_id => data.dig('home', 'runs'))
59
+ # update_score(away_id => data.dig('away', 'runs'))
60
+ end
61
+
62
+ def update(data, source: nil, **opts)
63
+ @id = data['id'] || @id
64
+ # @year = data['year'] || @week&.season.year
65
+ # @type = data['type'] || @week&.season.type
66
+ # @week_number = data['week'] || @week&.sequence
67
+
68
+ @week_number = data['week_number'] || week&.number || opts[:week]&.number || @week_number
69
+ @year = data['year'] || week&.year || opts[:week]&.year || @year
70
+ @type = data['type'] || week&.type || opts[:week]&.type || @type
71
+
72
+
73
+ @coverage = data['coverage']
74
+ @scheduled = Time.parse(data["scheduled"]) if data["scheduled"]
75
+ update_teams(data)
76
+ @status = data['status'] || @status
77
+ @clock = data['clock'] || @clock
78
+ @quarter = data['quarter'] || @quarter
79
+ @home_rotation = data['home_rotation']
80
+ @away_rotation = data['away_rotation']
81
+ @neutral_site = data['neutral_site']
82
+ @home_points = data['home_points']
83
+ @away_points = data['away_points']
84
+ @venue = Venue.new(data["venue"]) if data["venue"]
85
+ @weather = data['weather']
86
+ @broadcast = Broadcast.new(data['broadcast']) if !data['broadcast'].to_h.empty?
87
+ @attendance = data['attendance']
88
+ @title = data['title'] || @title || generate_title
89
+
90
+ # @links = data['links'] ? structure_links(data['links']) : {}
91
+
92
+ @teams_hash = { @home.id => @home, @away.id => @away } if @home && @away
93
+ @team_ids = { home: (@home&.id || home_alias), away: (@away&.id || away_alias) }
94
+
95
+ @scoring_raw.update(data, source: source)
96
+ if data['statistics']
97
+ @home.update({ 'statistics' => data.dig('statistics', 'home')}, game: self)
98
+ @away.update({ 'statistics' => data.dig('statistics', 'away')}, game: self)
99
+ end
100
+
101
+ create_data(@teams_hash, data['team'], klass: team_class, api: api, game: self) if data['team']
102
+
103
+ self
104
+ end
105
+
106
+ def generate_title
107
+ (home && away && "#{home.full_name} vs #{away.full_name}")
108
+ end
109
+
110
+ def update_teams(data)
111
+ if data['summary']
112
+ @home.update(data.dig('summary', 'home'), game: self)
113
+ @away.update(data.dig('summary', 'away'), game: self)
114
+ else
115
+ @home.update(data['home_team'], game: self) if data['home_team'].is_a?(Hash)
116
+ @away.update(data['away_team'], game: self) if data['away_team'].is_a?(Hash)
117
+ @home_alias = data['home'] if data['home'].is_a?(String) # this might actually be team ID and not alias. check in NFL
118
+ @away_alias = data['away'] if data['away'].is_a?(String) # this might actually be team ID and not alias. check in NFL
119
+ end
120
+ end
121
+
122
+ # def update_from_team(id, data)
123
+ # end
124
+
125
+ def home
126
+ @teams_hash[@home_id] || @home
127
+ end
128
+
129
+ def home_alias
130
+ @home_alias || @home&.alias
131
+ end
132
+
133
+ def away
134
+ @teams_hash[@away_id] || @away
135
+ end
136
+
137
+ def away_alias
138
+ @away_alias || @away&.alias
139
+ end
140
+
141
+ def tied?
142
+ @score[away_id].to_i == @score[home_id].to_i
143
+ end
144
+ def scoring
145
+ @scoring_raw.scores
146
+ end
147
+ def update_score(score)
148
+ @score.merge!(score)
149
+ end
150
+
151
+ def leading_team_id
152
+ return nil if tied?
153
+ score.max_by(&:last).first
154
+ end
155
+
156
+ def leading_team
157
+ @teams_hash[leading_team_id] || (@away_id == leading_team_id && away) || (@home_id == leading_team_id && home)
158
+ end
159
+
160
+ def team(team_id)
161
+ @teams_hash[team_id]
162
+ end
163
+
164
+ def assign_home(team)
165
+ @home_id = team.id
166
+ @teams_hash[team.id] = team
167
+ end
168
+
169
+ def assign_away(team)
170
+ @away_id = team.id
171
+ @teams_hash[team.id] = team
172
+ end
173
+
174
+ def box
175
+ @box ||= get_box
176
+ end
177
+
178
+ def pbp
179
+ if !future? && quarters.empty?
180
+ get_pbp
181
+ end
182
+ @pbp ||= quarters
183
+ end
184
+
185
+ def drives
186
+ quarters.flat_map(&:drives).compact
187
+ end
188
+
189
+ def plays
190
+ drives.flat_map(&:plays).compact
191
+ end
192
+
193
+ def events
194
+ drives.flat_map(&:events).compact
195
+ end
196
+
197
+ # def summary
198
+ # @summary ||= get_summary
199
+ # end
200
+
201
+ def quarters
202
+ @quarters_hash.values
203
+ end
204
+ def half_quarters
205
+ quarters.flat_map(&:half_quarters)
206
+ end
207
+
208
+ # tracking updates
209
+ def remember(key, object)
210
+ @updates[key] = object&.dup
211
+ end
212
+
213
+ def not_updated?(key, object)
214
+ @updates[key] == object
215
+ end
216
+
217
+ def changed?(key)
218
+ @changes[key]
219
+ end
220
+
221
+ def check_newness(key, new_object)
222
+ @changes[key] = !not_updated?(key, new_object)
223
+ remember(key, new_object)
224
+ end
225
+
226
+ # status helpers
227
+ def realtime_state
228
+ if future?
229
+ 'Scheduled'
230
+ elsif delayed?
231
+ 'Delayed'
232
+ elsif finished?
233
+ 'Final'
234
+ elsif postponed?
235
+ 'Postponed'
236
+ elsif halftime?
237
+ 'Halftime'
238
+ else
239
+ clock_display
240
+ end
241
+ end
242
+
243
+ def clock_display
244
+ if clock && quarter
245
+ "#{clock} #{quarter_display}"
246
+ end
247
+ end
248
+ def quarter_display
249
+ if quarter > 5
250
+ "#{quarter - 4}OT"
251
+ elsif quarter == 5
252
+ 'OT'
253
+ else
254
+ "Q#{quarter}"
255
+ end
256
+ end
257
+
258
+ def postponed?
259
+ 'postponed' == status
260
+ end
261
+
262
+ def unnecessary?
263
+ 'unnecessary' == status
264
+ end
265
+
266
+ def cancelled?
267
+ ['unnecessary', 'postponed'].include? status
268
+ end
269
+
270
+ def delayed?
271
+ 'delayed' == status
272
+ end
273
+
274
+ def future?
275
+ ['scheduled', 'created', 'time-tbd'].include? status
276
+ end
277
+
278
+ def started?
279
+ ['inprogress', 'halftime', 'wdelay', 'delayed'].include? status
280
+ end
281
+
282
+ def halftime?
283
+ 'halftime' == status
284
+ end
285
+
286
+ def finished?
287
+ ['complete', 'closed'].include? status
288
+ end
289
+
290
+ def completed?
291
+ 'complete' == status
292
+ end
293
+
294
+ def closed?
295
+ 'closed' == status
296
+ end
297
+
298
+ # url path helpers
299
+ def path_box
300
+ "#{ path_base }/boxscore"
301
+ end
302
+ def path_extended_box
303
+ "#{ path_base }/extended-boxscore"
304
+ end
305
+ def path_pbp
306
+ "#{ path_base }/pbp"
307
+ end
308
+ def path_roster
309
+ "#{ path_base }/roster"
310
+ end
311
+ def path_statistics
312
+ "#{ path_base }/statistics"
313
+ end
314
+ def path_summary
315
+ "#{ path_base }/summary"
316
+ end
317
+
318
+ # data retrieval
319
+
320
+ def get_box
321
+ data = api.get_data(path_box).to_h
322
+ ingest_box(data)
323
+ end
324
+
325
+ def ingest_box(data)
326
+ data = data
327
+ update(data, source: :box)
328
+ check_newness(:box, @clock)
329
+ data
330
+ # rescue => e
331
+ # binding.pry
332
+ end
333
+
334
+ def queue_pbp
335
+ url, headers, options, timeout = api.get_request_info(path_pbp)
336
+ {url: url, headers: headers, params: options, timeout: timeout, callback: method(:ingest_pbp)}
337
+ end
338
+
339
+ def get_pbp
340
+ data = api.get_data(path_pbp).to_h
341
+ ingest_pbp(data)
342
+ end
343
+
344
+ def ingest_pbp(data)
345
+ data = data
346
+ update(data, source: :pbp)
347
+ create_data(@quarters_hash, data[period_key], klass: quarter_class, identifier: 'number', api: api, game: self) if data[period_key]
348
+ check_newness(:pbp, plays.last&.description)
349
+ check_newness(:score, @score)
350
+ @pbp = @quarters_hash.values
351
+ data
352
+ # rescue => e
353
+ # binding.pry
354
+ end
355
+
356
+ def period_key
357
+ 'quarters'
358
+ end
359
+
360
+ def get_statistics
361
+ data = api.get_data(path_statistics).to_h
362
+ ingest_statistics(data)
363
+ end
364
+
365
+ def queue_statistics
366
+ url, headers, options, timeout = api.get_request_info(path_statistics)
367
+ {url: url, headers: headers, params: options, timeout: timeout, callback: method(:ingest_statistics)}
368
+ end
369
+
370
+ def ingest_statistics(data)
371
+ update(data, source: :statistics)
372
+ check_newness(:statistics, @clock)
373
+ data
374
+ # rescue => e
375
+ # binding.pry
376
+ end
377
+
378
+ def quarter_class
379
+ Sportradar::Api::Football::Quarter
380
+ end
381
+
382
+ def team_class
383
+ Team
384
+ end
385
+
386
+ end
387
+ end
388
+ end
389
+ end
@@ -0,0 +1,135 @@
1
+ module Sportradar
2
+ module Api
3
+ module Football
4
+ class GameStats < Data
5
+ attr_accessor :response, :id, :efficiency, :first_downs, :interceptions, :touchdowns, :name, :market, :alias, :reference, :possession_time, :avg_gain, :safeties, :turnovers, :play_count, :rush_plays, :total_yards, :lost_fumbles, :penalty_yards, :return_yards
6
+
7
+ # attr_writer :rushing, :receiving, :punts, :punt_returns, :penalties, :passing, :misc_returns, :kickoffs, :kick_returns, :int_returns, :fumbles, :field_goals, :extra_points, :defense # probably not necessary, but leaving here in case we want it later
8
+
9
+ def initialize(data)
10
+ @response = data
11
+ @id = data["id"]
12
+ @name = data["name"]
13
+ @market = data["market"]
14
+ @alias = data["alias"]
15
+ @reference = data["reference"]
16
+ @efficiency = data["efficiency"]
17
+ @first_downs = data["first_downs"]
18
+ @interceptions = data["interceptions"]
19
+ @touchdowns = data["touchdowns"]
20
+ @possession_time = data["possession_time"]
21
+ @avg_gain = data["avg_gain"]
22
+ @safeties = data["safeties"]
23
+ @turnovers = data["turnovers"]
24
+ @play_count = data["play_count"]
25
+ @rush_plays = data["rush_plays"]
26
+ @total_yards = data["total_yards"]
27
+ @lost_fumbles = data["lost_fumbles"]
28
+ @penalty_yards = data["penalty_yards"]
29
+ @return_yards = data["return_yards"]
30
+ end
31
+
32
+ # :skip_test_coverage:
33
+ # These are in methods rather than attributes to use them lazily. Each one is tested in it's respective class
34
+ def rushing
35
+ @rushing ||= if response["rushing"]
36
+ response["rushing"] = parse_out_hashes response["rushing"]
37
+ Sportradar::Api::Football::StatPack::Rushing.new(response["rushing"])
38
+ end
39
+ end
40
+
41
+ def receiving
42
+ @receiving ||= if response["receiving"]
43
+ response["receiving"] = parse_out_hashes response["receiving"]
44
+ Sportradar::Api::Football::StatPack::Receiving.new(response["receiving"])
45
+ end
46
+ end
47
+
48
+ def punts
49
+ @punts ||= if (data = response["punts"] || response["punting"])
50
+ data = parse_out_hashes data
51
+ Sportradar::Api::Football::StatPack::Punts.new(data)
52
+ end
53
+ end
54
+
55
+ def punt_returns
56
+ @punt_returns ||= if (data = response["punt_returns"] || response["punt_return"])
57
+ data = parse_out_hashes data
58
+ Sportradar::Api::Football::StatPack::PuntReturns.new(data)
59
+ end
60
+ end
61
+
62
+ def penalties
63
+ @penalties ||= if (data = response["penalties"] || response["penalty"])
64
+ data = parse_out_hashes data
65
+ Sportradar::Api::Football::StatPack::Penalties.new(data)
66
+ end
67
+ end
68
+
69
+ def passing
70
+ @passing ||= if response["passing"]
71
+ response["passing"] = parse_out_hashes response["passing"]
72
+ Sportradar::Api::Football::StatPack::Passing.new(response["passing"])
73
+ end
74
+ end
75
+
76
+ def misc_returns
77
+ @misc_returns ||= if response["misc_returns"]
78
+ response["misc_returns"] = parse_out_hashes response["misc_returns"]
79
+ Sportradar::Api::Football::StatPack::MiscReturns.new(response["misc_returns"])
80
+ end
81
+ end
82
+
83
+ def kickoffs
84
+ @kickoffs ||= if response["kickoffs"]
85
+ response["kickoffs"] = parse_out_hashes response["kickoffs"]
86
+ Sportradar::Api::Football::StatPack::Kickoffs.new(response["kickoffs"])
87
+ end
88
+ end
89
+
90
+ def kick_returns
91
+ @kick_returns ||= if (data = response["kick_returns"] || response["kick_return"])
92
+ data = parse_out_hashes data
93
+ Sportradar::Api::Football::StatPack::KickReturns.new(data)
94
+ end
95
+ end
96
+
97
+ def int_returns
98
+ @int_returns ||= if response["int_returns"]
99
+ response["int_returns"] = parse_out_hashes response["int_returns"]
100
+ Sportradar::Api::Football::StatPack::IntReturns.new(response["int_returns"])
101
+ end
102
+ end
103
+
104
+ def fumbles
105
+ @fumbles ||= if response["fumbles"]
106
+ response["fumbles"] = parse_out_hashes response["fumbles"]
107
+ Sportradar::Api::Football::StatPack::Fumbles.new(response["fumbles"])
108
+ end
109
+ end
110
+
111
+ def field_goals
112
+ @field_goals ||= if (data = response["field_goals"] || response["field_goal"])
113
+ data = parse_out_hashes data
114
+ Sportradar::Api::Football::StatPack::FieldGoals.new(data)
115
+ end
116
+ end
117
+
118
+ def extra_points
119
+ @extra_points ||= if (data = response["extra_points"] || response["extra_point"])
120
+ data = parse_out_hashes data
121
+ Sportradar::Api::Football::StatPack::ExtraPoints.new(data)
122
+ end
123
+ end
124
+
125
+ def defense
126
+ @defense ||= if response["defense"]
127
+ response["defense"] = parse_out_hashes response["defense"]
128
+ Sportradar::Api::Football::StatPack::Defense.new(response["defense"])
129
+ end
130
+ end
131
+ # :skip_test_coverage:
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,76 @@
1
+ module Sportradar
2
+ module Api
3
+ module Football
4
+ class Ncaafb
5
+ class Api < Request
6
+ attr_accessor :league, :access_level, :error
7
+
8
+ def initialize(access_level = 't')
9
+ @league = 'ncaafb'
10
+ raise ::Sportradar::Api::Error::InvalidAccessLevel unless allowed_access_levels.include? access_level
11
+ @access_level = access_level
12
+ end
13
+
14
+ def default_year
15
+ default_date.year
16
+ end
17
+ def default_date
18
+ Date.today - 90
19
+ end
20
+ def default_season
21
+ 'reg'
22
+ end
23
+ def default_access_level
24
+ if (ENV['SPORTRADAR_ENV'] || ENV['SPORTRADAR_ENV_MLB'] || ENV['RACK_ENV'] || ENV['RAILS_ENV']) == 'production'
25
+ 'p'
26
+ else
27
+ 't'
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def content_format
34
+ 'json'
35
+ end
36
+
37
+ def request_url(path)
38
+ "/ncaafb-#{access_level}#{version}/#{path}"
39
+ end
40
+
41
+ def api_key
42
+ if !['t', 'sim-t'].include?(access_level)
43
+ ::Sportradar::Api.api_key_params('ncaafb', 'production')
44
+ else
45
+ ::Sportradar::Api.api_key_params('ncaafb')
46
+ end
47
+ end
48
+
49
+ def version
50
+ ::Sportradar::Api.version('ncaafb')
51
+ end
52
+
53
+ def allowed_access_levels
54
+ %w[rt p s b t sim-t]
55
+ end
56
+
57
+ def allowed_seasons
58
+ ["pre", "reg", "pst"]
59
+ end
60
+ end
61
+
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ __END__
68
+
69
+ ncaafb = Sportradar::Api::Ncaafb.new
70
+ sw = ncaafb.weekly_schedule;
71
+ ss = ncaafb.schedule;
72
+
73
+ ss.games.count
74
+ ss.weeks.count
75
+ ss.weeks.first.response['game'].count
76
+
@@ -0,0 +1,53 @@
1
+ module Sportradar
2
+ module Api
3
+ module Football
4
+ class Ncaafb
5
+ class Conference < Data
6
+ attr_accessor :response, :id, :name, :alias
7
+
8
+ def initialize(data, **opts)
9
+ @response = data
10
+ @api = opts[:api]
11
+
12
+ @id = data["id"]
13
+ @name = data["name"]
14
+ @alias = data["alias"]
15
+ @teams_hash = {}
16
+ @subdivisions_hash = {}
17
+ @assigned_teams = nil
18
+ # binding.pry
19
+
20
+ create_data(@teams_hash, data["teams"], klass: Team, conference: self, api: @api) if data["teams"]
21
+ create_data(@subdivisions_hash, data["subdivisions"], klass: Subdivision, conference: self, api: @api) if data["subdivisions"]
22
+ end
23
+
24
+ def teams
25
+ @assigned_teams || begin
26
+ if !@subdivisions_hash.empty?
27
+ @subdivisions_hash.each_value.flat_map(&:teams)
28
+ elsif !@teams_hash.empty?
29
+ @teams_hash.values
30
+ else
31
+ []
32
+ end
33
+ end
34
+ end
35
+ def teams=(array)
36
+ @assigned_teams = array
37
+ end
38
+ def team(code_name)
39
+ teams_by_name[code_name]
40
+ end
41
+ private def teams_by_name
42
+ @teams_by_name ||= teams.map { |t| [t.alias, t] }.to_h
43
+ end
44
+ def conferences
45
+ teams.flat_map(&:conferences)
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+
@@ -0,0 +1,42 @@
1
+ module Sportradar
2
+ module Api
3
+ module Football
4
+ class Ncaafb
5
+ class Division < Data
6
+ attr_accessor :response, :id, :name, :alias
7
+
8
+ def initialize(data, **opts)
9
+ # @response = data
10
+ @api = opts[:api]
11
+
12
+ @id = data["id"]
13
+ @name = data["name"]
14
+ @alias = data["alias"]
15
+ update(data, **opts)
16
+ end
17
+
18
+ def update(data, **opts)
19
+ @conferences_hash = create_data({}, data["conferences"], klass: Conference, division: self, api: @api) if data["conferences"]
20
+ end
21
+
22
+ def conferences
23
+ @conferences_hash.values
24
+ end
25
+
26
+ def conference(code_name)
27
+ conferences_by_name[code_name]
28
+ end
29
+
30
+ def conferences_by_name
31
+ @conferences_by_name ||= conferences.map { |c| [c.alias, c] }.to_h
32
+ end
33
+
34
+ def teams
35
+ conferences.flat_map(&:teams)
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end