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,275 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "utils"
5
+
6
+ require_relative "team_dashboard_stat"
7
+
8
+ module NBA
9
+ # Provides methods to retrieve team dashboard data with various splits
10
+ module TeamDashboard
11
+ # Season type constant for regular season
12
+ # @return [String] the season type
13
+ REGULAR_SEASON = "Regular Season".freeze
14
+
15
+ # Season type constant for playoffs
16
+ # @return [String] the season type
17
+ PLAYOFFS = "Playoffs".freeze
18
+
19
+ # Per mode constant for per game stats
20
+ # @return [String] the per mode
21
+ PER_GAME = "PerGame".freeze
22
+
23
+ # Per mode constant for totals
24
+ # @return [String] the per mode
25
+ TOTALS = "Totals".freeze
26
+
27
+ # Per mode constant for per 100 possessions
28
+ # @return [String] the per mode
29
+ PER_100 = "Per100Possessions".freeze
30
+
31
+ # Retrieves team dashboard by general splits
32
+ #
33
+ # @api public
34
+ # @example
35
+ # stats = NBA::TeamDashboard.general_splits(team: NBA::Team::GSW)
36
+ # stats.each { |s| puts "#{s.group_value}: #{s.pts} ppg" }
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 dashboard stats
43
+ def self.general_splits(team:, season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
44
+ fetch_dashboard(team, season, season_type, per_mode, "teamdashboardbygeneralsplits", client: client)
45
+ end
46
+
47
+ # Retrieves team dashboard by shooting splits
48
+ #
49
+ # @api public
50
+ # @example
51
+ # stats = NBA::TeamDashboard.shooting_splits(team: NBA::Team::GSW)
52
+ # stats.each { |s| puts "#{s.group_value}: #{s.fg_pct}" }
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 dashboard stats
59
+ def self.shooting_splits(team:, season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
60
+ fetch_dashboard(team, season, season_type, per_mode, "teamdashboardbyshootingsplits", client: client)
61
+ end
62
+
63
+ # Retrieves team lineup data
64
+ #
65
+ # @api public
66
+ # @example
67
+ # stats = NBA::TeamDashboard.lineups(team: NBA::Team::GSW)
68
+ # stats.each { |s| puts "#{s.group_value}: #{s.pts} ppg" }
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 dashboard stats
75
+ def self.lineups(team:, season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
76
+ fetch_dashboard(team, season, season_type, per_mode, "teamdashlineups", client: client)
77
+ end
78
+
79
+ # Retrieves team dashboard by clutch splits
80
+ #
81
+ # @api public
82
+ # @example
83
+ # stats = NBA::TeamDashboard.clutch_splits(team: NBA::Team::GSW)
84
+ # stats.each { |s| puts "#{s.group_value}: #{s.pts} ppg" }
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 dashboard stats
91
+ def self.clutch_splits(team:, season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
92
+ fetch_dashboard(team, season, season_type, per_mode, "teamdashboardbyclutch", client: client)
93
+ end
94
+
95
+ # Retrieves team dashboard by game splits
96
+ #
97
+ # @api public
98
+ # @example
99
+ # stats = NBA::TeamDashboard.game_splits(team: NBA::Team::GSW)
100
+ # stats.each { |s| puts "#{s.group_value}: #{s.pts} ppg" }
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 dashboard stats
107
+ def self.game_splits(team:, season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
108
+ fetch_dashboard(team, season, season_type, per_mode, "teamdashboardbygamesplits", client: client)
109
+ end
110
+
111
+ # Retrieves team dashboard by last N games
112
+ #
113
+ # @api public
114
+ # @example
115
+ # stats = NBA::TeamDashboard.last_n_games(team: NBA::Team::GSW)
116
+ # stats.each { |s| puts "#{s.group_value}: #{s.pts} ppg" }
117
+ # @param team [Integer, Team] the team ID or Team object
118
+ # @param season [Integer] the season year
119
+ # @param season_type [String] the season type
120
+ # @param per_mode [String] the per mode
121
+ # @param client [Client] the API client to use
122
+ # @return [Collection] a collection of dashboard stats
123
+ def self.last_n_games(team:, season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
124
+ fetch_dashboard(team, season, season_type, per_mode, "teamdashboardbylastngames", client: client)
125
+ end
126
+
127
+ # Retrieves team dashboard by team performance
128
+ #
129
+ # @api public
130
+ # @example
131
+ # stats = NBA::TeamDashboard.team_performance(team: NBA::Team::GSW)
132
+ # stats.each { |s| puts "#{s.group_value}: #{s.pts} ppg" }
133
+ # @param team [Integer, Team] the team ID or Team object
134
+ # @param season [Integer] the season year
135
+ # @param season_type [String] the season type
136
+ # @param per_mode [String] the per mode
137
+ # @param client [Client] the API client to use
138
+ # @return [Collection] a collection of dashboard stats
139
+ def self.team_performance(team:, season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
140
+ fetch_dashboard(team, season, season_type, per_mode, "teamdashboardbyteamperformance", client: client)
141
+ end
142
+
143
+ # Retrieves team dashboard by year over year
144
+ #
145
+ # @api public
146
+ # @example
147
+ # stats = NBA::TeamDashboard.year_over_year(team: NBA::Team::GSW)
148
+ # stats.each { |s| puts "#{s.group_value}: #{s.pts} ppg" }
149
+ # @param team [Integer, Team] the team ID or Team object
150
+ # @param season [Integer] the season year
151
+ # @param season_type [String] the season type
152
+ # @param per_mode [String] the per mode
153
+ # @param client [Client] the API client to use
154
+ # @return [Collection] a collection of dashboard stats
155
+ def self.year_over_year(team:, season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
156
+ fetch_dashboard(team, season, season_type, per_mode, "teamdashboardbyyearoveryear", client: client)
157
+ end
158
+
159
+ # Fetches dashboard data from the API
160
+ #
161
+ # @api private
162
+ # @return [Collection] collection of dashboard stats
163
+ def self.fetch_dashboard(team, season, season_type, per_mode, endpoint, client:)
164
+ team_id = Utils.extract_id(team)
165
+ path = build_path(team_id, season, season_type, per_mode, endpoint)
166
+ response = client.get(path)
167
+ parse_response(response, team_id)
168
+ end
169
+ private_class_method :fetch_dashboard
170
+
171
+ # Builds the API path
172
+ #
173
+ # @api private
174
+ # @return [String] the request path
175
+ def self.build_path(team_id, season, season_type, per_mode, endpoint)
176
+ season_str = Utils.format_season(season)
177
+ "#{endpoint}?TeamID=#{team_id}&Season=#{season_str}&SeasonType=#{season_type}&PerMode=#{per_mode}&LeagueID=00"
178
+ end
179
+ private_class_method :build_path
180
+
181
+ # Parses the API response into dashboard stat objects
182
+ #
183
+ # @api private
184
+ # @return [Collection] collection of dashboard stats
185
+ def self.parse_response(response, team_id)
186
+ return Collection.new unless response
187
+
188
+ data = JSON.parse(response)
189
+ result_sets = data["resultSets"]
190
+ return Collection.new unless result_sets
191
+
192
+ all_stats = result_sets.flat_map { |rs| parse_result_set(rs, team_id) }
193
+ Collection.new(all_stats)
194
+ end
195
+ private_class_method :parse_response
196
+
197
+ # Parses a result set into stat objects
198
+ #
199
+ # @api private
200
+ # @return [Array<TeamDashboardStat>] array of stats
201
+ def self.parse_result_set(result_set, team_id)
202
+ headers = result_set["headers"]
203
+ rows = result_set["rowSet"]
204
+ group_set = result_set["name"]
205
+ return [] unless headers && rows
206
+
207
+ rows.map { |row| build_dashboard_stat(headers, row, group_set, team_id) }
208
+ end
209
+ private_class_method :parse_result_set
210
+
211
+ # Builds a TeamDashboardStat object from raw data
212
+ #
213
+ # @api private
214
+ # @return [TeamDashboardStat] the dashboard stat object
215
+ def self.build_dashboard_stat(headers, row, group_set, team_id)
216
+ data = headers.zip(row).to_h
217
+ TeamDashboardStat.new(**dashboard_attributes(data, group_set, team_id))
218
+ end
219
+ private_class_method :build_dashboard_stat
220
+
221
+ # Combines all dashboard attributes
222
+ #
223
+ # @api private
224
+ # @return [Hash] the combined attributes
225
+ def self.dashboard_attributes(data, group_set, team_id)
226
+ identity_attributes(data, group_set, team_id)
227
+ .merge(record_attributes(data))
228
+ .merge(shooting_attributes(data))
229
+ .merge(counting_attributes(data))
230
+ end
231
+ private_class_method :dashboard_attributes
232
+
233
+ # Extracts identity attributes from data
234
+ #
235
+ # @api private
236
+ # @return [Hash] identity attributes
237
+ def self.identity_attributes(data, group_set, team_id)
238
+ {group_set: group_set, group_value: data["GROUP_VALUE"],
239
+ team_id: team_id, gp: data["GP"], min: data["MIN"]}
240
+ end
241
+ private_class_method :identity_attributes
242
+
243
+ # Extracts record attributes from data
244
+ #
245
+ # @api private
246
+ # @return [Hash] record attributes
247
+ def self.record_attributes(data)
248
+ {w: data["W"], l: data["L"], w_pct: data["W_PCT"]}
249
+ end
250
+ private_class_method :record_attributes
251
+
252
+ # Extracts shooting attributes from data
253
+ #
254
+ # @api private
255
+ # @return [Hash] shooting attributes
256
+ def self.shooting_attributes(data)
257
+ {fgm: data["FGM"], fga: data["FGA"], fg_pct: data["FG_PCT"],
258
+ fg3m: data["FG3M"], fg3a: data["FG3A"], fg3_pct: data["FG3_PCT"],
259
+ ftm: data["FTM"], fta: data["FTA"], ft_pct: data["FT_PCT"]}
260
+ end
261
+ private_class_method :shooting_attributes
262
+
263
+ # Extracts counting stats attributes from data
264
+ #
265
+ # @api private
266
+ # @return [Hash] counting attributes
267
+ def self.counting_attributes(data)
268
+ {oreb: data["OREB"], dreb: data["DREB"], reb: data["REB"],
269
+ ast: data["AST"], tov: data["TOV"], stl: data["STL"], blk: data["BLK"],
270
+ blka: data["BLKA"], pf: data["PF"], pfd: data["PFD"],
271
+ pts: data["PTS"], plus_minus: data["PLUS_MINUS"]}
272
+ end
273
+ private_class_method :counting_attributes
274
+ end
275
+ end
@@ -0,0 +1,248 @@
1
+ module NBA
2
+ # Represents team dashboard split statistics
3
+ class TeamDashboardStat < Shale::Mapper
4
+ include Equalizer.new(:team_id, :group_value)
5
+
6
+ # @!attribute [rw] group_set
7
+ # Returns the group set name
8
+ # @api public
9
+ # @example
10
+ # stat.group_set #=> "Overall"
11
+ # @return [String] the group set
12
+ attribute :group_set, Shale::Type::String
13
+
14
+ # @!attribute [rw] group_value
15
+ # Returns the group value
16
+ # @api public
17
+ # @example
18
+ # stat.group_value #=> "2023-24"
19
+ # @return [String] the group value
20
+ attribute :group_value, Shale::Type::String
21
+
22
+ # @!attribute [rw] team_id
23
+ # Returns the team ID
24
+ # @api public
25
+ # @example
26
+ # stat.team_id #=> 1610612744
27
+ # @return [Integer] the team ID
28
+ attribute :team_id, Shale::Type::Integer
29
+
30
+ # @!attribute [rw] gp
31
+ # Returns games played
32
+ # @api public
33
+ # @example
34
+ # stat.gp #=> 82
35
+ # @return [Integer] games played
36
+ attribute :gp, Shale::Type::Integer
37
+
38
+ # @!attribute [rw] w
39
+ # Returns wins
40
+ # @api public
41
+ # @example
42
+ # stat.w #=> 46
43
+ # @return [Integer] wins
44
+ attribute :w, Shale::Type::Integer
45
+
46
+ # @!attribute [rw] l
47
+ # Returns losses
48
+ # @api public
49
+ # @example
50
+ # stat.l #=> 36
51
+ # @return [Integer] losses
52
+ attribute :l, Shale::Type::Integer
53
+
54
+ # @!attribute [rw] w_pct
55
+ # Returns win percentage
56
+ # @api public
57
+ # @example
58
+ # stat.w_pct #=> 0.561
59
+ # @return [Float] win percentage
60
+ attribute :w_pct, Shale::Type::Float
61
+
62
+ # @!attribute [rw] min
63
+ # Returns minutes per game
64
+ # @api public
65
+ # @example
66
+ # stat.min #=> 240.0
67
+ # @return [Float] minutes
68
+ attribute :min, Shale::Type::Float
69
+
70
+ # @!attribute [rw] fgm
71
+ # Returns field goals made per game
72
+ # @api public
73
+ # @example
74
+ # stat.fgm #=> 39.6
75
+ # @return [Float] field goals made
76
+ attribute :fgm, Shale::Type::Float
77
+
78
+ # @!attribute [rw] fga
79
+ # Returns field goals attempted per game
80
+ # @api public
81
+ # @example
82
+ # stat.fga #=> 87.8
83
+ # @return [Float] field goals attempted
84
+ attribute :fga, Shale::Type::Float
85
+
86
+ # @!attribute [rw] fg_pct
87
+ # Returns field goal percentage
88
+ # @api public
89
+ # @example
90
+ # stat.fg_pct #=> 0.451
91
+ # @return [Float] field goal percentage
92
+ attribute :fg_pct, Shale::Type::Float
93
+
94
+ # @!attribute [rw] fg3m
95
+ # Returns three-pointers made per game
96
+ # @api public
97
+ # @example
98
+ # stat.fg3m #=> 14.8
99
+ # @return [Float] three-pointers made
100
+ attribute :fg3m, Shale::Type::Float
101
+
102
+ # @!attribute [rw] fg3a
103
+ # Returns three-pointers attempted per game
104
+ # @api public
105
+ # @example
106
+ # stat.fg3a #=> 40.2
107
+ # @return [Float] three-pointers attempted
108
+ attribute :fg3a, Shale::Type::Float
109
+
110
+ # @!attribute [rw] fg3_pct
111
+ # Returns three-point percentage
112
+ # @api public
113
+ # @example
114
+ # stat.fg3_pct #=> 0.368
115
+ # @return [Float] three-point percentage
116
+ attribute :fg3_pct, Shale::Type::Float
117
+
118
+ # @!attribute [rw] ftm
119
+ # Returns free throws made per game
120
+ # @api public
121
+ # @example
122
+ # stat.ftm #=> 17.8
123
+ # @return [Float] free throws made
124
+ attribute :ftm, Shale::Type::Float
125
+
126
+ # @!attribute [rw] fta
127
+ # Returns free throws attempted per game
128
+ # @api public
129
+ # @example
130
+ # stat.fta #=> 22.1
131
+ # @return [Float] free throws attempted
132
+ attribute :fta, Shale::Type::Float
133
+
134
+ # @!attribute [rw] ft_pct
135
+ # Returns free throw percentage
136
+ # @api public
137
+ # @example
138
+ # stat.ft_pct #=> 0.805
139
+ # @return [Float] free throw percentage
140
+ attribute :ft_pct, Shale::Type::Float
141
+
142
+ # @!attribute [rw] oreb
143
+ # Returns offensive rebounds per game
144
+ # @api public
145
+ # @example
146
+ # stat.oreb #=> 9.1
147
+ # @return [Float] offensive rebounds
148
+ attribute :oreb, Shale::Type::Float
149
+
150
+ # @!attribute [rw] dreb
151
+ # Returns defensive rebounds per game
152
+ # @api public
153
+ # @example
154
+ # stat.dreb #=> 34.8
155
+ # @return [Float] defensive rebounds
156
+ attribute :dreb, Shale::Type::Float
157
+
158
+ # @!attribute [rw] reb
159
+ # Returns total rebounds per game
160
+ # @api public
161
+ # @example
162
+ # stat.reb #=> 43.9
163
+ # @return [Float] total rebounds
164
+ attribute :reb, Shale::Type::Float
165
+
166
+ # @!attribute [rw] ast
167
+ # Returns assists per game
168
+ # @api public
169
+ # @example
170
+ # stat.ast #=> 27.5
171
+ # @return [Float] assists
172
+ attribute :ast, Shale::Type::Float
173
+
174
+ # @!attribute [rw] tov
175
+ # Returns turnovers per game
176
+ # @api public
177
+ # @example
178
+ # stat.tov #=> 14.1
179
+ # @return [Float] turnovers
180
+ attribute :tov, Shale::Type::Float
181
+
182
+ # @!attribute [rw] stl
183
+ # Returns steals per game
184
+ # @api public
185
+ # @example
186
+ # stat.stl #=> 7.6
187
+ # @return [Float] steals
188
+ attribute :stl, Shale::Type::Float
189
+
190
+ # @!attribute [rw] blk
191
+ # Returns blocks per game
192
+ # @api public
193
+ # @example
194
+ # stat.blk #=> 4.8
195
+ # @return [Float] blocks
196
+ attribute :blk, Shale::Type::Float
197
+
198
+ # @!attribute [rw] blka
199
+ # Returns blocked attempts per game
200
+ # @api public
201
+ # @example
202
+ # stat.blka #=> 4.2
203
+ # @return [Float] blocked attempts
204
+ attribute :blka, Shale::Type::Float
205
+
206
+ # @!attribute [rw] pf
207
+ # Returns personal fouls per game
208
+ # @api public
209
+ # @example
210
+ # stat.pf #=> 20.1
211
+ # @return [Float] personal fouls
212
+ attribute :pf, Shale::Type::Float
213
+
214
+ # @!attribute [rw] pfd
215
+ # Returns personal fouls drawn per game
216
+ # @api public
217
+ # @example
218
+ # stat.pfd #=> 18.9
219
+ # @return [Float] personal fouls drawn
220
+ attribute :pfd, Shale::Type::Float
221
+
222
+ # @!attribute [rw] pts
223
+ # Returns points per game
224
+ # @api public
225
+ # @example
226
+ # stat.pts #=> 111.8
227
+ # @return [Float] points
228
+ attribute :pts, Shale::Type::Float
229
+
230
+ # @!attribute [rw] plus_minus
231
+ # Returns plus/minus per game
232
+ # @api public
233
+ # @example
234
+ # stat.plus_minus #=> 2.5
235
+ # @return [Float] plus/minus
236
+ attribute :plus_minus, Shale::Type::Float
237
+
238
+ # Returns the team object
239
+ #
240
+ # @api public
241
+ # @example
242
+ # stat.team #=> #<NBA::Team>
243
+ # @return [Team, nil] the team object
244
+ def team
245
+ Teams.find(team_id)
246
+ end
247
+ end
248
+ end
@@ -0,0 +1,117 @@
1
+ require "equalizer"
2
+ require "shale"
3
+
4
+ module NBA
5
+ # Represents detailed team information
6
+ class TeamDetail < Shale::Mapper
7
+ include Equalizer.new(:team_id)
8
+
9
+ # @!attribute [rw] team_id
10
+ # Returns the team ID
11
+ # @api public
12
+ # @example
13
+ # detail.team_id #=> 1610612744
14
+ # @return [Integer] the team ID
15
+ attribute :team_id, Shale::Type::Integer
16
+
17
+ # @!attribute [rw] abbreviation
18
+ # Returns the team abbreviation
19
+ # @api public
20
+ # @example
21
+ # detail.abbreviation #=> "GSW"
22
+ # @return [String] the abbreviation
23
+ attribute :abbreviation, Shale::Type::String
24
+
25
+ # @!attribute [rw] nickname
26
+ # Returns the team nickname
27
+ # @api public
28
+ # @example
29
+ # detail.nickname #=> "Warriors"
30
+ # @return [String] the nickname
31
+ attribute :nickname, Shale::Type::String
32
+
33
+ # @!attribute [rw] year_founded
34
+ # Returns the year the team was founded
35
+ # @api public
36
+ # @example
37
+ # detail.year_founded #=> 1946
38
+ # @return [Integer] the year founded
39
+ attribute :year_founded, Shale::Type::Integer
40
+
41
+ # @!attribute [rw] city
42
+ # Returns the team city
43
+ # @api public
44
+ # @example
45
+ # detail.city #=> "Golden State"
46
+ # @return [String] the city
47
+ attribute :city, Shale::Type::String
48
+
49
+ # @!attribute [rw] arena
50
+ # Returns the team's home arena
51
+ # @api public
52
+ # @example
53
+ # detail.arena #=> "Chase Center"
54
+ # @return [String] the arena
55
+ attribute :arena, Shale::Type::String
56
+
57
+ # @!attribute [rw] arena_capacity
58
+ # Returns the arena capacity
59
+ # @api public
60
+ # @example
61
+ # detail.arena_capacity #=> 18064
62
+ # @return [Integer] the capacity
63
+ attribute :arena_capacity, Shale::Type::Integer
64
+
65
+ # @!attribute [rw] owner
66
+ # Returns the team owner
67
+ # @api public
68
+ # @example
69
+ # detail.owner #=> "Joe Lacob"
70
+ # @return [String] the owner
71
+ attribute :owner, Shale::Type::String
72
+
73
+ # @!attribute [rw] general_manager
74
+ # Returns the general manager
75
+ # @api public
76
+ # @example
77
+ # detail.general_manager #=> "Mike Dunleavy Jr."
78
+ # @return [String] the general manager
79
+ attribute :general_manager, Shale::Type::String
80
+
81
+ # @!attribute [rw] head_coach
82
+ # Returns the head coach
83
+ # @api public
84
+ # @example
85
+ # detail.head_coach #=> "Steve Kerr"
86
+ # @return [String] the head coach
87
+ attribute :head_coach, Shale::Type::String
88
+
89
+ # @!attribute [rw] d_league_affiliation
90
+ # Returns the G League affiliate
91
+ # @api public
92
+ # @example
93
+ # detail.d_league_affiliation #=> "Santa Cruz Warriors"
94
+ # @return [String] the G League affiliate
95
+ attribute :d_league_affiliation, Shale::Type::String
96
+
97
+ # Returns the team object
98
+ #
99
+ # @api public
100
+ # @example
101
+ # detail.team #=> #<NBA::Team>
102
+ # @return [Team, nil] the team object
103
+ def team
104
+ Teams.find(team_id)
105
+ end
106
+
107
+ # Returns the full team name
108
+ #
109
+ # @api public
110
+ # @example
111
+ # detail.full_name #=> "Golden State Warriors"
112
+ # @return [String] the full name
113
+ def full_name
114
+ "#{city} #{nickname}".strip
115
+ end
116
+ end
117
+ end