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,147 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "fantasy_profile_stat"
5
+ require_relative "utils"
6
+
7
+ module NBA
8
+ # Provides methods to retrieve player fantasy profile bar graph statistics
9
+ #
10
+ # @api public
11
+ module PlayerFantasyProfileBarGraph
12
+ # Result set name for last five games average
13
+ # @return [String] the result set name
14
+ LAST_FIVE_GAMES_AVG = "LastFiveGamesAvg".freeze
15
+
16
+ # Result set name for season average
17
+ # @return [String] the result set name
18
+ SEASON_AVG = "SeasonAvg".freeze
19
+
20
+ # Retrieves last five games average statistics for a player
21
+ #
22
+ # @api public
23
+ # @example
24
+ # stats = NBA::PlayerFantasyProfileBarGraph.last_five_games_avg(player: 201939)
25
+ # stats.first.fan_duel_pts #=> 45.2
26
+ # @param player [Integer, Player] the player ID or Player object
27
+ # @param season [Integer] the season year
28
+ # @param season_type [String] the season type
29
+ # @param client [Client] the API client to use
30
+ # @return [Collection] a collection of fantasy profile statistics
31
+ def self.last_five_games_avg(player:, season: Utils.current_season, season_type: "Regular Season",
32
+ client: CLIENT)
33
+ path = build_path(player, season, season_type)
34
+ response = client.get(path)
35
+ parse_response(response, LAST_FIVE_GAMES_AVG)
36
+ end
37
+
38
+ # Retrieves season average statistics for a player
39
+ #
40
+ # @api public
41
+ # @example
42
+ # stats = NBA::PlayerFantasyProfileBarGraph.season_avg(player: 201939)
43
+ # stats.first.nba_fantasy_pts #=> 52.1
44
+ # @param player [Integer, Player] the player ID or Player object
45
+ # @param season [Integer] the season year
46
+ # @param season_type [String] the season type
47
+ # @param client [Client] the API client to use
48
+ # @return [Collection] a collection of fantasy profile statistics
49
+ def self.season_avg(player:, season: Utils.current_season, season_type: "Regular Season",
50
+ client: CLIENT)
51
+ path = build_path(player, season, season_type)
52
+ response = client.get(path)
53
+ parse_response(response, SEASON_AVG)
54
+ end
55
+
56
+ # Builds the API path
57
+ #
58
+ # @api private
59
+ # @return [String] the request path
60
+ def self.build_path(player, season, season_type)
61
+ player_id = Utils.extract_id(player)
62
+ season_str = Utils.format_season(season)
63
+ "playerfantasyprofilebargraph?PlayerID=#{player_id}&Season=#{season_str}" \
64
+ "&SeasonType=#{season_type}&LeagueID=00"
65
+ end
66
+ private_class_method :build_path
67
+
68
+ # Parses the API response into fantasy profile stat objects
69
+ #
70
+ # @api private
71
+ # @return [Collection] collection of fantasy profile stats
72
+ def self.parse_response(response, result_set_name)
73
+ return Collection.new if response.nil? || response.empty?
74
+
75
+ data = JSON.parse(response)
76
+ result_set = find_result_set(data, result_set_name)
77
+ build_collection(result_set)
78
+ end
79
+ private_class_method :parse_response
80
+
81
+ # Finds a result set by name
82
+ #
83
+ # @api private
84
+ # @return [Hash, nil] the result set hash or nil if not found
85
+ def self.find_result_set(data, result_set_name)
86
+ result_sets = data["resultSets"]
87
+ return unless result_sets
88
+
89
+ result_sets.find { |rs| rs["name"].eql?(result_set_name) }
90
+ end
91
+ private_class_method :find_result_set
92
+
93
+ # Builds a collection from a result set
94
+ #
95
+ # @api private
96
+ # @return [Collection] the stats collection
97
+ def self.build_collection(result_set)
98
+ return Collection.new unless result_set
99
+
100
+ headers = result_set["headers"]
101
+ rows = result_set["rowSet"]
102
+ return Collection.new unless headers && rows
103
+
104
+ Collection.new(rows.map { |row| build_fantasy_profile_stat(headers.zip(row).to_h) })
105
+ end
106
+ private_class_method :build_collection
107
+
108
+ # Builds a fantasy profile stat from API data
109
+ #
110
+ # @api private
111
+ # @return [FantasyProfileStat] the fantasy profile stat object
112
+ def self.build_fantasy_profile_stat(data)
113
+ FantasyProfileStat.new(**identity_info(data), **fantasy_info(data), **stat_info(data))
114
+ end
115
+ private_class_method :build_fantasy_profile_stat
116
+
117
+ # Extracts identity information from data
118
+ #
119
+ # @api private
120
+ # @return [Hash] the identity information hash
121
+ def self.identity_info(data)
122
+ {player_id: data["PLAYER_ID"], player_name: data["PLAYER_NAME"],
123
+ team_id: data["TEAM_ID"], team_abbreviation: data["TEAM_ABBREVIATION"]}
124
+ end
125
+ private_class_method :identity_info
126
+
127
+ # Extracts fantasy information from data
128
+ #
129
+ # @api private
130
+ # @return [Hash] the fantasy information hash
131
+ def self.fantasy_info(data)
132
+ {fan_duel_pts: data["FAN_DUEL_PTS"], nba_fantasy_pts: data["NBA_FANTASY_PTS"]}
133
+ end
134
+ private_class_method :fantasy_info
135
+
136
+ # Extracts stat information from data
137
+ #
138
+ # @api private
139
+ # @return [Hash] the stat information hash
140
+ def self.stat_info(data)
141
+ {pts: data["PTS"], reb: data["REB"], ast: data["AST"],
142
+ fg3m: data["FG3M"], fg_pct: data["FG_PCT"], ft_pct: data["FT_PCT"],
143
+ stl: data["STL"], blk: data["BLK"], tov: data["TOV"]}
144
+ end
145
+ private_class_method :stat_info
146
+ end
147
+ end
@@ -0,0 +1,72 @@
1
+ require_relative "client"
2
+ require_relative "response_parser"
3
+ require_relative "game_log"
4
+ require_relative "utils"
5
+
6
+ module NBA
7
+ # Provides methods to retrieve player game logs
8
+ module PlayerGameLog
9
+ # Regular season type
10
+ # @return [String] the season type
11
+ REGULAR_SEASON = "Regular Season".freeze
12
+
13
+ # Playoffs season type
14
+ # @return [String] the season type
15
+ PLAYOFFS = "Playoffs".freeze
16
+
17
+ # Retrieves game logs for a player
18
+ #
19
+ # @api public
20
+ # @example
21
+ # logs = NBA::PlayerGameLog.find(player: 201939)
22
+ # logs.each { |log| puts "#{log.game_date}: #{log.pts} points" }
23
+ # @param player [Integer, Player] the player ID or Player object
24
+ # @param season [Integer] the season year (defaults to current season)
25
+ # @param season_type [String] the season type (Regular Season, Playoffs)
26
+ # @param client [Client] the API client to use
27
+ # @return [Collection] a collection of game logs
28
+ def self.find(player:, season: Utils.current_season, season_type: REGULAR_SEASON, client: CLIENT)
29
+ path = "playergamelog?PlayerID=#{Utils.extract_id(player)}&Season=#{Utils.format_season(season)}" \
30
+ "&SeasonType=#{season_type}"
31
+ ResponseParser.parse(client.get(path)) { |data| build_game_log(data) }
32
+ end
33
+
34
+ # Builds a game log from API data
35
+ # @api private
36
+ # @return [GameLog]
37
+ def self.build_game_log(data)
38
+ GameLog.new(**game_info(data), **shooting_stats(data), **counting_stats(data))
39
+ end
40
+ private_class_method :build_game_log
41
+
42
+ # Extracts game information from data
43
+ # @api private
44
+ # @return [Hash]
45
+ def self.game_info(data)
46
+ {season_id: data["SEASON_ID"], player_id: data["Player_ID"], game_id: data["Game_ID"],
47
+ game_date: data["GAME_DATE"], matchup: data["MATCHUP"], wl: data["WL"], min: data["MIN"]}
48
+ end
49
+ private_class_method :game_info
50
+
51
+ # Extracts shooting statistics from data
52
+ # @api private
53
+ # @return [Hash]
54
+ def self.shooting_stats(data)
55
+ {fgm: data["FGM"], fga: data["FGA"], fg_pct: data["FG_PCT"],
56
+ fg3m: data["FG3M"], fg3a: data["FG3A"], fg3_pct: data["FG3_PCT"],
57
+ ftm: data["FTM"], fta: data["FTA"], ft_pct: data["FT_PCT"]}
58
+ end
59
+ private_class_method :shooting_stats
60
+
61
+ # Extracts counting statistics from data
62
+ # @api private
63
+ # @return [Hash]
64
+ def self.counting_stats(data)
65
+ {oreb: data["OREB"], dreb: data["DREB"], reb: data["REB"],
66
+ ast: data["AST"], stl: data["STL"], blk: data["BLK"],
67
+ tov: data["TOV"], pf: data["PF"], pts: data["PTS"],
68
+ plus_minus: data["PLUS_MINUS"]}
69
+ end
70
+ private_class_method :counting_stats
71
+ end
72
+ end
@@ -0,0 +1,117 @@
1
+ require_relative "client"
2
+ require_relative "response_parser"
3
+ require_relative "game_log"
4
+ require_relative "utils"
5
+
6
+ module NBA
7
+ # Provides methods to retrieve player game logs in batch
8
+ #
9
+ # @api public
10
+ module PlayerGameLogs
11
+ # Regular season type
12
+ # @return [String] the season type
13
+ REGULAR_SEASON = "Regular Season".freeze
14
+
15
+ # Playoffs season type
16
+ # @return [String] the season type
17
+ PLAYOFFS = "Playoffs".freeze
18
+
19
+ # Per game mode
20
+ # @return [String] the per mode
21
+ PER_GAME = "PerGame".freeze
22
+
23
+ # Totals mode
24
+ # @return [String] the per mode
25
+ TOTALS = "Totals".freeze
26
+
27
+ # Result set name
28
+ # @return [String] the result set name
29
+ RESULT_SET_NAME = "PlayerGameLogs".freeze
30
+
31
+ # Retrieves game logs for all players matching the criteria
32
+ #
33
+ # @api public
34
+ # @example
35
+ # logs = NBA::PlayerGameLogs.all(season: 2024)
36
+ # logs.each { |log| puts "#{log.game_date}: #{log.player_name} - #{log.pts} pts" }
37
+ # @param season [Integer] the season year (defaults to current season)
38
+ # @param season_type [String] the season type (Regular Season, Playoffs)
39
+ # @param player [Integer, Player, nil] filter by player ID or Player object
40
+ # @param team [Integer, Team, nil] filter by team ID or Team object
41
+ # @param per_mode [String] the per mode (PerGame, Totals)
42
+ # @param client [Client] the API client to use
43
+ # @return [Collection] a collection of game logs
44
+ def self.all(season: Utils.current_season, season_type: REGULAR_SEASON, player: nil, team: nil,
45
+ per_mode: PER_GAME, client: CLIENT)
46
+ path = build_path(season, season_type, player, team, per_mode)
47
+ ResponseParser.parse(client.get(path), result_set: RESULT_SET_NAME) { |data| build_game_log(data) }
48
+ end
49
+
50
+ # Builds the API path
51
+ #
52
+ # @api private
53
+ # @return [String] the API path
54
+ def self.build_path(season, season_type, player, team, per_mode)
55
+ path = "playergamelogs?LeagueID=00&Season=#{Utils.format_season(season)}" \
56
+ "&SeasonType=#{season_type}&PerModeSimple=#{per_mode}"
57
+ path += "&PlayerID=#{Utils.extract_id(player)}" if player
58
+ path += "&TeamID=#{Utils.extract_id(team)}" if team
59
+ path
60
+ end
61
+ private_class_method :build_path
62
+
63
+ # Builds a game log from API data
64
+ #
65
+ # @api private
66
+ # @return [GameLog]
67
+ def self.build_game_log(data)
68
+ GameLog.new(**game_info(data), **player_info(data), **shooting_stats(data), **counting_stats(data))
69
+ end
70
+ private_class_method :build_game_log
71
+
72
+ # Extracts game information from data
73
+ #
74
+ # @api private
75
+ # @return [Hash]
76
+ def self.game_info(data)
77
+ {season_id: data["SEASON_YEAR"], game_id: data["GAME_ID"],
78
+ game_date: data["GAME_DATE"], matchup: data["MATCHUP"],
79
+ wl: data["WL"], min: data["MIN"]}
80
+ end
81
+ private_class_method :game_info
82
+
83
+ # Extracts player information from data
84
+ #
85
+ # @api private
86
+ # @return [Hash]
87
+ def self.player_info(data)
88
+ {player_id: data["PLAYER_ID"], player_name: data["PLAYER_NAME"],
89
+ team_id: data["TEAM_ID"], team_abbreviation: data["TEAM_ABBREVIATION"],
90
+ team_name: data["TEAM_NAME"]}
91
+ end
92
+ private_class_method :player_info
93
+
94
+ # Extracts shooting statistics from data
95
+ #
96
+ # @api private
97
+ # @return [Hash]
98
+ def self.shooting_stats(data)
99
+ {fgm: data["FGM"], fga: data["FGA"], fg_pct: data["FG_PCT"],
100
+ fg3m: data["FG3M"], fg3a: data["FG3A"], fg3_pct: data["FG3_PCT"],
101
+ ftm: data["FTM"], fta: data["FTA"], ft_pct: data["FT_PCT"]}
102
+ end
103
+ private_class_method :shooting_stats
104
+
105
+ # Extracts counting statistics from data
106
+ #
107
+ # @api private
108
+ # @return [Hash]
109
+ def self.counting_stats(data)
110
+ {oreb: data["OREB"], dreb: data["DREB"], reb: data["REB"],
111
+ ast: data["AST"], stl: data["STL"], blk: data["BLK"],
112
+ tov: data["TOV"], pf: data["PF"], pts: data["PTS"],
113
+ plus_minus: data["PLUS_MINUS"]}
114
+ end
115
+ private_class_method :counting_stats
116
+ end
117
+ end
@@ -0,0 +1,108 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "response_parser"
4
+ require_relative "game_streak"
5
+ require_relative "utils"
6
+
7
+ module NBA
8
+ # Provides methods to find player game streaks
9
+ #
10
+ # @api public
11
+ module PlayerGameStreakFinder
12
+ # Result set name for streak finder results
13
+ # @return [String] the result set name
14
+ RESULT_SET_NAME = "PlayerGameStreakFinderResults".freeze
15
+
16
+ # Stat filter parameter mappings
17
+ # @return [Hash] mapping of Ruby method parameters to API parameters
18
+ STAT_FILTERS = {gt_pts: :GtPTS, gt_reb: :GtREB, gt_ast: :GtAST, gt_stl: :GtSTL, gt_blk: :GtBLK, gt_fg3m: :GtFG3M}.freeze
19
+
20
+ # Finds player game streaks matching the specified criteria
21
+ #
22
+ # @api public
23
+ # @example Find active 10+ point streaks
24
+ # NBA::PlayerGameStreakFinder.find(gt_pts: 10, active_streaks_only: true)
25
+ # @param season [String, nil] the season to search (e.g., "2024-25")
26
+ # @param player [Integer, Player, nil] filter by player ID or Player object
27
+ # @param team [Integer, Team, nil] filter by team ID or Team object
28
+ # @param active_streaks_only [Boolean, nil] only return active streaks
29
+ # @param gt_pts [Integer, nil] minimum points per game
30
+ # @param gt_reb [Integer, nil] minimum rebounds per game
31
+ # @param gt_ast [Integer, nil] minimum assists per game
32
+ # @param gt_stl [Integer, nil] minimum steals per game
33
+ # @param gt_blk [Integer, nil] minimum blocks per game
34
+ # @param gt_fg3m [Integer, nil] minimum 3-pointers made per game
35
+ # @param client [Client] the API client to use
36
+ # @return [Collection] collection of GameStreak objects
37
+ def self.find(season: nil, player: nil, team: nil, active_streaks_only: nil, gt_pts: nil,
38
+ gt_reb: nil, gt_ast: nil, gt_stl: nil, gt_blk: nil, gt_fg3m: nil, client: CLIENT)
39
+ filters = {gt_pts: gt_pts, gt_reb: gt_reb, gt_ast: gt_ast, gt_stl: gt_stl, gt_blk: gt_blk, gt_fg3m: gt_fg3m}
40
+ path = build_path(season, player, team, active_streaks_only, filters)
41
+ ResponseParser.parse(client.get(path), result_set: RESULT_SET_NAME) { |data| build_streak(data) }
42
+ end
43
+
44
+ # Builds the API path with query parameters
45
+ #
46
+ # @api private
47
+ # @return [String] the API endpoint path
48
+ def self.build_path(season, player, team, active_only, filters)
49
+ params = base_params(season, player, team, active_only)
50
+ add_stat_filters(params, filters)
51
+ "playergamestreakfinder?#{URI.encode_www_form(params)}"
52
+ end
53
+ private_class_method :build_path
54
+
55
+ # Returns base parameters for the endpoint
56
+ #
57
+ # @api private
58
+ # @return [Hash] the base parameters hash
59
+ def self.base_params(season, player, team, active_only)
60
+ params = {LeagueID: "00", MinGames: 1}
61
+ params[:SeasonNullable] = season if season
62
+ params[:PlayerIDNullable] = Utils.extract_id(player) if player
63
+ params[:TeamIDNullable] = Utils.extract_id(team) if team
64
+ params[:ActiveStreaksOnly] = "Y" if active_only
65
+ params
66
+ end
67
+ private_class_method :base_params
68
+
69
+ # Adds stat filter parameters
70
+ #
71
+ # @api private
72
+ # @return [void]
73
+ def self.add_stat_filters(params, filters)
74
+ STAT_FILTERS.each { |key, param| params[param] = filters.fetch(key) if filters.fetch(key) }
75
+ end
76
+ private_class_method :add_stat_filters
77
+
78
+ # Builds a GameStreak from API data
79
+ #
80
+ # @api private
81
+ # @return [GameStreak] the game streak object
82
+ def self.build_streak(data)
83
+ GameStreak.new(**player_info(data), **streak_info(data))
84
+ end
85
+ private_class_method :build_streak
86
+
87
+ # Extracts player information from data
88
+ #
89
+ # @api private
90
+ # @return [Hash] the player information hash
91
+ def self.player_info(data)
92
+ {player_name: data["PLAYER_NAME_LAST_FIRST"], player_id: data["PLAYER_ID"]}
93
+ end
94
+ private_class_method :player_info
95
+
96
+ # Extracts streak information from data
97
+ #
98
+ # @api private
99
+ # @return [Hash] the streak information hash
100
+ def self.streak_info(data)
101
+ {game_streak: data["GAMESTREAK"], start_date: data["STARTDATE"],
102
+ end_date: data["ENDDATE"], active_streak: data["ACTIVESTREAK"],
103
+ num_seasons: data["NUMSEASONS"], last_season: data["LASTSEASON"],
104
+ first_season: data["FIRSTSEASON"]}
105
+ end
106
+ private_class_method :streak_info
107
+ end
108
+ end
@@ -0,0 +1,135 @@
1
+ require_relative "client"
2
+ require_relative "response_parser"
3
+ require_relative "utils"
4
+
5
+ require_relative "player_index_entry"
6
+
7
+ module NBA
8
+ # Provides methods to search and retrieve the player index
9
+ #
10
+ # @api public
11
+ module PlayerIndex
12
+ # Result set name for player index
13
+ # @return [String] the result set name
14
+ RESULT_SET_NAME = "PlayerIndex".freeze
15
+
16
+ # Historical flag: include historical players
17
+ # @return [Integer] the flag value
18
+ HISTORICAL = 1
19
+
20
+ # Historical flag: current players only
21
+ # @return [Integer] the flag value
22
+ CURRENT = 0
23
+
24
+ # Retrieves the player index with optional filters
25
+ #
26
+ # @api public
27
+ # @example
28
+ # # Get all current players
29
+ # players = NBA::PlayerIndex.all
30
+ # players.size #=> 450
31
+ #
32
+ # @example
33
+ # # Get players from a specific college
34
+ # duke_players = NBA::PlayerIndex.all(college: "Duke")
35
+ #
36
+ # @example
37
+ # # Get players from a specific country
38
+ # canadian = NBA::PlayerIndex.all(country: "Canada")
39
+ #
40
+ # @param season [Integer] the season year
41
+ # @param historical [Integer] whether to include historical players (0 or 1)
42
+ # @param active [String, nil] filter by active status ("1" for active)
43
+ # @param all_star [String, nil] filter by all-star status
44
+ # @param college [String, nil] filter by college
45
+ # @param country [String, nil] filter by country
46
+ # @param draft_pick [String, nil] filter by draft pick
47
+ # @param draft_year [String, nil] filter by draft year
48
+ # @param height [String, nil] filter by height
49
+ # @param team [Integer, Team, nil] filter by team
50
+ # @param weight [String, nil] filter by weight
51
+ # @param client [Client] the API client to use
52
+ # @return [Collection] a collection of player index entries
53
+ def self.all(season: Utils.current_season, historical: CURRENT, active: nil, all_star: nil,
54
+ college: nil, country: nil, draft_pick: nil, draft_year: nil, height: nil,
55
+ team: nil, weight: nil, client: CLIENT)
56
+ params = {season: season, historical: historical, active: active, all_star: all_star,
57
+ college: college, country: country, draft_pick: draft_pick, draft_year: draft_year,
58
+ height: height, team: team, weight: weight}
59
+ path = build_path(params)
60
+ ResponseParser.parse(client.get(path), result_set: RESULT_SET_NAME) do |data|
61
+ build_entry(data)
62
+ end
63
+ end
64
+
65
+ # Builds the API request path
66
+ # @api private
67
+ # @return [String] the request path
68
+ def self.build_path(params)
69
+ season_str = Utils.format_season(params.fetch(:season))
70
+ team_id = Utils.extract_id(params.fetch(:team))
71
+ "playerindex?LeagueID=00&Season=#{season_str}&Historical=#{params[:historical]}" \
72
+ "&Active=#{params[:active]}&AllStar=#{params[:all_star]}&College=#{params[:college]}" \
73
+ "&Country=#{params[:country]}&DraftPick=#{params[:draft_pick]}&DraftYear=#{params[:draft_year]}" \
74
+ "&Height=#{params[:height]}&TeamID=#{team_id}&Weight=#{params[:weight]}"
75
+ end
76
+ private_class_method :build_path
77
+
78
+ # Builds a player index entry from API data
79
+ # @api private
80
+ # @return [PlayerIndexEntry]
81
+ def self.build_entry(data)
82
+ PlayerIndexEntry.new(**identity_info(data), **team_info(data), **physical_info(data),
83
+ **draft_info(data), **stats_info(data))
84
+ end
85
+ private_class_method :build_entry
86
+
87
+ # Extracts identity information from data
88
+ # @api private
89
+ # @return [Hash]
90
+ def self.identity_info(data)
91
+ {id: data["PERSON_ID"], last_name: data["PLAYER_LAST_NAME"],
92
+ first_name: data["PLAYER_FIRST_NAME"], slug: data["PLAYER_SLUG"]}
93
+ end
94
+ private_class_method :identity_info
95
+
96
+ # Extracts team information from data
97
+ # @api private
98
+ # @return [Hash]
99
+ def self.team_info(data)
100
+ {team_id: data["TEAM_ID"], team_slug: data["TEAM_SLUG"],
101
+ team_city: data["TEAM_CITY"], team_name: data["TEAM_NAME"],
102
+ team_abbreviation: data["TEAM_ABBREVIATION"]}
103
+ end
104
+ private_class_method :team_info
105
+
106
+ # Extracts physical information from data
107
+ # @api private
108
+ # @return [Hash]
109
+ def self.physical_info(data)
110
+ {jersey_number: data["JERSEY_NUMBER"], position: data["POSITION"],
111
+ height: data["HEIGHT"], weight: data["WEIGHT"],
112
+ college: data["COLLEGE"], country: data["COUNTRY"]}
113
+ end
114
+ private_class_method :physical_info
115
+
116
+ # Extracts draft information from data
117
+ # @api private
118
+ # @return [Hash]
119
+ def self.draft_info(data)
120
+ {draft_year: data["DRAFT_YEAR"], draft_round: data["DRAFT_ROUND"],
121
+ draft_number: data["DRAFT_NUMBER"], roster_status: data["ROSTER_STATUS"]}
122
+ end
123
+ private_class_method :draft_info
124
+
125
+ # Extracts stats information from data
126
+ # @api private
127
+ # @return [Hash]
128
+ def self.stats_info(data)
129
+ {pts: data["PTS"], reb: data["REB"], ast: data["AST"],
130
+ stats_timeframe: data["STATS_TIMEFRAME"], from_year: data["FROM_YEAR"],
131
+ to_year: data["TO_YEAR"], is_defunct: data["IS_DEFUNCT"]}
132
+ end
133
+ private_class_method :stats_info
134
+ end
135
+ end