sportradar-api 0.9.12 → 0.11.21

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.
Files changed (215) hide show
  1. checksums.yaml +4 -4
  2. data/.env.sample +6 -0
  3. data/.travis.yml +1 -0
  4. data/Gemfile.lock +32 -30
  5. data/README.md +12 -9
  6. data/lib/sportradar/api/baseball/README.md +28 -0
  7. data/lib/sportradar/api/baseball/error.rb +25 -0
  8. data/lib/sportradar/api/baseball/event.rb +44 -0
  9. data/lib/sportradar/api/baseball/events/at_bat.rb +96 -0
  10. data/lib/sportradar/api/baseball/events/lineup.rb +41 -0
  11. data/lib/sportradar/api/baseball/events/warming_up.rb +35 -0
  12. data/lib/sportradar/api/baseball/fielder.rb +26 -0
  13. data/lib/sportradar/api/baseball/game.rb +472 -0
  14. data/lib/sportradar/api/baseball/half_inning.rb +69 -0
  15. data/lib/sportradar/api/baseball/inning.rb +42 -0
  16. data/lib/sportradar/api/baseball/lineup.rb +116 -0
  17. data/lib/sportradar/api/baseball/mlb/division.rb +32 -0
  18. data/lib/sportradar/api/baseball/mlb/hierarchy.rb +273 -0
  19. data/lib/sportradar/api/baseball/mlb/league.rb +27 -0
  20. data/lib/sportradar/api/baseball/mlb.rb +84 -0
  21. data/lib/sportradar/api/baseball/outcome.rb +87 -0
  22. data/lib/sportradar/api/baseball/pitch.rb +245 -0
  23. data/lib/sportradar/api/baseball/player.rb +119 -0
  24. data/lib/sportradar/api/baseball/record.rb +42 -0
  25. data/lib/sportradar/api/baseball/runner.rb +78 -0
  26. data/lib/sportradar/api/baseball/scoring.rb +86 -0
  27. data/lib/sportradar/api/baseball/team.rb +147 -0
  28. data/lib/sportradar/api/baseball/venue.rb +51 -0
  29. data/lib/sportradar/api/baseball.rb +46 -0
  30. data/lib/sportradar/api/basketball/broadcast.rb +15 -0
  31. data/lib/sportradar/api/basketball/game.rb +339 -0
  32. data/lib/sportradar/api/basketball/injury.rb +41 -0
  33. data/lib/sportradar/api/basketball/nba/conference.rb +27 -0
  34. data/lib/sportradar/api/basketball/nba/division.rb +30 -0
  35. data/lib/sportradar/api/basketball/nba/game.rb +62 -0
  36. data/lib/sportradar/api/basketball/nba/hierarchy.rb +47 -0
  37. data/lib/sportradar/api/basketball/nba/player.rb +160 -0
  38. data/lib/sportradar/api/basketball/nba/quarter.rb +51 -0
  39. data/lib/sportradar/api/basketball/nba/schedule.rb +43 -0
  40. data/lib/sportradar/api/basketball/nba/scoring.rb +15 -0
  41. data/lib/sportradar/api/basketball/nba/season.rb +54 -0
  42. data/lib/sportradar/api/basketball/nba/series.rb +82 -0
  43. data/lib/sportradar/api/basketball/nba/team.rb +74 -0
  44. data/lib/sportradar/api/basketball/nba.rb +129 -0
  45. data/lib/sportradar/api/basketball/ncaamb/bracket.rb +44 -0
  46. data/lib/sportradar/api/basketball/ncaamb/conference.rb +41 -0
  47. data/lib/sportradar/api/basketball/ncaamb/division.rb +42 -0
  48. data/lib/sportradar/api/basketball/ncaamb/game.rb +75 -0
  49. data/lib/sportradar/api/basketball/ncaamb/half.rb +49 -0
  50. data/lib/sportradar/api/basketball/ncaamb/hierarchy.rb +65 -0
  51. data/lib/sportradar/api/basketball/ncaamb/player.rb +162 -0
  52. data/lib/sportradar/api/basketball/ncaamb/round.rb +55 -0
  53. data/lib/sportradar/api/basketball/ncaamb/schedule.rb +41 -0
  54. data/lib/sportradar/api/basketball/ncaamb/season.rb +55 -0
  55. data/lib/sportradar/api/basketball/ncaamb/team.rb +61 -0
  56. data/lib/sportradar/api/basketball/ncaamb/tournament.rb +154 -0
  57. data/lib/sportradar/api/basketball/ncaamb.rb +149 -0
  58. data/lib/sportradar/api/basketball/play.rb +75 -0
  59. data/lib/sportradar/api/basketball/plays/assist.rb +14 -0
  60. data/lib/sportradar/api/basketball/plays/base.rb +126 -0
  61. data/lib/sportradar/api/basketball/plays/block.rb +14 -0
  62. data/lib/sportradar/api/basketball/plays/clear_path_foul.rb +11 -0
  63. data/lib/sportradar/api/basketball/plays/deadball.rb +11 -0
  64. data/lib/sportradar/api/basketball/plays/defensive_three_seconds.rb +11 -0
  65. data/lib/sportradar/api/basketball/plays/delay.rb +11 -0
  66. data/lib/sportradar/api/basketball/plays/ejection.rb +14 -0
  67. data/lib/sportradar/api/basketball/plays/end_period.rb +28 -0
  68. data/lib/sportradar/api/basketball/plays/flagrant_one.rb +11 -0
  69. data/lib/sportradar/api/basketball/plays/flagrant_two.rb +11 -0
  70. data/lib/sportradar/api/basketball/plays/foul.rb +17 -0
  71. data/lib/sportradar/api/basketball/plays/free_throw_made.rb +23 -0
  72. data/lib/sportradar/api/basketball/plays/free_throw_miss.rb +25 -0
  73. data/lib/sportradar/api/basketball/plays/jumpball.rb +12 -0
  74. data/lib/sportradar/api/basketball/plays/kickball.rb +11 -0
  75. data/lib/sportradar/api/basketball/plays/lineup_change.rb +11 -0
  76. data/lib/sportradar/api/basketball/plays/offensive_foul.rb +11 -0
  77. data/lib/sportradar/api/basketball/plays/official_timeout.rb +11 -0
  78. data/lib/sportradar/api/basketball/plays/open_inbound.rb +9 -0
  79. data/lib/sportradar/api/basketball/plays/open_tip.rb +11 -0
  80. data/lib/sportradar/api/basketball/plays/personal_foul.rb +9 -0
  81. data/lib/sportradar/api/basketball/plays/rebound.rb +28 -0
  82. data/lib/sportradar/api/basketball/plays/review.rb +11 -0
  83. data/lib/sportradar/api/basketball/plays/shooting_foul.rb +9 -0
  84. data/lib/sportradar/api/basketball/plays/shot_made.rb +22 -0
  85. data/lib/sportradar/api/basketball/plays/shot_miss.rb +22 -0
  86. data/lib/sportradar/api/basketball/plays/steal.rb +11 -0
  87. data/lib/sportradar/api/basketball/plays/team_timeout.rb +14 -0
  88. data/lib/sportradar/api/basketball/plays/technical_foul.rb +14 -0
  89. data/lib/sportradar/api/basketball/plays/three_point_made.rb +14 -0
  90. data/lib/sportradar/api/basketball/plays/three_point_miss.rb +11 -0
  91. data/lib/sportradar/api/basketball/plays/timeout.rb +24 -0
  92. data/lib/sportradar/api/basketball/plays/turnover.rb +19 -0
  93. data/lib/sportradar/api/basketball/plays/tv_timeout.rb +11 -0
  94. data/lib/sportradar/api/basketball/plays/two_point_made.rb +14 -0
  95. data/lib/sportradar/api/basketball/plays/two_point_miss.rb +11 -0
  96. data/lib/sportradar/api/basketball/plays.rb +39 -0
  97. data/lib/sportradar/api/basketball/record.rb +28 -0
  98. data/lib/sportradar/api/basketball/scoring.rb +103 -0
  99. data/lib/sportradar/api/basketball/season.rb +20 -0
  100. data/lib/sportradar/api/basketball/team.rb +136 -0
  101. data/lib/sportradar/api/basketball/venue.rb +54 -0
  102. data/lib/sportradar/api/basketball.rb +35 -0
  103. data/lib/sportradar/api/{nfl/broadcast.rb → broadcast.rb} +1 -1
  104. data/lib/sportradar/api/content/article.rb +1 -1
  105. data/lib/sportradar/api/content/article_list.rb +1 -1
  106. data/lib/sportradar/api/content.rb +17 -5
  107. data/lib/sportradar/api/data.rb +53 -0
  108. data/lib/sportradar/api/football/README.md +62 -0
  109. data/lib/sportradar/api/football/drive.rb +114 -0
  110. data/lib/sportradar/api/football/event.rb +36 -0
  111. data/lib/sportradar/api/football/game.rb +404 -0
  112. data/lib/sportradar/api/football/game_stats.rb +135 -0
  113. data/lib/sportradar/api/football/ncaafb/api.rb +81 -0
  114. data/lib/sportradar/api/football/ncaafb/conference.rb +53 -0
  115. data/lib/sportradar/api/football/ncaafb/division.rb +42 -0
  116. data/lib/sportradar/api/football/ncaafb/drive.rb +36 -0
  117. data/lib/sportradar/api/football/ncaafb/game.rb +130 -0
  118. data/lib/sportradar/api/football/ncaafb/play.rb +97 -0
  119. data/lib/sportradar/api/football/ncaafb/player.rb +31 -0
  120. data/lib/sportradar/api/football/ncaafb/quarter.rb +15 -0
  121. data/lib/sportradar/api/football/ncaafb/subdivision.rb +43 -0
  122. data/lib/sportradar/api/football/ncaafb/team.rb +49 -0
  123. data/lib/sportradar/api/football/ncaafb/week.rb +24 -0
  124. data/lib/sportradar/api/football/ncaafb.rb +273 -0
  125. data/lib/sportradar/api/football/nfl/api.rb +76 -0
  126. data/lib/sportradar/api/football/nfl/conference.rb +35 -0
  127. data/lib/sportradar/api/football/nfl/depth_chart.rb +53 -0
  128. data/lib/sportradar/api/football/nfl/division.rb +37 -0
  129. data/lib/sportradar/api/football/nfl/drive.rb +19 -0
  130. data/lib/sportradar/api/football/nfl/event.rb +19 -0
  131. data/lib/sportradar/api/football/nfl/game.rb +77 -0
  132. data/lib/sportradar/api/football/nfl/league_depth_chart.rb +41 -0
  133. data/lib/sportradar/api/football/nfl/play.rb +27 -0
  134. data/lib/sportradar/api/football/nfl/player.rb +31 -0
  135. data/lib/sportradar/api/football/nfl/quarter.rb +15 -0
  136. data/lib/sportradar/api/football/nfl/team.rb +42 -0
  137. data/lib/sportradar/api/football/nfl/team_depth_chart.rb +44 -0
  138. data/lib/sportradar/api/football/nfl/week.rb +24 -0
  139. data/lib/sportradar/api/football/nfl.rb +322 -0
  140. data/lib/sportradar/api/football/play.rb +116 -0
  141. data/lib/sportradar/api/football/play_statistics.rb +313 -0
  142. data/lib/sportradar/api/football/player.rb +121 -0
  143. data/lib/sportradar/api/football/quarter.rb +46 -0
  144. data/lib/sportradar/api/football/record.rb +48 -0
  145. data/lib/sportradar/api/football/scoring.rb +92 -0
  146. data/lib/sportradar/api/football/situation.rb +32 -0
  147. data/lib/sportradar/api/football/stat_pack/defense.rb +20 -20
  148. data/lib/sportradar/api/football/stat_pack/extra_points.rb +5 -4
  149. data/lib/sportradar/api/football/stat_pack/field_goals.rb +6 -5
  150. data/lib/sportradar/api/football/stat_pack/fumbles.rb +11 -9
  151. data/lib/sportradar/api/football/stat_pack/kick_returns.rb +8 -7
  152. data/lib/sportradar/api/football/stat_pack/kickoffs.rb +9 -7
  153. data/lib/sportradar/api/football/stat_pack/misc_returns.rb +1 -1
  154. data/lib/sportradar/api/football/stat_pack/passing.rb +13 -11
  155. data/lib/sportradar/api/football/stat_pack/penalties.rb +2 -2
  156. data/lib/sportradar/api/football/stat_pack/punt_returns.rb +7 -6
  157. data/lib/sportradar/api/football/stat_pack/punts.rb +12 -10
  158. data/lib/sportradar/api/football/stat_pack/receiving.rb +10 -9
  159. data/lib/sportradar/api/football/stat_pack/rushing.rb +11 -9
  160. data/lib/sportradar/api/football/stat_pack.rb +7 -3
  161. data/lib/sportradar/api/football/team.rb +160 -0
  162. data/lib/sportradar/api/football/venue.rb +25 -0
  163. data/lib/sportradar/api/football/week.rb +57 -0
  164. data/lib/sportradar/api/football.rb +47 -0
  165. data/lib/sportradar/api/images/asset.rb +2 -1
  166. data/lib/sportradar/api/images/ref.rb +15 -0
  167. data/lib/sportradar/api/images.rb +51 -9
  168. data/lib/sportradar/api/mma/event.rb +111 -0
  169. data/lib/sportradar/api/mma/fight.rb +107 -0
  170. data/lib/sportradar/api/mma/fighter.rb +95 -0
  171. data/lib/sportradar/api/mma/judge.rb +70 -0
  172. data/lib/sportradar/api/mma/league.rb +63 -0
  173. data/lib/sportradar/api/mma/referee.rb +70 -0
  174. data/lib/sportradar/api/mma/result.rb +68 -0
  175. data/lib/sportradar/api/mma/roster.rb +72 -0
  176. data/lib/sportradar/api/mma/schedule.rb +53 -0
  177. data/lib/sportradar/api/mma/score.rb +83 -0
  178. data/lib/sportradar/api/mma/venue.rb +72 -0
  179. data/lib/sportradar/api/mma.rb +195 -0
  180. data/lib/sportradar/api/poll.rb +40 -0
  181. data/lib/sportradar/api/request.rb +40 -8
  182. data/lib/sportradar/api/soccer/schedule.rb +1 -0
  183. data/lib/sportradar/api/version.rb +1 -1
  184. data/lib/sportradar/api.rb +20 -34
  185. metadata +157 -34
  186. data/lib/sportradar/api/nfl/.play_statistics.rb.swo +0 -0
  187. data/lib/sportradar/api/nfl/changelog.rb +0 -17
  188. data/lib/sportradar/api/nfl/coach.rb +0 -17
  189. data/lib/sportradar/api/nfl/conference.rb +0 -16
  190. data/lib/sportradar/api/nfl/depth_chart.rb +0 -47
  191. data/lib/sportradar/api/nfl/division.rb +0 -16
  192. data/lib/sportradar/api/nfl/draft.rb +0 -16
  193. data/lib/sportradar/api/nfl/drive.rb +0 -73
  194. data/lib/sportradar/api/nfl/event.rb +0 -19
  195. data/lib/sportradar/api/nfl/franchise.rb +0 -14
  196. data/lib/sportradar/api/nfl/game.rb +0 -94
  197. data/lib/sportradar/api/nfl/game_statistic.rb +0 -133
  198. data/lib/sportradar/api/nfl/hierarchy.rb +0 -19
  199. data/lib/sportradar/api/nfl/injury.rb +0 -16
  200. data/lib/sportradar/api/nfl/league_depth_chart.rb +0 -26
  201. data/lib/sportradar/api/nfl/play.rb +0 -39
  202. data/lib/sportradar/api/nfl/play_statistics.rb +0 -247
  203. data/lib/sportradar/api/nfl/player.rb +0 -49
  204. data/lib/sportradar/api/nfl/position.rb +0 -14
  205. data/lib/sportradar/api/nfl/quarter.rb +0 -29
  206. data/lib/sportradar/api/nfl/scoring.rb +0 -25
  207. data/lib/sportradar/api/nfl/season.rb +0 -23
  208. data/lib/sportradar/api/nfl/situation.rb +0 -18
  209. data/lib/sportradar/api/nfl/statistic.rb +0 -28
  210. data/lib/sportradar/api/nfl/summary.rb +0 -17
  211. data/lib/sportradar/api/nfl/team.rb +0 -56
  212. data/lib/sportradar/api/nfl/team_depth_chart.rb +0 -44
  213. data/lib/sportradar/api/nfl/venue.rb +0 -22
  214. data/lib/sportradar/api/nfl/week.rb +0 -16
  215. data/lib/sportradar/api/nfl.rb +0 -205
@@ -0,0 +1,36 @@
1
+ module Sportradar
2
+ module Api
3
+ module Football
4
+ class Event < Data
5
+ attr_accessor :response, :id, :sequence, :reference, :clock, :type, :event_type, :description, :alt_description
6
+
7
+ def initialize(data, **opts)
8
+ @response = data
9
+ @id = data["id"]
10
+ update(data, **opts)
11
+ end
12
+ def update(data, **opts)
13
+ @sequence = data["sequence"]
14
+ @reference = data["reference"]
15
+ @clock = data["clock"]
16
+ @type = data["type"]
17
+ @event_type = data["event_type"]
18
+ @description = data["description"] || data["summary"]
19
+ @alt_description = data["alt_description"]
20
+
21
+ self
22
+ end
23
+ def plays
24
+ []
25
+ end
26
+ def events
27
+ [self]
28
+ end
29
+ def over?
30
+ false # TODO
31
+ end
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,404 @@
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 period
36
+ quarter
37
+ end
38
+
39
+ def summary_stat(team_id, stat_name)
40
+ scoring.dig(team_id, stat_name)
41
+ end
42
+ def stats(team_id)
43
+ team_id.is_a?(Symbol) ? @team_stats[@team_ids[team_id]] : @team_stats[team_id]
44
+ end
45
+
46
+ def update_stats(team, stats)
47
+ @team_stats.merge!(team.id => stats)
48
+ end
49
+ def update_player_stats(player, stats)
50
+ @player_stats.merge!(player.id => stats.merge!(player: player))
51
+ end
52
+
53
+ def parse_score(data)
54
+ # home_id = data.dig('home', 'id')
55
+ # away_id = data.dig('away', 'id')
56
+ # rhe = {
57
+ # 'runs' => { home_id => data.dig('home', 'runs'), away_id => data.dig('away', 'runs')},
58
+ # 'hits' => { home_id => data.dig('home', 'hits'), away_id => data.dig('away', 'hits')},
59
+ # 'errors' => { home_id => data.dig('home', 'errors'), away_id => data.dig('away', 'errors')},
60
+ # }
61
+ # @scoring_raw.update(rhe, source: :rhe)
62
+ # update_score(home_id => data.dig('home', 'runs'))
63
+ # update_score(away_id => data.dig('away', 'runs'))
64
+ end
65
+
66
+ def update(data, source: nil, **opts)
67
+ @id = data['id'] || @id
68
+ # @year = data['year'] || @week&.season.year
69
+ # @type = data['type'] || @week&.season.type
70
+ # @week_number = data['week'] || @week&.sequence
71
+
72
+ @week_number = data['week_number'] || week&.number || opts[:week]&.number || @week_number
73
+ @year = data['year'] || week&.year || opts[:week]&.year || @year
74
+ @type = data['type'] || week&.type || opts[:week]&.type || @type
75
+
76
+
77
+ @coverage = data['coverage']
78
+ @scheduled = Time.parse(data["scheduled"]) if data["scheduled"]
79
+ update_teams(data)
80
+ @status = data['status'] || @status
81
+ @clock = data['clock'] || @clock
82
+ @quarter = data['quarter'] || @quarter
83
+ @home_rotation = data['home_rotation']
84
+ @away_rotation = data['away_rotation']
85
+ @neutral_site = data['neutral_site']
86
+ @home_points = data['home_points']
87
+ @away_points = data['away_points']
88
+ @venue = Venue.new(data["venue"]) if data["venue"]
89
+ @weather = data['weather']
90
+ @broadcast = Broadcast.new(data['broadcast']) if !data['broadcast'].to_h.empty?
91
+ @attendance = data['attendance']
92
+ @title = data['title'] || @title || generate_title
93
+
94
+ # @links = data['links'] ? structure_links(data['links']) : {}
95
+
96
+ @teams_hash = { @home.id => @home, @away.id => @away } if @home.id && @away.id
97
+ @team_ids = { home: (@home&.id || home_alias), away: (@away&.id || away_alias) }
98
+
99
+ @scoring_raw.update(data, source: source)
100
+ if data['statistics']
101
+ @home.update({ 'statistics' => data.dig('statistics', 'home')}, game: self)
102
+ @away.update({ 'statistics' => data.dig('statistics', 'away')}, game: self)
103
+ end
104
+
105
+ create_data(@teams_hash, data['team'], klass: team_class, api: api, game: self) if data['team']
106
+
107
+ self
108
+ end
109
+
110
+ def generate_title
111
+ (home && away && "#{home.full_name} vs #{away.full_name}")
112
+ end
113
+
114
+ def update_teams(data)
115
+ if data['summary']
116
+ @home.update(data.dig('summary', 'home'), game: self)
117
+ @away.update(data.dig('summary', 'away'), game: self)
118
+ else
119
+ @home.update(data['home_team'], game: self) if data['home_team'].is_a?(Hash)
120
+ @away.update(data['away_team'], game: self) if data['away_team'].is_a?(Hash)
121
+ if data['home'].is_a?(String) # this might actually be team ID and not alias. check in NFL
122
+ @home_alias = data['home']
123
+ @home.id ||= @home_alias
124
+ end
125
+ if data['away'].is_a?(String) # this might actually be team ID and not alias. check in NFL
126
+ @away_alias = data['away']
127
+ @away.id ||= @away_alias
128
+ end
129
+ end
130
+ end
131
+
132
+ # def update_from_team(id, data)
133
+ # end
134
+
135
+ def home
136
+ @teams_hash[@home_id] || @home
137
+ end
138
+
139
+ def home_alias
140
+ @home_alias || @home&.alias
141
+ end
142
+
143
+ def away
144
+ @teams_hash[@away_id] || @away
145
+ end
146
+
147
+ def away_alias
148
+ @away_alias || @away&.alias
149
+ end
150
+
151
+ def tied?
152
+ @score[away_id].to_i == @score[home_id].to_i
153
+ end
154
+ def scoring
155
+ @scoring_raw.scores
156
+ end
157
+ def update_score(score)
158
+ @score.merge!(score)
159
+ end
160
+
161
+ def leading_team_id
162
+ return nil if tied?
163
+ score.max_by(&:last).first
164
+ end
165
+
166
+ def leading_team
167
+ @teams_hash[leading_team_id] || (@away_id == leading_team_id && away) || (@home_id == leading_team_id && home)
168
+ end
169
+
170
+ def team(team_id)
171
+ @teams_hash[team_id]
172
+ end
173
+
174
+ def assign_home(team)
175
+ @home_id = team.id
176
+ @teams_hash[team.id] = team
177
+ end
178
+
179
+ def assign_away(team)
180
+ @away_id = team.id
181
+ @teams_hash[team.id] = team
182
+ end
183
+
184
+ def box
185
+ @box ||= get_box
186
+ end
187
+
188
+ def pbp
189
+ if !future? && quarters.empty?
190
+ get_pbp
191
+ end
192
+ @pbp ||= quarters
193
+ end
194
+
195
+ def drives
196
+ quarters.flat_map(&:drives).compact
197
+ end
198
+
199
+ def plays
200
+ drives.flat_map(&:plays).compact
201
+ end
202
+
203
+ def events
204
+ drives.flat_map(&:events).compact
205
+ end
206
+
207
+ # def summary
208
+ # @summary ||= get_summary
209
+ # end
210
+
211
+ def quarters
212
+ @quarters_hash.values
213
+ end
214
+ def half_quarters
215
+ quarters.flat_map(&:half_quarters)
216
+ end
217
+
218
+ # tracking updates
219
+ def remember(key, object)
220
+ @updates[key] = object&.dup
221
+ end
222
+
223
+ def not_updated?(key, object)
224
+ @updates[key] == object
225
+ end
226
+
227
+ def changed?(key)
228
+ @changes[key]
229
+ end
230
+
231
+ def check_newness(key, new_object)
232
+ @changes[key] = !not_updated?(key, new_object)
233
+ remember(key, new_object)
234
+ end
235
+
236
+ # status helpers
237
+ def realtime_state
238
+ if future?
239
+ 'Scheduled'
240
+ elsif delayed?
241
+ 'Delayed'
242
+ elsif finished?
243
+ 'Final'
244
+ elsif postponed?
245
+ 'Postponed'
246
+ elsif halftime?
247
+ 'Halftime'
248
+ else
249
+ clock_display
250
+ end
251
+ end
252
+
253
+ def clock_display
254
+ if clock && quarter
255
+ "#{clock} #{quarter_display}"
256
+ end
257
+ end
258
+ def quarter_display
259
+ if quarter > 5
260
+ "#{quarter - 4}OT"
261
+ elsif quarter == 5
262
+ 'OT'
263
+ else
264
+ "#{quarter}Q"
265
+ end
266
+ end
267
+
268
+ def postponed?
269
+ 'postponed' == status
270
+ end
271
+
272
+ def unnecessary?
273
+ 'unnecessary' == status
274
+ end
275
+
276
+ def cancelled?
277
+ ['unnecessary', 'postponed'].include? status
278
+ end
279
+
280
+ def delayed?
281
+ 'delayed' == status
282
+ end
283
+
284
+ def future?
285
+ ['scheduled', 'created', 'time-tbd'].include? status
286
+ end
287
+
288
+ def started?
289
+ ['inprogress', 'halftime', 'wdelay', 'delayed'].include? status
290
+ end
291
+
292
+ def halftime?
293
+ 'halftime' == status
294
+ end
295
+
296
+ def finished?
297
+ ['complete', 'closed'].include? status
298
+ end
299
+
300
+ def completed?
301
+ 'complete' == status
302
+ end
303
+
304
+ def closed?
305
+ 'closed' == status
306
+ end
307
+
308
+ # url path helpers
309
+ def path_box
310
+ "#{ path_base }/boxscore"
311
+ end
312
+ def path_extended_box
313
+ "#{ path_base }/extended-boxscore"
314
+ end
315
+ def path_pbp
316
+ "#{ path_base }/pbp"
317
+ end
318
+ def path_roster
319
+ "#{ path_base }/roster"
320
+ end
321
+ def path_statistics
322
+ "#{ path_base }/statistics"
323
+ end
324
+ def path_summary
325
+ "#{ path_base }/summary"
326
+ end
327
+
328
+ # data retrieval
329
+
330
+ def get_box
331
+ data = api.get_data(path_box).to_h
332
+ ingest_box(data)
333
+ end
334
+
335
+ def ingest_box(data)
336
+ data = data
337
+ update(data, source: :box)
338
+ check_newness(:box, @clock)
339
+ data
340
+ # rescue => e
341
+ # binding.pry
342
+ end
343
+
344
+ def queue_pbp
345
+ url, headers, options, timeout = api.get_request_info(path_pbp)
346
+ {url: url, headers: headers, params: options, timeout: timeout, callback: method(:ingest_pbp)}
347
+ end
348
+
349
+ def get_pbp
350
+ data = api.get_data(path_pbp).to_h
351
+ ingest_pbp(data)
352
+ end
353
+
354
+ def ingest_pbp(data)
355
+ data = data
356
+ update(data, source: :pbp)
357
+ create_data(@quarters_hash, data[period_key], klass: quarter_class, identifier: 'number', api: api, game: self) if data[period_key]
358
+ check_newness(:pbp, plays.last&.description)
359
+ check_newness(:score, @score)
360
+ @pbp = @quarters_hash.values
361
+ data
362
+ # rescue => e
363
+ # binding.pry
364
+ end
365
+
366
+ def period_key
367
+ 'quarters'
368
+ end
369
+
370
+ def get_statistics
371
+ data = api.get_data(path_statistics).to_h
372
+ ingest_statistics(data)
373
+ end
374
+
375
+ def queue_statistics
376
+ url, headers, options, timeout = api.get_request_info(path_statistics)
377
+ {url: url, headers: headers, params: options, timeout: timeout, callback: method(:ingest_statistics)}
378
+ end
379
+
380
+ def ingest_statistics(data)
381
+ update(data, source: :statistics)
382
+ check_newness(:statistics, @clock)
383
+ data
384
+ # rescue => e
385
+ # binding.pry
386
+ end
387
+
388
+ def quarter_class
389
+ Sportradar::Api::Football::Quarter
390
+ end
391
+
392
+ def team_class
393
+ Team
394
+ end
395
+
396
+ def sim!
397
+ @api = api.sim!
398
+ self
399
+ end
400
+
401
+ end
402
+ end
403
+ end
404
+ 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.dig('summary', "possession_time")
21
+ @avg_gain = data.dig('summary', "avg_gain")
22
+ @safeties = data.dig('summary', "safeties")
23
+ @turnovers = data.dig('summary', "turnovers")
24
+ @play_count = data.dig('summary', "play_count")
25
+ @rush_plays = data.dig('summary', "rush_plays")
26
+ @total_yards = data.dig('summary', "total_yards")
27
+ @lost_fumbles = data.dig('summary', "lost_fumbles")
28
+ @penalty_yards = data.dig('summary', "penalty_yards")
29
+ @return_yards = data.dig('summary', "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,81 @@
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 = default_access_level)
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 sim!
15
+ @access_level = "sim-#{default_access_level}"
16
+ self
17
+ end
18
+
19
+ def default_year
20
+ default_date.year
21
+ end
22
+ def default_date
23
+ Date.today - 90
24
+ end
25
+ def default_season
26
+ 'reg'
27
+ end
28
+ def default_access_level
29
+ if (ENV['SPORTRADAR_ENV'] || ENV['RACK_ENV'] || ENV['RAILS_ENV']) == 'production'
30
+ ENV['SPORTRADAR_ACCESS_NCAAFB'] || 'rt'
31
+ else
32
+ 't'
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def content_format
39
+ 'json'
40
+ end
41
+
42
+ def request_url(path)
43
+ "/ncaafb-#{access_level}#{version}/#{path}"
44
+ end
45
+
46
+ def api_key
47
+ if !['t', 'sim-t'].include?(access_level)
48
+ ::Sportradar::Api.api_key_params('ncaafb', 'production')
49
+ else
50
+ ::Sportradar::Api.api_key_params('ncaafb')
51
+ end
52
+ end
53
+
54
+ def version
55
+ ::Sportradar::Api.version('ncaafb')
56
+ end
57
+
58
+ def allowed_access_levels
59
+ %w[rt p s b t sim-t]
60
+ end
61
+
62
+ def allowed_seasons
63
+ ["pre", "reg", "pst"]
64
+ end
65
+ end
66
+
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ __END__
73
+
74
+ ncaafb = Sportradar::Api::Ncaafb.new
75
+ sw = ncaafb.weekly_schedule;
76
+ ss = ncaafb.schedule;
77
+
78
+ ss.games.count
79
+ ss.weeks.count
80
+ ss.weeks.first.response['game'].count
81
+
@@ -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"] || data["id"]
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
+