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,77 @@
1
+ require "equalizer"
2
+ require "shale"
3
+
4
+ module NBA
5
+ # Represents an all-time statistical leader
6
+ class AllTimeLeader < Shale::Mapper
7
+ include Equalizer.new(:player_id, :category)
8
+
9
+ # @!attribute [rw] player_id
10
+ # Returns the player ID
11
+ # @api public
12
+ # @example
13
+ # leader.player_id #=> 2544
14
+ # @return [Integer] the player ID
15
+ attribute :player_id, Shale::Type::Integer
16
+
17
+ # @!attribute [rw] player_name
18
+ # Returns the player name
19
+ # @api public
20
+ # @example
21
+ # leader.player_name #=> "LeBron James"
22
+ # @return [String] the player name
23
+ attribute :player_name, Shale::Type::String
24
+
25
+ # @!attribute [rw] category
26
+ # Returns the statistical category
27
+ # @api public
28
+ # @example
29
+ # leader.category #=> "PTS"
30
+ # @return [String] the category
31
+ attribute :category, Shale::Type::String
32
+
33
+ # @!attribute [rw] value
34
+ # Returns the stat value
35
+ # @api public
36
+ # @example
37
+ # leader.value #=> 40474
38
+ # @return [Float] the value
39
+ attribute :value, Shale::Type::Float
40
+
41
+ # @!attribute [rw] rank
42
+ # Returns the ranking position
43
+ # @api public
44
+ # @example
45
+ # leader.rank #=> 1
46
+ # @return [Integer] the rank
47
+ attribute :rank, Shale::Type::Integer
48
+
49
+ # @!attribute [rw] is_active
50
+ # Returns whether the player is active
51
+ # @api public
52
+ # @example
53
+ # leader.is_active #=> true
54
+ # @return [Boolean] whether active
55
+ attribute :is_active, Shale::Type::Boolean
56
+
57
+ # Returns the player object
58
+ #
59
+ # @api public
60
+ # @example
61
+ # leader.player #=> #<NBA::Player>
62
+ # @return [Player, nil] the player object
63
+ def player
64
+ Players.find(player_id)
65
+ end
66
+
67
+ # Returns whether the player is active
68
+ #
69
+ # @api public
70
+ # @example
71
+ # leader.active? #=> true
72
+ # @return [Boolean] true if active
73
+ def active?
74
+ is_active
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,185 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "all_time_leader"
5
+
6
+ module NBA
7
+ # Provides methods to retrieve all-time NBA statistical leaders
8
+ module AllTimeLeaders
9
+ # Points category
10
+ # @return [String] the category code
11
+ PTS = "PTS".freeze
12
+ # Rebounds category
13
+ # @return [String] the category code
14
+ REB = "REB".freeze
15
+ # Assists category
16
+ # @return [String] the category code
17
+ AST = "AST".freeze
18
+ # Steals category
19
+ # @return [String] the category code
20
+ STL = "STL".freeze
21
+ # Blocks category
22
+ # @return [String] the category code
23
+ BLK = "BLK".freeze
24
+ # Field goals made category
25
+ # @return [String] the category code
26
+ FGM = "FGM".freeze
27
+ # Field goals attempted category
28
+ # @return [String] the category code
29
+ FGA = "FGA".freeze
30
+ # Three pointers made category
31
+ # @return [String] the category code
32
+ FG3M = "FG3M".freeze
33
+ # Three pointers attempted category
34
+ # @return [String] the category code
35
+ FG3A = "FG3A".freeze
36
+ # Free throws made category
37
+ # @return [String] the category code
38
+ FTM = "FTM".freeze
39
+ # Free throws attempted category
40
+ # @return [String] the category code
41
+ FTA = "FTA".freeze
42
+ # Games played category
43
+ # @return [String] the category code
44
+ GP = "GP".freeze
45
+ # Turnovers category
46
+ # @return [String] the category code
47
+ TOV = "TOV".freeze
48
+ # Personal fouls category
49
+ # @return [String] the category code
50
+ PF = "PF".freeze
51
+ # Offensive rebounds category
52
+ # @return [String] the category code
53
+ OREB = "OREB".freeze
54
+ # Defensive rebounds category
55
+ # @return [String] the category code
56
+ DREB = "DREB".freeze
57
+
58
+ # Regular season type
59
+ # @return [String] the season type
60
+ REGULAR_SEASON = "Regular Season".freeze
61
+ # Playoffs season type
62
+ # @return [String] the season type
63
+ PLAYOFFS = "Playoffs".freeze
64
+
65
+ # Totals per mode
66
+ # @return [String] the per mode
67
+ TOTALS = "Totals".freeze
68
+ # Per game per mode
69
+ # @return [String] the per mode
70
+ PER_GAME = "PerGame".freeze
71
+
72
+ # Category to result set mapping
73
+ CATEGORY_RESULT_SETS = {
74
+ PTS => "PTSLeaders", REB => "REBLeaders", AST => "ASTLeaders",
75
+ STL => "STLLeaders", BLK => "BLKLeaders", FGM => "FGMLeaders",
76
+ FGA => "FGALeaders", FG3M => "FG3MLeaders", FG3A => "FG3ALeaders",
77
+ FTM => "FTMLeaders", FTA => "FTALeaders", GP => "GPLeaders",
78
+ TOV => "TOVLeaders", PF => "PFLeaders", OREB => "OREBLeaders",
79
+ DREB => "DREBLeaders"
80
+ }.freeze
81
+ private_constant :CATEGORY_RESULT_SETS
82
+
83
+ # Retrieves all-time leaders for a statistical category
84
+ #
85
+ # @api public
86
+ # @example
87
+ # leaders = NBA::AllTimeLeaders.find(category: NBA::AllTimeLeaders::PTS)
88
+ # leaders.each { |l| puts "#{l.rank}. #{l.player_name}: #{l.value.to_i}" }
89
+ # @param category [String] the statistical category (PTS, REB, AST, etc.)
90
+ # @param season_type [String] the season type (Regular Season, Playoffs)
91
+ # @param per_mode [String] the per mode (Totals, PerGame)
92
+ # @param limit [Integer] number of results to return (default 10)
93
+ # @param client [Client] the API client to use
94
+ # @return [Collection] a collection of all-time leaders
95
+ def self.find(category:, season_type: REGULAR_SEASON, per_mode: TOTALS, limit: 10, client: CLIENT)
96
+ path = build_path(season_type, per_mode, limit)
97
+ response = client.get(path)
98
+ parse_response(response, category, limit)
99
+ end
100
+
101
+ # Builds the API path
102
+ # @api private
103
+ # @param season_type [String] the season type
104
+ # @param per_mode [String] the per mode
105
+ # @param limit [Integer] the limit
106
+ # @return [String] the path
107
+ def self.build_path(season_type, per_mode, limit)
108
+ "alltimeleadersgrids?LeagueID=00&PerMode=#{per_mode}&SeasonType=#{season_type}&TopX=#{limit}"
109
+ end
110
+ private_class_method :build_path
111
+
112
+ # Parses the API response
113
+ # @api private
114
+ # @param response [String, nil] the JSON response
115
+ # @param category [String] the category
116
+ # @param limit [Integer] the limit
117
+ # @return [Collection] collection of leaders
118
+ def self.parse_response(response, category, limit)
119
+ return Collection.new unless response
120
+
121
+ data = JSON.parse(response)
122
+ result_set = find_result_set(data, CATEGORY_RESULT_SETS[category])
123
+ return Collection.new unless result_set
124
+
125
+ build_leaders(result_set, category, limit)
126
+ end
127
+ private_class_method :parse_response
128
+
129
+ # Finds a result set by name
130
+ # @api private
131
+ # @param data [Hash] the parsed JSON
132
+ # @param name [String] the result set name
133
+ # @return [Hash, nil] the result set
134
+ def self.find_result_set(data, name)
135
+ result_sets = data["resultSets"]
136
+ return unless result_sets
137
+
138
+ result_sets.find { |rs| rs.fetch("name").eql?(name) }
139
+ end
140
+ private_class_method :find_result_set
141
+
142
+ # Builds leaders collection from result set
143
+ # @api private
144
+ # @param result_set [Hash] the result set
145
+ # @param category [String] the category
146
+ # @param limit [Integer] the limit
147
+ # @return [Collection] collection of leaders
148
+ def self.build_leaders(result_set, category, limit)
149
+ headers = result_set["headers"]
150
+ rows = result_set["rowSet"]
151
+ return Collection.new unless headers && rows
152
+
153
+ leaders = rows.take(limit).map.with_index(1) do |row, rank|
154
+ build_leader(headers, row, category, rank)
155
+ end
156
+ Collection.new(leaders)
157
+ end
158
+ private_class_method :build_leaders
159
+
160
+ # Builds a single leader
161
+ # @api private
162
+ # @param headers [Array<String>] the headers
163
+ # @param row [Array] the row data
164
+ # @param category [String] the category
165
+ # @param rank [Integer] the rank
166
+ # @return [AllTimeLeader] the leader
167
+ def self.build_leader(headers, row, category, rank)
168
+ data = headers.zip(row).to_h
169
+ AllTimeLeader.new(**leader_attributes(data, category, rank))
170
+ end
171
+ private_class_method :build_leader
172
+
173
+ # Extracts leader attributes from data
174
+ # @api private
175
+ # @param data [Hash] the raw data
176
+ # @param category [String] the category
177
+ # @param rank [Integer] the rank
178
+ # @return [Hash] the attributes
179
+ def self.leader_attributes(data, category, rank)
180
+ {player_id: data.fetch("PLAYER_ID"), player_name: data.fetch("PLAYER_NAME"), category: category,
181
+ value: data.fetch(category), rank: rank, is_active: data.fetch("IS_ACTIVE_FLAG").eql?("Y")}
182
+ end
183
+ private_class_method :leader_attributes
184
+ end
185
+ end
@@ -0,0 +1,92 @@
1
+ require "equalizer"
2
+ require "shale"
3
+ require_relative "players"
4
+ require_relative "teams"
5
+
6
+ module NBA
7
+ # Represents an assist leader entry
8
+ class AssistLeader < Shale::Mapper
9
+ include Equalizer.new(:player_id, :rank)
10
+
11
+ # @!attribute [rw] player_id
12
+ # Returns the player ID
13
+ # @api public
14
+ # @example
15
+ # leader.player_id #=> 201566
16
+ # @return [Integer] the player ID
17
+ attribute :player_id, Shale::Type::Integer
18
+
19
+ # @!attribute [rw] player_name
20
+ # Returns the player name
21
+ # @api public
22
+ # @example
23
+ # leader.player_name #=> "Russell Westbrook"
24
+ # @return [String] the player name
25
+ attribute :player_name, Shale::Type::String
26
+
27
+ # @!attribute [rw] team_id
28
+ # Returns the team ID
29
+ # @api public
30
+ # @example
31
+ # leader.team_id #=> 1610612746
32
+ # @return [Integer] the team ID
33
+ attribute :team_id, Shale::Type::Integer
34
+
35
+ # @!attribute [rw] team_abbreviation
36
+ # Returns the team abbreviation
37
+ # @api public
38
+ # @example
39
+ # leader.team_abbreviation #=> "LAC"
40
+ # @return [String] the team abbreviation
41
+ attribute :team_abbreviation, Shale::Type::String
42
+
43
+ # @!attribute [rw] rank
44
+ # Returns the rank in the category
45
+ # @api public
46
+ # @example
47
+ # leader.rank #=> 1
48
+ # @return [Integer] the rank
49
+ attribute :rank, Shale::Type::Integer
50
+
51
+ # @!attribute [rw] ast
52
+ # Returns the total assists
53
+ # @api public
54
+ # @example
55
+ # leader.ast #=> 654
56
+ # @return [Integer] the total assists
57
+ attribute :ast, Shale::Type::Integer
58
+
59
+ # Returns the player object for this leader
60
+ #
61
+ # @api public
62
+ # @example
63
+ # leader.player #=> #<NBA::Player>
64
+ # @return [Player, nil] the hydrated player object
65
+ def player
66
+ Players.find(player_id)
67
+ end
68
+
69
+ # Returns the team object for this leader
70
+ #
71
+ # @api public
72
+ # @example
73
+ # leader.team #=> #<NBA::Team>
74
+ # @return [Team, nil] the team object
75
+ def team
76
+ Teams.find(team_id)
77
+ end
78
+
79
+ json do
80
+ map "player_id", to: :player_id
81
+ map "playerId", to: :player_id
82
+ map "player_name", to: :player_name
83
+ map "playerName", to: :player_name
84
+ map "team_id", to: :team_id
85
+ map "teamId", to: :team_id
86
+ map "team_abbreviation", to: :team_abbreviation
87
+ map "teamAbbreviation", to: :team_abbreviation
88
+ map "rank", to: :rank
89
+ map "ast", to: :ast
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,64 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "assist_leader"
5
+ require_relative "response_parser"
6
+ require_relative "utils"
7
+
8
+ module NBA
9
+ # Provides methods to retrieve NBA assist leaders
10
+ module AssistLeaders
11
+ # Result set name for assist leaders
12
+ # @return [String] the result set name
13
+ RESULT_SET = "AssistLeaders".freeze
14
+
15
+ # Retrieves assist leaders for a season
16
+ #
17
+ # @api public
18
+ # @example
19
+ # leaders = NBA::AssistLeaders.all(season: 2023)
20
+ # leaders.each { |leader| puts "#{leader.rank}. #{leader.player_name}: #{leader.ast}" }
21
+ # @param season [Integer] the season year (defaults to current season)
22
+ # @param season_type [String] the season type (Regular Season, Playoffs, etc.)
23
+ # @param per_mode [String] the per mode (Totals, PerGame)
24
+ # @param player_or_team [String] player or team stats (Player, Team)
25
+ # @param league [String, League] the league ID or League object (default NBA)
26
+ # @param client [Client] the API client to use
27
+ # @return [Collection] a collection of assist leaders
28
+ def self.all(season: Utils.current_season, season_type: "Regular Season", per_mode: "Totals",
29
+ player_or_team: "Player", league: League::NBA, client: CLIENT)
30
+ league_id = Utils.extract_league_id(league)
31
+ path = build_path(season, season_type, per_mode, player_or_team, league_id)
32
+ ResponseParser.parse(client.get(path), result_set: RESULT_SET) { |data| build_leader(data) }
33
+ end
34
+
35
+ # Builds the API request path
36
+ # @api private
37
+ # @return [String] the request path
38
+ def self.build_path(season, season_type, per_mode, player_or_team, league_id)
39
+ "assistleaders?LeagueID=#{league_id}&PerMode=#{per_mode}&PlayerOrTeam=#{player_or_team}" \
40
+ "&Season=#{Utils.format_season(season)}&SeasonType=#{season_type}"
41
+ end
42
+ private_class_method :build_path
43
+
44
+ # Builds an AssistLeader object from raw data
45
+ # @api private
46
+ # @param data [Hash] the row data
47
+ # @return [AssistLeader] the leader object
48
+ def self.build_leader(data)
49
+ AssistLeader.new(**leader_attributes(data))
50
+ end
51
+ private_class_method :build_leader
52
+
53
+ # Extracts leader attributes from data
54
+ # @api private
55
+ # @param data [Hash] the row data
56
+ # @return [Hash] leader attributes
57
+ def self.leader_attributes(data)
58
+ {player_id: data["PLAYER_ID"], player_name: data["PLAYER_NAME"],
59
+ team_id: data["TEAM_ID"], team_abbreviation: data["TEAM_ABBREVIATION"],
60
+ rank: data["RANK"], ast: data["AST"]}
61
+ end
62
+ private_class_method :leader_attributes
63
+ end
64
+ end
@@ -0,0 +1,108 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "assist_tracker_entry"
5
+ require_relative "response_parser"
6
+ require_relative "utils"
7
+
8
+ module NBA
9
+ # Provides methods to retrieve NBA assist tracker data (who passes to who)
10
+ module AssistTracker
11
+ # Result set name for assist tracker
12
+ # @return [String] the result set name
13
+ RESULT_SET = "AssistTracker".freeze
14
+
15
+ # Retrieves assist tracker data for a season
16
+ #
17
+ # @api public
18
+ # @example
19
+ # entries = NBA::AssistTracker.all(season: 2023)
20
+ # entries.each { |e| puts "#{e.player_name} -> #{e.pass_to}: #{e.ast} assists" }
21
+ # @param season [Integer] the season year (defaults to current season)
22
+ # @param season_type [String] the season type (Regular Season, Playoffs, etc.)
23
+ # @param per_mode [String] the per mode (Totals, PerGame)
24
+ # @param league [String, League] the league ID or League object (default NBA)
25
+ # @param client [Client] the API client to use
26
+ # @return [Collection] a collection of assist tracker entries
27
+ def self.all(season: Utils.current_season, season_type: "Regular Season", per_mode: "Totals",
28
+ league: League::NBA, client: CLIENT)
29
+ league_id = Utils.extract_league_id(league)
30
+ path = build_path(season, season_type, per_mode, league_id)
31
+ ResponseParser.parse(client.get(path), result_set: RESULT_SET) { |data| build_entry(data) }
32
+ end
33
+
34
+ # Builds the API request path
35
+ # @api private
36
+ # @return [String] the request path
37
+ def self.build_path(season, season_type, per_mode, league_id)
38
+ "assisttracker?LeagueID=#{league_id}&PerMode=#{per_mode}" \
39
+ "&Season=#{Utils.format_season(season)}&SeasonType=#{season_type}"
40
+ end
41
+ private_class_method :build_path
42
+
43
+ # Builds an AssistTrackerEntry object from raw data
44
+ # @api private
45
+ # @param data [Hash] the row data
46
+ # @return [AssistTrackerEntry] the entry object
47
+ def self.build_entry(data)
48
+ AssistTrackerEntry.new(**player_attrs(data), **pass_attrs(data), **shooting_attrs(data))
49
+ end
50
+ private_class_method :build_entry
51
+
52
+ # Extracts player attributes from data
53
+ # @api private
54
+ # @param data [Hash] the row data
55
+ # @return [Hash] player attributes
56
+ def self.player_attrs(data)
57
+ {player_id: data["PLAYER_ID"], player_name: data["PLAYER_NAME"],
58
+ team_id: data["TEAM_ID"], team_abbreviation: data["TEAM_ABBREVIATION"]}
59
+ end
60
+ private_class_method :player_attrs
61
+
62
+ # Extracts pass attributes from data
63
+ # @api private
64
+ # @param data [Hash] the row data
65
+ # @return [Hash] pass attributes
66
+ def self.pass_attrs(data)
67
+ {pass_to: data["PASS_TO"], pass_to_player_id: data["PASS_TO_PLAYER_ID"],
68
+ frequency: data["FREQUENCY"], pass: data["PASS"], ast: data["AST"]}
69
+ end
70
+ private_class_method :pass_attrs
71
+
72
+ # Extracts shooting attributes from data
73
+ # @api private
74
+ # @param data [Hash] the row data
75
+ # @return [Hash] shooting attributes
76
+ def self.shooting_attrs(data)
77
+ fg_attrs(data).merge(fg2_attrs(data)).merge(fg3_attrs(data))
78
+ end
79
+ private_class_method :shooting_attrs
80
+
81
+ # Extracts field goal attributes from data
82
+ # @api private
83
+ # @param data [Hash] the row data
84
+ # @return [Hash] field goal attributes
85
+ def self.fg_attrs(data)
86
+ {fg_m: data["FGM"], fg_a: data["FGA"], fg_pct: data["FG_PCT"]}
87
+ end
88
+ private_class_method :fg_attrs
89
+
90
+ # Extracts 2-point field goal attributes from data
91
+ # @api private
92
+ # @param data [Hash] the row data
93
+ # @return [Hash] 2-point field goal attributes
94
+ def self.fg2_attrs(data)
95
+ {fg2m: data["FG2M"], fg2a: data["FG2A"], fg2_pct: data["FG2_PCT"]}
96
+ end
97
+ private_class_method :fg2_attrs
98
+
99
+ # Extracts 3-point field goal attributes from data
100
+ # @api private
101
+ # @param data [Hash] the row data
102
+ # @return [Hash] 3-point field goal attributes
103
+ def self.fg3_attrs(data)
104
+ {fg3m: data["FG3M"], fg3a: data["FG3A"], fg3_pct: data["FG3_PCT"]}
105
+ end
106
+ private_class_method :fg3_attrs
107
+ end
108
+ end