nba 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (321) hide show
  1. checksums.yaml +5 -5
  2. data/AGENTS.md +362 -0
  3. data/CHANGELOG.md +169 -0
  4. data/CLAUDE.md +1 -0
  5. data/LICENSE +21 -0
  6. data/README.md +501 -101
  7. data/bin/console +10 -0
  8. data/bin/setup +6 -0
  9. data/exe/nba +8 -0
  10. data/lib/nba/all_time_leader.rb +77 -0
  11. data/lib/nba/all_time_leaders.rb +185 -0
  12. data/lib/nba/assist_leader.rb +92 -0
  13. data/lib/nba/assist_leaders.rb +64 -0
  14. data/lib/nba/assist_tracker.rb +108 -0
  15. data/lib/nba/assist_tracker_entry.rb +206 -0
  16. data/lib/nba/award.rb +128 -0
  17. data/lib/nba/box_score.rb +2 -0
  18. data/lib/nba/box_score_advanced.rb +114 -0
  19. data/lib/nba/box_score_advanced_player_stat.rb +297 -0
  20. data/lib/nba/box_score_advanced_team_stat.rb +237 -0
  21. data/lib/nba/box_score_advanced_v3.rb +124 -0
  22. data/lib/nba/box_score_defensive_player_stat.rb +281 -0
  23. data/lib/nba/box_score_defensive_team_stat.rb +85 -0
  24. data/lib/nba/box_score_defensive_v2.rb +190 -0
  25. data/lib/nba/box_score_four_factors.rb +91 -0
  26. data/lib/nba/box_score_four_factors_player_stat.rb +185 -0
  27. data/lib/nba/box_score_four_factors_team_stat.rb +141 -0
  28. data/lib/nba/box_score_four_factors_v3.rb +133 -0
  29. data/lib/nba/box_score_hustle.rb +226 -0
  30. data/lib/nba/box_score_hustle_player_stat.rb +233 -0
  31. data/lib/nba/box_score_hustle_team_stat.rb +189 -0
  32. data/lib/nba/box_score_matchup_stat.rb +417 -0
  33. data/lib/nba/box_score_matchups_v3.rb +184 -0
  34. data/lib/nba/box_score_misc.rb +100 -0
  35. data/lib/nba/box_score_misc_player_stat.rb +217 -0
  36. data/lib/nba/box_score_misc_team_stat.rb +173 -0
  37. data/lib/nba/box_score_misc_v3.rb +163 -0
  38. data/lib/nba/box_score_player_stat.rb +273 -0
  39. data/lib/nba/box_score_player_track.rb +223 -0
  40. data/lib/nba/box_score_player_track_stat.rb +273 -0
  41. data/lib/nba/box_score_player_track_team_stat.rb +229 -0
  42. data/lib/nba/box_score_scoring.rb +103 -0
  43. data/lib/nba/box_score_scoring_player_stat.rb +241 -0
  44. data/lib/nba/box_score_scoring_team_stat.rb +197 -0
  45. data/lib/nba/box_score_scoring_v3.rb +170 -0
  46. data/lib/nba/box_score_similarity_score.rb +119 -0
  47. data/lib/nba/box_score_similarity_stat.rb +76 -0
  48. data/lib/nba/box_score_starter_bench_stat.rb +257 -0
  49. data/lib/nba/box_score_summary.rb +285 -0
  50. data/lib/nba/box_score_summary_v2.rb +202 -0
  51. data/lib/nba/box_score_summary_v3.rb +120 -0
  52. data/lib/nba/box_score_summary_v3_data.rb +419 -0
  53. data/lib/nba/box_score_team_stat.rb +229 -0
  54. data/lib/nba/box_score_traditional.rb +101 -0
  55. data/lib/nba/box_score_traditional_v3.rb +195 -0
  56. data/lib/nba/box_score_usage.rb +102 -0
  57. data/lib/nba/box_score_usage_player_stat.rb +265 -0
  58. data/lib/nba/box_score_usage_team_stat.rb +221 -0
  59. data/lib/nba/box_score_usage_v3.rb +169 -0
  60. data/lib/nba/box_score_v3_helpers.rb +144 -0
  61. data/lib/nba/career_stats.rb +217 -0
  62. data/lib/nba/cli/display/player_display.rb +98 -0
  63. data/lib/nba/cli/display.rb +178 -0
  64. data/lib/nba/cli/formatters/game_formatters.rb +86 -0
  65. data/lib/nba/cli/formatters/leaders_formatters.rb +26 -0
  66. data/lib/nba/cli/formatters/player_formatters.rb +52 -0
  67. data/lib/nba/cli/formatters/standings_formatters.rb +26 -0
  68. data/lib/nba/cli/formatters/team_formatters.rb +67 -0
  69. data/lib/nba/cli/formatters/time_formatters.rb +82 -0
  70. data/lib/nba/cli/formatters.rb +56 -0
  71. data/lib/nba/cli/helpers.rb +135 -0
  72. data/lib/nba/cli.rb +171 -20
  73. data/lib/nba/client.rb +35 -0
  74. data/lib/nba/collection.rb +89 -0
  75. data/lib/nba/college_player_stat.rb +200 -0
  76. data/lib/nba/common_player_info.rb +142 -0
  77. data/lib/nba/common_playoff_series.rb +90 -0
  78. data/lib/nba/common_team_years.rb +113 -0
  79. data/lib/nba/conference.rb +39 -0
  80. data/lib/nba/connection.rb +84 -0
  81. data/lib/nba/cume_stats_player.rb +358 -0
  82. data/lib/nba/cume_stats_player_game.rb +217 -0
  83. data/lib/nba/cume_stats_player_games.rb +99 -0
  84. data/lib/nba/cume_stats_player_games_entry.rb +25 -0
  85. data/lib/nba/cume_stats_player_total.rb +481 -0
  86. data/lib/nba/cume_stats_team.rb +349 -0
  87. data/lib/nba/cume_stats_team_games.rb +145 -0
  88. data/lib/nba/cume_stats_team_games_entry.rb +25 -0
  89. data/lib/nba/cume_stats_team_player.rb +485 -0
  90. data/lib/nba/cume_stats_team_total.rb +267 -0
  91. data/lib/nba/data.rb +73 -0
  92. data/lib/nba/defense_hub.rb +109 -0
  93. data/lib/nba/defense_hub_stat.rb +57 -0
  94. data/lib/nba/defensive_shot_stat.rb +102 -0
  95. data/lib/nba/division.rb +49 -0
  96. data/lib/nba/draft_board.rb +126 -0
  97. data/lib/nba/draft_board_pick.rb +173 -0
  98. data/lib/nba/draft_combine_anthro_measurement.rb +163 -0
  99. data/lib/nba/draft_combine_drill_result.rb +115 -0
  100. data/lib/nba/draft_combine_drill_results.rb +112 -0
  101. data/lib/nba/draft_combine_non_stationary_shooting.rb +268 -0
  102. data/lib/nba/draft_combine_non_stationary_shooting_result.rb +355 -0
  103. data/lib/nba/draft_combine_player_anthro.rb +133 -0
  104. data/lib/nba/draft_combine_spot_shooting.rb +243 -0
  105. data/lib/nba/draft_combine_spot_shooting_result.rb +419 -0
  106. data/lib/nba/draft_combine_stat.rb +211 -0
  107. data/lib/nba/draft_combine_stats.rb +160 -0
  108. data/lib/nba/draft_history.rb +142 -0
  109. data/lib/nba/draft_pick.rb +154 -0
  110. data/lib/nba/dunk_score_leader.rb +93 -0
  111. data/lib/nba/dunk_score_leaders.rb +77 -0
  112. data/lib/nba/estimated_metrics_stat.rb +152 -0
  113. data/lib/nba/fantasy_profile_stat.rb +142 -0
  114. data/lib/nba/fantasy_widget.rb +72 -0
  115. data/lib/nba/fantasy_widget_player.rb +98 -0
  116. data/lib/nba/found_game.rb +260 -0
  117. data/lib/nba/franchise.rb +136 -0
  118. data/lib/nba/franchise_history.rb +142 -0
  119. data/lib/nba/franchise_leader.rb +147 -0
  120. data/lib/nba/franchise_leaders.rb +162 -0
  121. data/lib/nba/franchise_player.rb +224 -0
  122. data/lib/nba/franchise_players.rb +147 -0
  123. data/lib/nba/game.rb +80 -64
  124. data/lib/nba/game_log.rb +349 -0
  125. data/lib/nba/game_rotation.rb +152 -0
  126. data/lib/nba/game_streak.rb +102 -0
  127. data/lib/nba/games.rb +46 -0
  128. data/lib/nba/home_page_leader.rb +99 -0
  129. data/lib/nba/home_page_leaders.rb +75 -0
  130. data/lib/nba/home_page_stat.rb +57 -0
  131. data/lib/nba/home_page_v2.rb +110 -0
  132. data/lib/nba/hustle_stats_box_score.rb +182 -0
  133. data/lib/nba/infographic_fan_duel_player.rb +139 -0
  134. data/lib/nba/infographic_fan_duel_player_stat.rb +311 -0
  135. data/lib/nba/ist_standing.rb +167 -0
  136. data/lib/nba/ist_standings.rb +81 -0
  137. data/lib/nba/leader.rb +103 -0
  138. data/lib/nba/leaders.rb +110 -0
  139. data/lib/nba/leaders_tile.rb +57 -0
  140. data/lib/nba/leaders_tiles.rb +90 -0
  141. data/lib/nba/league.rb +37 -0
  142. data/lib/nba/league_dash_lineup_stat.rb +270 -0
  143. data/lib/nba/league_dash_lineups.rb +177 -0
  144. data/lib/nba/league_dash_opp_pt_shot.rb +150 -0
  145. data/lib/nba/league_dash_player_bio_stat.rb +217 -0
  146. data/lib/nba/league_dash_player_bio_stats.rb +164 -0
  147. data/lib/nba/league_dash_player_clutch.rb +212 -0
  148. data/lib/nba/league_dash_player_clutch_stat.rb +271 -0
  149. data/lib/nba/league_dash_player_pt_shot.rb +152 -0
  150. data/lib/nba/league_dash_player_pt_shot_stat.rb +193 -0
  151. data/lib/nba/league_dash_player_shot_location_stat.rb +265 -0
  152. data/lib/nba/league_dash_player_shot_locations.rb +210 -0
  153. data/lib/nba/league_dash_player_stat.rb +306 -0
  154. data/lib/nba/league_dash_player_stats.rb +176 -0
  155. data/lib/nba/league_dash_pt_defend.rb +160 -0
  156. data/lib/nba/league_dash_pt_defend_stat.rb +145 -0
  157. data/lib/nba/league_dash_pt_stats.rb +152 -0
  158. data/lib/nba/league_dash_pt_stats_stat.rb +169 -0
  159. data/lib/nba/league_dash_pt_team_defend.rb +158 -0
  160. data/lib/nba/league_dash_pt_team_defend_stat.rb +110 -0
  161. data/lib/nba/league_dash_team_clutch.rb +211 -0
  162. data/lib/nba/league_dash_team_clutch_stat.rb +237 -0
  163. data/lib/nba/league_dash_team_pt_shot.rb +150 -0
  164. data/lib/nba/league_dash_team_pt_shot_stat.rb +166 -0
  165. data/lib/nba/league_dash_team_shot_location_stat.rb +230 -0
  166. data/lib/nba/league_dash_team_shot_locations.rb +208 -0
  167. data/lib/nba/league_dash_team_stat.rb +275 -0
  168. data/lib/nba/league_dash_team_stats.rb +172 -0
  169. data/lib/nba/league_game_finder.rb +170 -0
  170. data/lib/nba/league_game_log.rb +224 -0
  171. data/lib/nba/league_hustle_stats_player.rb +161 -0
  172. data/lib/nba/league_hustle_stats_player_stat.rb +253 -0
  173. data/lib/nba/league_hustle_stats_team.rb +157 -0
  174. data/lib/nba/league_hustle_stats_team_stat.rb +179 -0
  175. data/lib/nba/league_lineup_viz.rb +184 -0
  176. data/lib/nba/league_lineup_viz_stat.rb +214 -0
  177. data/lib/nba/league_player_on_details.rb +175 -0
  178. data/lib/nba/league_player_on_details_stat.rb +313 -0
  179. data/lib/nba/league_season_matchup_stat.rb +241 -0
  180. data/lib/nba/league_season_matchups.rb +181 -0
  181. data/lib/nba/league_standing.rb +284 -0
  182. data/lib/nba/league_standings.rb +159 -0
  183. data/lib/nba/league_wide_shot_stat.rb +62 -0
  184. data/lib/nba/live_action.rb +240 -0
  185. data/lib/nba/live_box_score.rb +143 -0
  186. data/lib/nba/live_connection.rb +84 -0
  187. data/lib/nba/live_game.rb +230 -0
  188. data/lib/nba/live_play_by_play.rb +120 -0
  189. data/lib/nba/live_player_stat.rb +276 -0
  190. data/lib/nba/live_scoreboard.rb +102 -0
  191. data/lib/nba/matchup_rollup.rb +98 -0
  192. data/lib/nba/matchups_rollup.rb +81 -0
  193. data/lib/nba/pass_stat.rb +209 -0
  194. data/lib/nba/play.rb +258 -0
  195. data/lib/nba/play_by_play.rb +85 -0
  196. data/lib/nba/play_by_play_v3.rb +91 -0
  197. data/lib/nba/play_type_stat.rb +206 -0
  198. data/lib/nba/player.rb +242 -24
  199. data/lib/nba/player_awards.rb +110 -0
  200. data/lib/nba/player_career_by_college.rb +86 -0
  201. data/lib/nba/player_career_by_college_rollup.rb +143 -0
  202. data/lib/nba/player_career_stats.rb +77 -0
  203. data/lib/nba/player_compare.rb +156 -0
  204. data/lib/nba/player_comparison_stat.rb +242 -0
  205. data/lib/nba/player_dash_pt_pass.rb +164 -0
  206. data/lib/nba/player_dash_pt_reb.rb +235 -0
  207. data/lib/nba/player_dash_pt_shot_defend.rb +119 -0
  208. data/lib/nba/player_dash_pt_shots.rb +279 -0
  209. data/lib/nba/player_dashboard.rb +259 -0
  210. data/lib/nba/player_dashboard_stat.rb +248 -0
  211. data/lib/nba/player_estimated_metrics.rb +84 -0
  212. data/lib/nba/player_fantasy_profile_bar_graph.rb +147 -0
  213. data/lib/nba/player_game_log.rb +72 -0
  214. data/lib/nba/player_game_logs.rb +117 -0
  215. data/lib/nba/player_game_streak_finder.rb +108 -0
  216. data/lib/nba/player_index.rb +135 -0
  217. data/lib/nba/player_index_entry.rb +266 -0
  218. data/lib/nba/player_info.rb +225 -0
  219. data/lib/nba/player_next_n_games.rb +64 -0
  220. data/lib/nba/player_profile_v2.rb +169 -0
  221. data/lib/nba/player_vs_player.rb +153 -0
  222. data/lib/nba/players.rb +107 -0
  223. data/lib/nba/playoff_matchup.rb +84 -0
  224. data/lib/nba/playoff_picture.rb +98 -0
  225. data/lib/nba/playoff_series.rb +76 -0
  226. data/lib/nba/position.rb +48 -0
  227. data/lib/nba/rebound_stat.rb +189 -0
  228. data/lib/nba/response_parser.rb +116 -0
  229. data/lib/nba/roster.rb +74 -0
  230. data/lib/nba/rotation_entry.rb +154 -0
  231. data/lib/nba/schedule.rb +183 -0
  232. data/lib/nba/schedule_international.rb +182 -0
  233. data/lib/nba/scheduled_game.rb +240 -0
  234. data/lib/nba/scoreboard.rb +183 -0
  235. data/lib/nba/scoreboard_v3.rb +104 -0
  236. data/lib/nba/shot.rb +208 -0
  237. data/lib/nba/shot_chart.rb +75 -0
  238. data/lib/nba/shot_chart_league_wide.rb +102 -0
  239. data/lib/nba/shot_chart_lineup_detail.rb +109 -0
  240. data/lib/nba/shot_stat.rb +174 -0
  241. data/lib/nba/standing.rb +129 -0
  242. data/lib/nba/standings.rb +75 -0
  243. data/lib/nba/static.rb +107 -0
  244. data/lib/nba/synergy_play_types.rb +211 -0
  245. data/lib/nba/team.rb +203 -127
  246. data/lib/nba/team_and_players_vs_players.rb +227 -0
  247. data/lib/nba/team_and_players_vs_players_stat.rb +155 -0
  248. data/lib/nba/team_dash_pt_pass.rb +157 -0
  249. data/lib/nba/team_dash_pt_reb.rb +216 -0
  250. data/lib/nba/team_dash_pt_shots.rb +244 -0
  251. data/lib/nba/team_dashboard.rb +275 -0
  252. data/lib/nba/team_dashboard_stat.rb +248 -0
  253. data/lib/nba/team_detail.rb +117 -0
  254. data/lib/nba/team_details.rb +173 -0
  255. data/lib/nba/team_estimated_metrics.rb +91 -0
  256. data/lib/nba/team_estimated_metrics_stat.rb +146 -0
  257. data/lib/nba/team_game_log.rb +143 -0
  258. data/lib/nba/team_game_log_entry.rb +246 -0
  259. data/lib/nba/team_game_log_stat.rb +275 -0
  260. data/lib/nba/team_game_logs.rb +163 -0
  261. data/lib/nba/team_game_streak.rb +111 -0
  262. data/lib/nba/team_game_streak_finder.rb +109 -0
  263. data/lib/nba/team_historical_leader.rb +207 -0
  264. data/lib/nba/team_historical_leaders.rb +98 -0
  265. data/lib/nba/team_historical_record.rb +139 -0
  266. data/lib/nba/team_info.rb +150 -0
  267. data/lib/nba/team_info_common.rb +177 -0
  268. data/lib/nba/team_on_off_overall_stat.rb +477 -0
  269. data/lib/nba/team_on_off_player_stat.rb +523 -0
  270. data/lib/nba/team_on_off_player_summary.rb +135 -0
  271. data/lib/nba/team_pass_stat.rb +183 -0
  272. data/lib/nba/team_player_dashboard.rb +212 -0
  273. data/lib/nba/team_player_on_off_details.rb +218 -0
  274. data/lib/nba/team_player_on_off_summary.rb +214 -0
  275. data/lib/nba/team_player_stat.rb +275 -0
  276. data/lib/nba/team_rebound_stat.rb +189 -0
  277. data/lib/nba/team_season_rank.rb +110 -0
  278. data/lib/nba/team_shot_stat.rb +173 -0
  279. data/lib/nba/team_vs_player.rb +151 -0
  280. data/lib/nba/team_vs_player_stat.rb +157 -0
  281. data/lib/nba/team_year.rb +55 -0
  282. data/lib/nba/team_year_by_year_stats.rb +152 -0
  283. data/lib/nba/team_year_stat.rb +282 -0
  284. data/lib/nba/teams.rb +33 -0
  285. data/lib/nba/upcoming_game.rb +115 -0
  286. data/lib/nba/utils.rb +94 -0
  287. data/lib/nba/version.rb +5 -2
  288. data/lib/nba/video_detail.rb +103 -0
  289. data/lib/nba/video_details.rb +118 -0
  290. data/lib/nba/video_details_asset.rb +115 -0
  291. data/lib/nba/video_details_asset_entry.rb +91 -0
  292. data/lib/nba/video_event.rb +83 -0
  293. data/lib/nba/video_event_asset.rb +91 -0
  294. data/lib/nba/video_events.rb +106 -0
  295. data/lib/nba/video_events_asset.rb +107 -0
  296. data/lib/nba/video_status.rb +129 -0
  297. data/lib/nba/video_status_entry.rb +161 -0
  298. data/lib/nba/vs_player_stat.rb +156 -0
  299. data/lib/nba/win_probability.rb +117 -0
  300. data/lib/nba/win_probability_point.rb +140 -0
  301. data/lib/nba.rb +249 -5
  302. data/sig/equalizer.rbs +3 -0
  303. data/sig/nba.rbs +7297 -0
  304. data/sig/shale.rbs +24 -0
  305. data/sig/thor.rbs +19 -0
  306. metadata +324 -95
  307. data/.gitignore +0 -18
  308. data/.travis.yml +0 -22
  309. data/Gemfile +0 -23
  310. data/LICENSE.md +0 -22
  311. data/Rakefile +0 -18
  312. data/bin/nba +0 -7
  313. data/cache/teams.json +0 -16529
  314. data/lib/faraday_middleware/scrape_game.rb +0 -41
  315. data/lib/nba/request.rb +0 -37
  316. data/nba.gemspec +0 -28
  317. data/spec/fixtures/games.html +0 -785
  318. data/spec/fixtures/teams.json +0 -16529
  319. data/spec/game_spec.rb +0 -40
  320. data/spec/spec_helper.rb +0 -25
  321. data/spec/team_spec.rb +0 -93
@@ -0,0 +1,216 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "team_rebound_stat"
5
+ require_relative "utils"
6
+
7
+ module NBA
8
+ # Provides methods to retrieve team tracking rebound statistics
9
+ #
10
+ # @api public
11
+ module TeamDashPtReb
12
+ # Result set name for number contested rebounding
13
+ # @return [String] the result set name
14
+ NUM_CONTESTED = "NumContestedRebounding".freeze
15
+
16
+ # Result set name for overall rebounding
17
+ # @return [String] the result set name
18
+ OVERALL = "OverallRebounding".freeze
19
+
20
+ # Result set name for rebound distance rebounding
21
+ # @return [String] the result set name
22
+ REB_DISTANCE = "RebDistanceRebounding".freeze
23
+
24
+ # Result set name for shot distance rebounding
25
+ # @return [String] the result set name
26
+ SHOT_DISTANCE = "ShotDistanceRebounding".freeze
27
+
28
+ # Result set name for shot type rebounding
29
+ # @return [String] the result set name
30
+ SHOT_TYPE = "ShotTypeRebounding".freeze
31
+
32
+ # Retrieves number contested rebounding stats for a team
33
+ #
34
+ # @api public
35
+ # @example
36
+ # stats = NBA::TeamDashPtReb.num_contested(team: 1610612744)
37
+ # @param team [Integer, Team] the team ID or Team object
38
+ # @param season [Integer] the season year
39
+ # @param season_type [String] the season type
40
+ # @param per_mode [String] the per mode
41
+ # @param client [Client] the API client to use
42
+ # @return [Collection] a collection of rebound statistics
43
+ def self.num_contested(team:, season: Utils.current_season, season_type: "Regular Season",
44
+ per_mode: "PerGame", client: CLIENT)
45
+ fetch_stats(team, season, season_type, per_mode, NUM_CONTESTED, client: client)
46
+ end
47
+
48
+ # Retrieves overall rebounding stats for a team
49
+ #
50
+ # @api public
51
+ # @example
52
+ # stats = NBA::TeamDashPtReb.overall(team: 1610612744)
53
+ # @param team [Integer, Team] the team ID or Team object
54
+ # @param season [Integer] the season year
55
+ # @param season_type [String] the season type
56
+ # @param per_mode [String] the per mode
57
+ # @param client [Client] the API client to use
58
+ # @return [Collection] a collection of rebound statistics
59
+ def self.overall(team:, season: Utils.current_season, season_type: "Regular Season",
60
+ per_mode: "PerGame", client: CLIENT)
61
+ fetch_stats(team, season, season_type, per_mode, OVERALL, client: client)
62
+ end
63
+
64
+ # Retrieves rebound distance rebounding stats for a team
65
+ #
66
+ # @api public
67
+ # @example
68
+ # stats = NBA::TeamDashPtReb.reb_distance(team: 1610612744)
69
+ # @param team [Integer, Team] the team ID or Team object
70
+ # @param season [Integer] the season year
71
+ # @param season_type [String] the season type
72
+ # @param per_mode [String] the per mode
73
+ # @param client [Client] the API client to use
74
+ # @return [Collection] a collection of rebound statistics
75
+ def self.reb_distance(team:, season: Utils.current_season, season_type: "Regular Season",
76
+ per_mode: "PerGame", client: CLIENT)
77
+ fetch_stats(team, season, season_type, per_mode, REB_DISTANCE, client: client)
78
+ end
79
+
80
+ # Retrieves shot distance rebounding stats for a team
81
+ #
82
+ # @api public
83
+ # @example
84
+ # stats = NBA::TeamDashPtReb.shot_distance(team: 1610612744)
85
+ # @param team [Integer, Team] the team ID or Team object
86
+ # @param season [Integer] the season year
87
+ # @param season_type [String] the season type
88
+ # @param per_mode [String] the per mode
89
+ # @param client [Client] the API client to use
90
+ # @return [Collection] a collection of rebound statistics
91
+ def self.shot_distance(team:, season: Utils.current_season, season_type: "Regular Season",
92
+ per_mode: "PerGame", client: CLIENT)
93
+ fetch_stats(team, season, season_type, per_mode, SHOT_DISTANCE, client: client)
94
+ end
95
+
96
+ # Retrieves shot type rebounding stats for a team
97
+ #
98
+ # @api public
99
+ # @example
100
+ # stats = NBA::TeamDashPtReb.shot_type(team: 1610612744)
101
+ # @param team [Integer, Team] the team ID or Team object
102
+ # @param season [Integer] the season year
103
+ # @param season_type [String] the season type
104
+ # @param per_mode [String] the per mode
105
+ # @param client [Client] the API client to use
106
+ # @return [Collection] a collection of rebound statistics
107
+ def self.shot_type(team:, season: Utils.current_season, season_type: "Regular Season",
108
+ per_mode: "PerGame", client: CLIENT)
109
+ fetch_stats(team, season, season_type, per_mode, SHOT_TYPE, client: client)
110
+ end
111
+
112
+ # Fetches rebound stats from the API
113
+ #
114
+ # @api private
115
+ # @return [Collection] collection of rebound stats
116
+ def self.fetch_stats(team, season, season_type, per_mode, result_set_name, client:)
117
+ path = build_path(team, season, season_type, per_mode)
118
+ response = client.get(path)
119
+ parse_response(response, result_set_name)
120
+ end
121
+ private_class_method :fetch_stats
122
+
123
+ # Builds the API path
124
+ #
125
+ # @api private
126
+ # @return [String] the request path
127
+ def self.build_path(team, season, season_type, per_mode)
128
+ team_id = Utils.extract_id(team)
129
+ season_str = Utils.format_season(season)
130
+ "teamdashptreb?TeamID=#{team_id}&Season=#{season_str}" \
131
+ "&SeasonType=#{season_type}&PerMode=#{per_mode}&LeagueID=00"
132
+ end
133
+ private_class_method :build_path
134
+
135
+ # Parses the API response into rebound stat objects
136
+ #
137
+ # @api private
138
+ # @return [Collection] collection of rebound stats
139
+ def self.parse_response(response, result_set_name)
140
+ return Collection.new if response.nil? || response.empty?
141
+
142
+ data = JSON.parse(response)
143
+ result_set = find_result_set(data, result_set_name)
144
+ build_collection(result_set)
145
+ end
146
+ private_class_method :parse_response
147
+
148
+ # Finds a result set by name
149
+ #
150
+ # @api private
151
+ # @return [Hash, nil] the result set hash or nil if not found
152
+ def self.find_result_set(data, result_set_name)
153
+ result_sets = data["resultSets"]
154
+ return unless result_sets
155
+
156
+ result_sets.find { |rs| rs["name"].eql?(result_set_name) }
157
+ end
158
+ private_class_method :find_result_set
159
+
160
+ # Builds a collection from a result set
161
+ #
162
+ # @api private
163
+ # @return [Collection] the stats collection
164
+ def self.build_collection(result_set)
165
+ return Collection.new unless result_set
166
+
167
+ headers = result_set["headers"]
168
+ rows = result_set["rowSet"]
169
+ return Collection.new unless headers && rows
170
+
171
+ Collection.new(rows.map { |row| build_rebound_stat(headers.zip(row).to_h) })
172
+ end
173
+ private_class_method :build_collection
174
+
175
+ # Builds a rebound stat from API data
176
+ #
177
+ # @api private
178
+ # @return [TeamReboundStat] the rebound stat object
179
+ def self.build_rebound_stat(data)
180
+ TeamReboundStat.new(**identity_info(data), **range_info(data), **rebound_info(data))
181
+ end
182
+ private_class_method :build_rebound_stat
183
+
184
+ # Extracts identity information from data
185
+ #
186
+ # @api private
187
+ # @return [Hash] the identity information hash
188
+ def self.identity_info(data)
189
+ {team_id: data["TEAM_ID"], team_name: data["TEAM_NAME"],
190
+ sort_order: data["SORT_ORDER"], g: data["G"]}
191
+ end
192
+ private_class_method :identity_info
193
+
194
+ # Extracts range information from data
195
+ #
196
+ # @api private
197
+ # @return [Hash] the range information hash
198
+ def self.range_info(data)
199
+ {reb_num_contesting_range: data["REB_NUM_CONTESTING_RANGE"], overall: data["OVERALL"],
200
+ reb_dist_range: data["REB_DIST_RANGE"], shot_dist_range: data["SHOT_DIST_RANGE"],
201
+ shot_type_range: data["SHOT_TYPE_RANGE"], reb_frequency: data["REB_FREQUENCY"]}
202
+ end
203
+ private_class_method :range_info
204
+
205
+ # Extracts rebound information from data
206
+ #
207
+ # @api private
208
+ # @return [Hash] the rebound information hash
209
+ def self.rebound_info(data)
210
+ {oreb: data["OREB"], dreb: data["DREB"], reb: data["REB"],
211
+ c_oreb: data["C_OREB"], c_dreb: data["C_DREB"], c_reb: data["C_REB"], c_reb_pct: data["C_REB_PCT"],
212
+ uc_oreb: data["UC_OREB"], uc_dreb: data["UC_DREB"], uc_reb: data["UC_REB"], uc_reb_pct: data["UC_REB_PCT"]}
213
+ end
214
+ private_class_method :rebound_info
215
+ end
216
+ end
@@ -0,0 +1,244 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "team_shot_stat"
5
+ require_relative "utils"
6
+
7
+ module NBA
8
+ # Provides methods to retrieve team tracking shot statistics
9
+ #
10
+ # @api public
11
+ module TeamDashPtShots
12
+ # Result set name for general shooting
13
+ # @return [String] the result set name
14
+ GENERAL = "GeneralShooting".freeze
15
+
16
+ # Result set name for shot clock shooting
17
+ # @return [String] the result set name
18
+ SHOT_CLOCK = "ShotClockShooting".freeze
19
+
20
+ # Result set name for dribble shooting
21
+ # @return [String] the result set name
22
+ DRIBBLE = "DribbleShooting".freeze
23
+
24
+ # Result set name for closest defender shooting
25
+ # @return [String] the result set name
26
+ CLOSEST_DEFENDER = "ClosestDefenderShooting".freeze
27
+
28
+ # Result set name for closest defender 10ft+ shooting
29
+ # @return [String] the result set name
30
+ CLOSEST_DEFENDER_10FT = "ClosestDefender10ftPlusShooting".freeze
31
+
32
+ # Result set name for touch time shooting
33
+ # @return [String] the result set name
34
+ TOUCH_TIME = "TouchTimeShooting".freeze
35
+
36
+ # Retrieves general shot statistics for a team
37
+ #
38
+ # @api public
39
+ # @example
40
+ # stats = NBA::TeamDashPtShots.general(team: 1610612744)
41
+ # stats.each { |s| puts "#{s.shot_type}: #{s.fg_pct}" }
42
+ # @param team [Integer, Team] the team ID or Team object
43
+ # @param season [Integer] the season year
44
+ # @param season_type [String] the season type
45
+ # @param per_mode [String] the per mode
46
+ # @param client [Client] the API client to use
47
+ # @return [Collection] a collection of shot statistics
48
+ def self.general(team:, season: Utils.current_season, season_type: "Regular Season",
49
+ per_mode: "PerGame", client: CLIENT)
50
+ fetch_stats(team, season, season_type, per_mode, GENERAL, client: client)
51
+ end
52
+
53
+ # Retrieves shot clock shot statistics for a team
54
+ #
55
+ # @api public
56
+ # @example
57
+ # stats = NBA::TeamDashPtShots.shot_clock(team: 1610612744)
58
+ # stats.each { |s| puts "#{s.shot_type}: #{s.fg_pct}" }
59
+ # @param team [Integer, Team] the team ID or Team object
60
+ # @param season [Integer] the season year
61
+ # @param season_type [String] the season type
62
+ # @param per_mode [String] the per mode
63
+ # @param client [Client] the API client to use
64
+ # @return [Collection] a collection of shot statistics
65
+ def self.shot_clock(team:, season: Utils.current_season, season_type: "Regular Season",
66
+ per_mode: "PerGame", client: CLIENT)
67
+ fetch_stats(team, season, season_type, per_mode, SHOT_CLOCK, client: client)
68
+ end
69
+
70
+ # Retrieves dribble shot statistics for a team
71
+ #
72
+ # @api public
73
+ # @example
74
+ # stats = NBA::TeamDashPtShots.dribble(team: 1610612744)
75
+ # stats.each { |s| puts "#{s.shot_type}: #{s.fg_pct}" }
76
+ # @param team [Integer, Team] the team ID or Team object
77
+ # @param season [Integer] the season year
78
+ # @param season_type [String] the season type
79
+ # @param per_mode [String] the per mode
80
+ # @param client [Client] the API client to use
81
+ # @return [Collection] a collection of shot statistics
82
+ def self.dribble(team:, season: Utils.current_season, season_type: "Regular Season",
83
+ per_mode: "PerGame", client: CLIENT)
84
+ fetch_stats(team, season, season_type, per_mode, DRIBBLE, client: client)
85
+ end
86
+
87
+ # Retrieves closest defender shot statistics for a team
88
+ #
89
+ # @api public
90
+ # @example
91
+ # stats = NBA::TeamDashPtShots.closest_defender(team: 1610612744)
92
+ # stats.each { |s| puts "#{s.shot_type}: #{s.fg_pct}" }
93
+ # @param team [Integer, Team] the team ID or Team object
94
+ # @param season [Integer] the season year
95
+ # @param season_type [String] the season type
96
+ # @param per_mode [String] the per mode
97
+ # @param client [Client] the API client to use
98
+ # @return [Collection] a collection of shot statistics
99
+ def self.closest_defender(team:, season: Utils.current_season, season_type: "Regular Season",
100
+ per_mode: "PerGame", client: CLIENT)
101
+ fetch_stats(team, season, season_type, per_mode, CLOSEST_DEFENDER, client: client)
102
+ end
103
+
104
+ # Retrieves closest defender 10ft+ shot statistics for a team
105
+ #
106
+ # @api public
107
+ # @example
108
+ # stats = NBA::TeamDashPtShots.closest_defender_10ft(team: 1610612744)
109
+ # stats.each { |s| puts "#{s.shot_type}: #{s.fg_pct}" }
110
+ # @param team [Integer, Team] the team ID or Team object
111
+ # @param season [Integer] the season year
112
+ # @param season_type [String] the season type
113
+ # @param per_mode [String] the per mode
114
+ # @param client [Client] the API client to use
115
+ # @return [Collection] a collection of shot statistics
116
+ def self.closest_defender_10ft(team:, season: Utils.current_season, season_type: "Regular Season",
117
+ per_mode: "PerGame", client: CLIENT)
118
+ fetch_stats(team, season, season_type, per_mode, CLOSEST_DEFENDER_10FT, client: client)
119
+ end
120
+
121
+ # Retrieves touch time shot statistics for a team
122
+ #
123
+ # @api public
124
+ # @example
125
+ # stats = NBA::TeamDashPtShots.touch_time(team: 1610612744)
126
+ # stats.each { |s| puts "#{s.shot_type}: #{s.fg_pct}" }
127
+ # @param team [Integer, Team] the team ID or Team object
128
+ # @param season [Integer] the season year
129
+ # @param season_type [String] the season type
130
+ # @param per_mode [String] the per mode
131
+ # @param client [Client] the API client to use
132
+ # @return [Collection] a collection of shot statistics
133
+ def self.touch_time(team:, season: Utils.current_season, season_type: "Regular Season",
134
+ per_mode: "PerGame", client: CLIENT)
135
+ fetch_stats(team, season, season_type, per_mode, TOUCH_TIME, client: client)
136
+ end
137
+
138
+ # Fetches shot stats from the API
139
+ #
140
+ # @api private
141
+ # @return [Collection] collection of shot stats
142
+ def self.fetch_stats(team, season, season_type, per_mode, result_set_name, client:)
143
+ path = build_path(team, season, season_type, per_mode)
144
+ response = client.get(path)
145
+ parse_response(response, result_set_name)
146
+ end
147
+ private_class_method :fetch_stats
148
+
149
+ # Builds the API path
150
+ #
151
+ # @api private
152
+ # @return [String] the request path
153
+ def self.build_path(team, season, season_type, per_mode)
154
+ team_id = Utils.extract_id(team)
155
+ season_str = Utils.format_season(season)
156
+ "teamdashptshots?TeamID=#{team_id}&Season=#{season_str}" \
157
+ "&SeasonType=#{season_type}&PerMode=#{per_mode}&LeagueID=00"
158
+ end
159
+ private_class_method :build_path
160
+
161
+ # Parses the API response into shot stat objects
162
+ #
163
+ # @api private
164
+ # @return [Collection] collection of shot stats
165
+ def self.parse_response(response, result_set_name)
166
+ return Collection.new if response.nil? || response.empty?
167
+
168
+ data = JSON.parse(response)
169
+ result_set = find_result_set(data, result_set_name)
170
+ build_collection(result_set)
171
+ end
172
+ private_class_method :parse_response
173
+
174
+ # Finds a result set by name
175
+ #
176
+ # @api private
177
+ # @return [Hash, nil] the result set hash or nil if not found
178
+ def self.find_result_set(data, result_set_name)
179
+ result_sets = data["resultSets"]
180
+ return unless result_sets
181
+
182
+ result_sets.find { |rs| rs["name"].eql?(result_set_name) }
183
+ end
184
+ private_class_method :find_result_set
185
+
186
+ # Builds a collection from a result set
187
+ #
188
+ # @api private
189
+ # @return [Collection] the stats collection
190
+ def self.build_collection(result_set)
191
+ return Collection.new unless result_set
192
+
193
+ headers = result_set["headers"]
194
+ rows = result_set["rowSet"]
195
+ return Collection.new unless headers && rows
196
+
197
+ Collection.new(rows.map { |row| build_shot_stat(headers.zip(row).to_h) })
198
+ end
199
+ private_class_method :build_collection
200
+
201
+ # Builds a shot stat from API data
202
+ #
203
+ # @api private
204
+ # @return [TeamShotStat] the shot stat object
205
+ def self.build_shot_stat(data)
206
+ TeamShotStat.new(**identity_info(data), **shot_info(data), **shooting_info(data))
207
+ end
208
+ private_class_method :build_shot_stat
209
+
210
+ # Extracts identity information from data
211
+ #
212
+ # @api private
213
+ # @return [Hash] the identity information hash
214
+ def self.identity_info(data)
215
+ {team_id: data["TEAM_ID"], team_name: data["TEAM_NAME"],
216
+ team_abbreviation: data["TEAM_ABBREVIATION"],
217
+ sort_order: data["SORT_ORDER"], g: data["G"]}
218
+ end
219
+ private_class_method :identity_info
220
+
221
+ # Extracts shot information from data
222
+ #
223
+ # @api private
224
+ # @return [Hash] the shot information hash
225
+ def self.shot_info(data)
226
+ {shot_type: data["SHOT_TYPE"], fga_frequency: data["FGA_FREQUENCY"],
227
+ fgm: data["FGM"], fga: data["FGA"], fg_pct: data["FG_PCT"],
228
+ efg_pct: data["EFG_PCT"]}
229
+ end
230
+ private_class_method :shot_info
231
+
232
+ # Extracts shooting information from data
233
+ #
234
+ # @api private
235
+ # @return [Hash] the shooting information hash
236
+ def self.shooting_info(data)
237
+ {fg2a_frequency: data["FG2A_FREQUENCY"], fg2m: data["FG2M"],
238
+ fg2a: data["FG2A"], fg2_pct: data["FG2_PCT"],
239
+ fg3a_frequency: data["FG3A_FREQUENCY"], fg3m: data["FG3M"],
240
+ fg3a: data["FG3A"], fg3_pct: data["FG3_PCT"]}
241
+ end
242
+ private_class_method :shooting_info
243
+ end
244
+ end