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,103 @@
1
+ module Sportradar
2
+ module Api
3
+ module Basketball
4
+ class Scoring < Data
5
+ attr_accessor :response, :api, :id, :home, :away, :scores
6
+
7
+ def initialize(data, **opts)
8
+ @api = opts[:api]
9
+ @game = opts[:game]
10
+
11
+ @scores = {}
12
+ @id = data['id']
13
+
14
+ update(data, **opts)
15
+ end
16
+
17
+ def update(data, source: nil, **opts)
18
+ new_scores = case source
19
+ when :box
20
+ parse_from_box(data)
21
+ when :pbp
22
+ parse_from_pbp(data)
23
+ when :summary
24
+ parse_from_box(data)
25
+ else
26
+ if data['quarter'] || data['half']
27
+ parse_from_pbp(data)
28
+ elsif data['team']
29
+ parse_from_box(data)
30
+ else # schedule requests
31
+ {}
32
+ end
33
+ end
34
+ # parse data structure
35
+ # handle data from team (all quarters)
36
+ # handle data from quarter (both teams)
37
+ # handle data from game?
38
+ @scores.each { |k, v| v.merge!(new_scores.delete(k) || {} ) }
39
+ new_scores.each { |k, v| @scores.merge!(k => v) }
40
+ end
41
+
42
+ def points(team_id)
43
+ @score[team_id].to_i
44
+ end
45
+
46
+
47
+ private
48
+
49
+ def parse_from_box(data)
50
+ return {} if data.dig('team', 0, 'scoring').is_a?(String) || data.dig('team', 0, 'scoring').nil? # game hasn't started yet
51
+ period_name = data.dig('team', 0, 'scoring').keys.first
52
+ id = data.dig('team', 0, 'id')
53
+ da = data.dig('team', 0, 'scoring', period_name)
54
+ da_ot = data.dig('team', 0, 'scoring', 'overtime')
55
+ arr = [da].compact.flatten(1)
56
+ a = arr + [da_ot].compact.flatten(1)
57
+ a.each { |h| h[id] = h.delete('points').to_i }
58
+ id = data.dig('team', 1, 'id')
59
+ da = data.dig('team', 1, 'scoring', period_name)
60
+ da_ot = data.dig('team', 1, 'scoring', 'overtime')
61
+ arr = [da].compact.flatten(1)
62
+ b = arr + [da_ot].compact.flatten(1)
63
+ b.each { |h| h[id] = h.delete('points').to_i }
64
+ a.zip(b).map{ |a, b| [a['sequence'].to_i, a.merge(b)] }.sort{ |(a,_), (b,_)| a <=> b }.to_h
65
+ end
66
+
67
+ def parse_from_box(data)
68
+ id = data.dig('home', 'id')
69
+ # binding.pry if id
70
+ da = data.dig('home', 'scoring')
71
+ return {} unless da
72
+ da.each { |h| h[id] = h.delete('points').to_i }
73
+ id = data.dig('away', 'id')
74
+ db = data.dig('away', 'scoring')
75
+ return {} unless db
76
+ db.each { |h| h[id] = h.delete('points').to_i }
77
+ da.zip(db).map{ |a, b| [a['sequence'].to_i, a.merge(b)] }.sort{ |(a,_), (b,_)| a <=> b }.to_h
78
+ end
79
+
80
+ def parse_from_pbp(data)
81
+ period_name = data.key?('quarter') ? 'quarter' : 'half'
82
+ period_name = 'periods'
83
+ return {} unless data[period_name] # game hasn't started
84
+ quarters = data[period_name]#[1..-1]
85
+ overtimes = data['overtime']
86
+ overtimes = [overtimes] if !overtimes.is_a?(Array)
87
+ quarters = quarters[0] if (quarters.is_a?(Array) && (quarters.size == 1) && quarters.first.is_a?(Array))
88
+ data = (quarters + overtimes).compact.map{|q| q['scoring'] }
89
+ data.map.with_index(1) { |h, i| [i, { h.dig('home', 'id') => h.dig('home', 'points').to_i, h.dig('away', 'id') => h.dig('away', 'points').to_i }] }.to_h
90
+ end
91
+
92
+ # def period_name
93
+ # 'quarter'
94
+ # end
95
+
96
+ def parse_from_summary(data)
97
+ #
98
+ end
99
+
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,20 @@
1
+ module Sportradar
2
+ module Api
3
+ module Basketball
4
+ class Season < Data
5
+ attr_accessor :response
6
+
7
+ # def initialize(data, **opts)
8
+ # @response = data
9
+ # @api = opts[:api]
10
+
11
+ # @id = response['id']
12
+ # @name = response['name']
13
+ # @alias = response['alias']
14
+
15
+ # end
16
+
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,136 @@
1
+ module Sportradar
2
+ module Api
3
+ module Basketball
4
+ class Team < Data
5
+ attr_accessor :response, :id, :market, :name, :alias, :full_name, :venue, :records, :player_stats, :team_stats, :seed
6
+
7
+ def initialize(data, **opts)
8
+ @response = data
9
+ @api = opts[:api]
10
+
11
+ @games_hash = {}
12
+ @players_hash = {}
13
+ @player_stats = {}
14
+ @records = {}
15
+ @stats = nil
16
+ @points = nil
17
+
18
+ case data
19
+ when String
20
+ @id = data
21
+ when Hash
22
+ @id = data['id']
23
+ update(data, **opts)
24
+ end
25
+ end
26
+
27
+ def profile
28
+ Profile.new(self)
29
+ end
30
+
31
+ def update(data, **opts)
32
+ handle_names(data)
33
+ @venue = Venue.new(data['venue']) if data['venue']
34
+
35
+ @seed = data['seed'].to_i if data['seed']
36
+ @alias = data['alias'] if data['alias']
37
+ @points = data['points'].to_i if data['points']
38
+ # @home = data['home'] == 'true' if data['home']
39
+ # @away = data['away'] == 'true' if data['away']
40
+ # @scoring = data.dig('scoring', 'quarter') if data.dig('scoring', 'quarter')
41
+
42
+ parse_records(data) if data['records']
43
+ # binding.pry if data['players']
44
+ parse_players(data.dig('players'), opts[:game]) if data.dig('players')
45
+ # parse_stats(data['statistics']) if data['statistics']
46
+ if opts[:game]
47
+ add_game(opts[:game])
48
+ opts[:game].update_score(id => @points) if @points
49
+ opts[:game].update_stats(self, data['statistics']) if data['statistics']
50
+ end
51
+ end
52
+ def handle_names(data)
53
+ # need to do some more work here
54
+ @name = data['name'] if data['name']
55
+ if data['name'] && !data.key?('market')
56
+ @full_name = data['name']
57
+ elsif data['name'] && data['market']
58
+ @market = data['market']
59
+ @full_name = [@market, data['name']].join(' ')
60
+ end
61
+ end
62
+
63
+ def record(type = 'overall')
64
+ @records[type]
65
+ end
66
+
67
+ def games
68
+ @games_hash.values
69
+ end
70
+ def add_game(game)
71
+ @games_hash[game.id] = game.id if game
72
+ end
73
+
74
+ # def parse_stats(data)
75
+ # @stats = data
76
+ # end
77
+
78
+ def players
79
+ get_roster if @players_hash.empty?
80
+ @players_hash.values
81
+ end
82
+ alias :roster :players
83
+ def parse_players(data, game)
84
+ create_data(@players_hash, data, klass: player_class, api: api, team: self, game: game)
85
+ end
86
+ def update_player_stats(player, stats, game = nil)
87
+ game ? game.update_player_stats(player, stats) : @player_stats.merge!(player.id => stats.merge!(player: player))
88
+ end
89
+
90
+ def get_roster
91
+ data = api.get_data(path_roster)
92
+ ingest_roster(data)
93
+ end
94
+ def ingest_roster(data)
95
+ update(data)
96
+ data
97
+ end
98
+
99
+ def get_season_stats
100
+ data = api.get_data(path_season_stats)
101
+ ingest_season_stats(data)
102
+ end
103
+ def ingest_season_stats(data)
104
+ parse_season_stats(data)
105
+ end
106
+
107
+ def parse_records(data)
108
+ @records['overall'] = Record.new(data, type: 'overall')
109
+ data['records'].each { |record| @records[record['record_type']] = Record.new(record, type: record['record_type']) }
110
+ end
111
+
112
+ def parse_season_stats(data)
113
+ @team_stats = data.dig('own_record')
114
+ update(data)
115
+ player_data = data.dig('players')
116
+ create_data(@players_hash, player_data, klass: player_class, api: api, team: self)
117
+ data
118
+ end
119
+
120
+ def path_base
121
+ "teams/#{ id }"
122
+ end
123
+ def path_base_stats(season_year = api.default_year, default_season = api.default_season)
124
+ "seasontd/#{season_year}/#{default_season}/teams/#{id}"
125
+ end
126
+ def path_roster
127
+ "#{ path_base }/profile"
128
+ end
129
+ def path_season_stats
130
+ "#{ path_base_stats }/statistics"
131
+ end
132
+
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,54 @@
1
+ module Sportradar
2
+ module Api
3
+ module Basketball
4
+ class Venue < Data
5
+ attr_accessor :response, :id, :name, :address, :city, :state, :country, :zip, :capacity, :timezone
6
+ @all_hash = {}
7
+ def self.new(data, **opts)
8
+ existing = @all_hash[data['id']]
9
+ if existing
10
+ existing.update(data, **opts)
11
+ existing
12
+ else
13
+ @all_hash[data['id']] = super
14
+ end
15
+ end
16
+ def self.all
17
+ @all_hash.values
18
+ end
19
+
20
+ def initialize(data, **opts)
21
+ @response = data
22
+ @id = data["id"]
23
+
24
+ update(data, **opts)
25
+ end
26
+ def update(data, **opts)
27
+ @name = data['name']
28
+ @address = data['address']
29
+ @city = data['city']
30
+ @state = data['state']
31
+ @zip = data['zip']
32
+ @country = data['country']
33
+ @capacity = data['capacity']
34
+ @timezone = data['timezone']
35
+ end
36
+
37
+ def location
38
+ "#{name}, #{city}"
39
+ end
40
+
41
+ KEYS_SCHEDULE = ["id", "name", "capacity", "address", "city", "state", "zip", "country"]
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ __END__
48
+
49
+ sr = Sportradar::Api::Nba.new
50
+ lh = sr.league_hierarchy;
51
+ t = lh.teams.first;
52
+ t.venue.id
53
+ t.venue.name
54
+ t.venue.city
@@ -0,0 +1,35 @@
1
+ require_relative 'basketball/season'
2
+ require_relative 'basketball/game'
3
+ require_relative 'basketball/team'
4
+ require_relative 'basketball/record'
5
+ require_relative 'basketball/venue'
6
+ require_relative 'basketball/broadcast'
7
+ require_relative 'basketball/injury'
8
+ require_relative 'basketball/plays'
9
+ require_relative 'basketball/scoring'
10
+
11
+ require_relative 'basketball/nba'
12
+ require_relative 'basketball/nba/hierarchy'
13
+ require_relative 'basketball/nba/conference'
14
+ require_relative 'basketball/nba/division'
15
+ require_relative 'basketball/nba/season'
16
+ require_relative 'basketball/nba/series'
17
+ require_relative 'basketball/nba/schedule'
18
+ require_relative 'basketball/nba/game'
19
+ require_relative 'basketball/nba/team'
20
+ require_relative 'basketball/nba/player'
21
+ require_relative 'basketball/nba/quarter'
22
+
23
+ require_relative 'basketball/ncaamb'
24
+ require_relative 'basketball/ncaamb/season'
25
+ require_relative 'basketball/ncaamb/schedule'
26
+ require_relative 'basketball/ncaamb/tournament'
27
+ require_relative 'basketball/ncaamb/round'
28
+ require_relative 'basketball/ncaamb/bracket'
29
+ require_relative 'basketball/ncaamb/game'
30
+ require_relative 'basketball/ncaamb/half'
31
+ require_relative 'basketball/ncaamb/hierarchy'
32
+ require_relative 'basketball/ncaamb/division'
33
+ require_relative 'basketball/ncaamb/conference'
34
+ require_relative 'basketball/ncaamb/team'
35
+ require_relative 'basketball/ncaamb/player'
@@ -1,6 +1,6 @@
1
1
  module Sportradar
2
2
  module Api
3
- class Nfl::Broadcast < Data
3
+ class Broadcast < Data
4
4
  attr_accessor :response, :network
5
5
 
6
6
  def initialize(data)
@@ -16,7 +16,7 @@ module Sportradar
16
16
  @credit = data["credit"]
17
17
  @content = data["content"]["long"] if data["content"] && data["content"]["long"]
18
18
  @provider = OpenStruct.new(data["provider"]) if data["provider"]
19
- @references = parse_into_array(selector: response["refs"]["ref"], klass: Sportradar::Api::Content::Reference) if response["refs"] && response["refs"]["ref"]
19
+ @references = parse_into_array(selector: response["refs"], klass: Sportradar::Api::Content::Reference) if response["refs"]
20
20
  end
21
21
 
22
22
  def transaction?
@@ -9,7 +9,7 @@ module Sportradar
9
9
  @provider = data["provider"]
10
10
  @start_time = Time.parse(data["start_time"]) if data["start_time"]
11
11
  @end_time = Time.parse(data["end_time"]) if data["end_time"]
12
- @articles = parse_into_array(selector: response["item"], klass: Sportradar::Api::Content::Article) if response["item"]
12
+ @articles = parse_into_array(selector: response["items"], klass: Sportradar::Api::Content::Article) if response["items"]
13
13
  end
14
14
 
15
15
  end
@@ -3,7 +3,7 @@ module Sportradar
3
3
  class Content < Request
4
4
  attr_accessor :sport, :access_level
5
5
 
6
- def initialize( sport, access_level = 't')
6
+ def initialize( sport, access_level = default_access_level)
7
7
  raise Sportradar::Api::Error::InvalidSport unless allowed_sports.include? sport
8
8
  @sport = sport
9
9
  raise Sportradar::Api::Error::InvalidAccessLevel unless allowed_access_levels.include? access_level
@@ -13,8 +13,8 @@ module Sportradar
13
13
  def news( date = Date.today, content_type: 'all' )
14
14
  raise Sportradar::Api::Error::InvalidType unless allowed_news_types.include? content_type
15
15
  response = get request_url("#{provider }/news/#{date_path(date)}/#{content_type}")
16
- if response.success? && response["content"]
17
- Sportradar::Api::Content::ArticleList.new response["content"]
16
+ if response.success? && response["items"]
17
+ Sportradar::Api::Content::ArticleList.new response.to_h
18
18
  else
19
19
  response
20
20
  end
@@ -23,8 +23,8 @@ module Sportradar
23
23
  def analysis( date = Date.today, content_type: 'all' )
24
24
  raise Sportradar::Api::Error::InvalidType unless allowed_analysis_types.include? content_type
25
25
  response = get request_url("#{provider }/analysis/#{date_path(date)}/#{content_type}")
26
- if response.success? && response["content"]
27
- Sportradar::Api::Content::ArticleList.new response["content"]
26
+ if response.success? && response["items"]
27
+ Sportradar::Api::Content::ArticleList.new response.to_h
28
28
  else
29
29
  response
30
30
  end
@@ -32,10 +32,22 @@ module Sportradar
32
32
 
33
33
  private
34
34
 
35
+ def default_access_level
36
+ if (ENV['SPORTRADAR_ENV'] || ENV['RACK_ENV'] || ENV['RAILS_ENV']) == 'production'
37
+ 'p'
38
+ else
39
+ 't'
40
+ end
41
+ end
42
+
35
43
  def request_url(path)
36
44
  "/content-#{sport}-#{access_level}#{version}/#{path}"
37
45
  end
38
46
 
47
+ def content_format
48
+ 'json'
49
+ end
50
+
39
51
  def api_key
40
52
  if access_level == 'p'
41
53
  Sportradar::Api.api_key_params("content_#{sport}", "production")
@@ -18,6 +18,59 @@ module Sportradar
18
18
  [ klass.new(selector) ]
19
19
  end
20
20
  end
21
+ def parse_into_array_with_options(selector: , klass: , **opts)
22
+ if selector.is_a?(Array)
23
+ selector.map {|x| klass.new(x, **opts) }
24
+ elsif selector.is_a?(Hash)
25
+ [ klass.new(selector, **opts) ]
26
+ else
27
+ []
28
+ end
29
+ end
30
+
31
+ def structure_links(links_arr)
32
+ links_arr.map { |hash| [hash['rel'], hash['href'].gsub('.xml', '')] }.to_h
33
+ end
34
+
35
+ # @param existing [Hash{String=>Data}] Existing data hash, ID => entity
36
+ # @param data [Hash, Array] new data to update with
37
+ def update_data(existing, data)
38
+ case data
39
+ when Array
40
+ data.each { |hash| existing[hash['id']].update(hash) }
41
+ when Hash
42
+ existing[data['id']].update(data)
43
+ else
44
+ # raise
45
+ end
46
+ existing
47
+ end
48
+
49
+ # @param existing [Hash{String=>Data}] Existing data hash, ID => entity
50
+ # @param data [Hash, Array] new data to update with
51
+ def create_data(existing = {}, data, klass: nil, identifier: 'id', **opts)
52
+ existing ||= {} # handles nil case, typically during object instantiation
53
+ case data
54
+ when [], {}
55
+ existing
56
+ when Array
57
+ data.each do |hash|
58
+ current = existing[hash[identifier]]
59
+ if current
60
+ current.update(hash, **opts)
61
+ else
62
+ current = klass.new(hash, **opts)
63
+ existing[current.id] = current
64
+ end
65
+ existing[current.id]
66
+ end
67
+ when Hash
68
+ existing[data[identifier]] = klass.new(data, **opts)
69
+ else
70
+ # raise
71
+ end
72
+ existing
73
+ end
21
74
 
22
75
  def parse_out_hashes(data_element)
23
76
  if data_element && data_element.is_a?(Array)
@@ -0,0 +1,62 @@
1
+ # Sportradar Football
2
+
3
+ ![API Reference](https://developer.sportradar.com/files/indexFootball.html)
4
+
5
+ ## NFL
6
+
7
+ Get started with official NFL api v1:
8
+
9
+ ```ruby
10
+ nfl = Sportradar::Api::Football::Nfl.new
11
+ nfl = Sportradar::Api::Football::Nfl.new(year: 2016)
12
+ res = nfl.get_schedule # => res is the raw response data hash. the `nfl` object now has weeks present to interact with
13
+ res = nfl.get_weekly_schedule # => res is the raw response data hash. the `nfl` object now has weeks present to interact with
14
+ nfl.weeks.count # => 17
15
+ nfl.games.count # => 256
16
+ nfl.weeks.first.games.count # => 16
17
+ game = nfl.games.sample # => Sportradar::Api::Football::Nfl::Game
18
+ res = game.get_pbp # => res is raw response data hash. the `game` object now has quarters/drives/plays to interact with
19
+ game.quarters.size # => 4 (unless the game went to overtime)
20
+ game.drives.size # => (20-30) most NFL games have between 20 and 30 drives
21
+ game.plays.size # => 150 most NFL games have about 150 total plays
22
+
23
+ game.get_statistics # => res is raw response data hash. the `game` object now has team stats to interact with
24
+ game.home.stats.passing # => Sportradar::Api::Football::StatPack::Passing => passing stats
25
+ game.home.stats.passing.players.first
26
+ ```
27
+
28
+
29
+ ```ruby
30
+ nfl = Marshal.load(File.binread('nfl.bin'));
31
+ ncaafb = Marshal.load(File.binread('ncaafb.bin'));
32
+ g1 = nfl.games.sample;
33
+ g2 = ncaafb.games.sample
34
+ g2.year
35
+ g1.year
36
+ games = [g1, g2]
37
+ games.map(&:year)
38
+ games.map(&:week)
39
+ games.map(&:week_number)
40
+ g1
41
+ g1.year
42
+ g1.week_number
43
+ games.map(&:type)
44
+ games.map(&:path_pbp)
45
+ games.map(&:plays)
46
+ games.map(&:drives).map(&:count)
47
+ games.map(&:plays).map(&:count)
48
+ games.map(&:quarter)
49
+ games.map(&:score)
50
+ games.each(&:get_statistics);
51
+ games.each(&:get_box);
52
+ games.map(&:score)
53
+ games.each(&:get_pbp);
54
+ games.map(&:plays).map(&:count)
55
+ games.map(&:drives).map(&:count)
56
+
57
+
58
+ uri = '2015/REG/1/WKY/MSH'
59
+ game = Sportradar::Api::Football::Ncaafb::Game.new('uri' => uri)
60
+ ```
61
+
62
+
@@ -0,0 +1,114 @@
1
+ module Sportradar
2
+ module Api
3
+ module Football
4
+ class Drive < Data
5
+ attr_accessor :response, :api, :id, :sequence, :start_reason, :end_reason, :play_count, :duration, :first_downs, :gain, :penalty_yards, :scoring_drive, :quarter, :team
6
+
7
+ def self.new(data, **opts)
8
+ if data['type'] == 'event'
9
+ Event.new(data, **opts)
10
+ else
11
+ super
12
+ end
13
+ end
14
+
15
+ def initialize(data, **opts)
16
+ @id = data["id"]
17
+ @api = opts[:api]
18
+ @plays_hash = {}
19
+ @events_hash = {}
20
+
21
+ update(data, **opts)
22
+ end
23
+
24
+ def update(data, **opts)
25
+ @response = data
26
+ @type = data['type']
27
+ @team = data['team']
28
+ @clock = data['clock']
29
+ @overtime = !!opts[:quarter]&.overtime? || @overtime
30
+
31
+ @sequence = data["sequence"]
32
+ @start_reason = data["start_reason"]
33
+ @end_reason = data["end_reason"]
34
+ @play_count = data["play_count"]
35
+ @duration = data["duration"]
36
+ @first_downs = data["first_downs"]
37
+ @gain = data["gain"]
38
+ @penalty_yards = data["penalty_yards"]
39
+ @scoring_drive = data["scoring_drive"]
40
+
41
+ @quarter_data = data['quarter']
42
+ @team_data = data['team']
43
+
44
+ handle_plays_and_events(data, **opts)
45
+
46
+ self
47
+ end
48
+
49
+ def overtime?
50
+ @overtime
51
+ end
52
+
53
+ def plays
54
+ @plays_hash.values
55
+ end
56
+
57
+ def events
58
+ @events_hash.values
59
+ end
60
+
61
+ def over?
62
+ @end_reason != 'UNKNOWN' && !@end_reason.nil?
63
+ end
64
+
65
+ def end_reason_possibilities
66
+ [
67
+ 'UNKNOWN',
68
+ 'Touchdown',
69
+ 'Safety',
70
+ 'Field Goal',
71
+ 'Missed FG',
72
+ 'Blocked FG',
73
+ 'Blocked FG, Downs',
74
+ 'Blocked FG, Safety',
75
+ 'Punt',
76
+ 'Blocked Punt',
77
+ 'Blocked Punt, Downs',
78
+ 'Blocked Punt, Safety',
79
+ 'Downs',
80
+ 'Interception',
81
+ 'Fumble',
82
+ 'Fumble, Safety',
83
+ 'Muffed FG',
84
+ 'Muffed Punt',
85
+ 'Muffed Kickoff',
86
+ 'Kickoff',
87
+ 'Own Kickoff',
88
+ 'Onside Kick',
89
+ 'Kickoff, No Play',
90
+ 'End of Half',
91
+ 'End of Game',
92
+ ]
93
+ end
94
+ def normalized_end_reason
95
+ case end_reason
96
+ when 'Touchdown'
97
+ 'Touchdown'
98
+ when 'Field Goal', 'Missed FG', "Blocked FG, Downs", 'Muffed FG', 'Blocked FG, Safety'
99
+ 'Field Goal'
100
+ when 'Downs'
101
+ 'Downs'
102
+ when 'Interception', 'Fumble'
103
+ 'Turnover'
104
+ when 'Punt'
105
+ 'Punt'
106
+ else
107
+ 'Other'
108
+ end
109
+ end
110
+ end
111
+
112
+ end
113
+ end
114
+ end