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,126 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "draft_board_pick"
5
+
6
+ module NBA
7
+ # Provides methods to retrieve draft board data
8
+ module DraftBoard
9
+ # Result set name
10
+ # @return [String] the result set name
11
+ RESULTS = "DraftBoard".freeze
12
+
13
+ # Retrieves draft board picks for a season
14
+ #
15
+ # @api public
16
+ # @example
17
+ # picks = NBA::DraftBoard.all(season: 2023)
18
+ # picks.each { |p| puts "#{p.player_name}: Pick #{p.overall_pick}" }
19
+ # @param season [Integer] the draft season year
20
+ # @param league [String, League] the league ID or League object (default NBA)
21
+ # @param client [Client] the API client to use
22
+ # @return [Collection] a collection of draft board picks
23
+ def self.all(season:, league: League::NBA, client: CLIENT)
24
+ league_id = Utils.extract_league_id(league)
25
+ path = build_path(season, league_id)
26
+ response = client.get(path)
27
+ parse_response(response)
28
+ end
29
+
30
+ # Builds the API request path
31
+ # @api private
32
+ # @return [String] the request path
33
+ def self.build_path(season, league_id)
34
+ "draftboard?LeagueID=#{league_id}&SeasonYear=#{season}"
35
+ end
36
+ private_class_method :build_path
37
+
38
+ # Parses the API response into pick objects
39
+ # @api private
40
+ # @return [Collection] collection of picks
41
+ def self.parse_response(response)
42
+ return Collection.new unless response
43
+
44
+ data = JSON.parse(response)
45
+ result_set = find_result_set(data)
46
+ return Collection.new unless result_set
47
+
48
+ headers = result_set["headers"]
49
+ rows = result_set["rowSet"]
50
+ return Collection.new unless headers && rows
51
+
52
+ picks = rows.map { |row| build_pick(headers, row) }
53
+ Collection.new(picks)
54
+ end
55
+ private_class_method :parse_response
56
+
57
+ # Finds the result set in the response
58
+ # @api private
59
+ # @return [Hash, nil] the result set hash
60
+ def self.find_result_set(data)
61
+ result_sets = data["resultSets"]
62
+ return unless result_sets
63
+
64
+ result_sets.find { |rs| rs["name"].eql?(RESULTS) }
65
+ end
66
+ private_class_method :find_result_set
67
+
68
+ # Builds a DraftBoardPick object from raw data
69
+ # @api private
70
+ # @return [DraftBoardPick] the pick object
71
+ def self.build_pick(headers, row)
72
+ data = headers.zip(row).to_h
73
+ DraftBoardPick.new(**PickAttributes.extract(data))
74
+ end
75
+ private_class_method :build_pick
76
+
77
+ # Extracts pick attributes from data
78
+ # @api private
79
+ module PickAttributes
80
+ # Extracts all pick attributes from data
81
+ # @api private
82
+ # @param data [Hash] the row data
83
+ # @return [Hash] extracted attributes
84
+ def self.extract(data)
85
+ player(data).merge(draft_info(data)).merge(team(data)).merge(physical(data))
86
+ end
87
+
88
+ # Extracts player attributes from data
89
+ # @api private
90
+ # @param data [Hash] the row data
91
+ # @return [Hash] player attributes
92
+ def self.player(data)
93
+ {person_id: data["PERSON_ID"], player_name: data["PLAYER_NAME"]}
94
+ end
95
+
96
+ # Extracts draft info attributes from data
97
+ # @api private
98
+ # @param data [Hash] the row data
99
+ # @return [Hash] draft info attributes
100
+ def self.draft_info(data)
101
+ {season: data["SEASON"], round_number: data["ROUND_NUMBER"],
102
+ round_pick: data["ROUND_PICK"], overall_pick: data["OVERALL_PICK"]}
103
+ end
104
+
105
+ # Extracts team attributes from data
106
+ # @api private
107
+ # @param data [Hash] the row data
108
+ # @return [Hash] team attributes
109
+ def self.team(data)
110
+ {team_id: data["TEAM_ID"], team_city: data["TEAM_CITY"],
111
+ team_name: data["TEAM_NAME"], team_abbreviation: data["TEAM_ABBREVIATION"],
112
+ organization: data["ORGANIZATION"], organization_type: data["ORGANIZATION_TYPE"]}
113
+ end
114
+
115
+ # Extracts physical attributes from data
116
+ # @api private
117
+ # @param data [Hash] the row data
118
+ # @return [Hash] physical attributes
119
+ def self.physical(data)
120
+ {height: data["HEIGHT"], weight: data["WEIGHT"],
121
+ position: data["POSITION"], jersey_number: data["JERSEY_NUMBER"],
122
+ birthdate: data["BIRTHDATE"], age: data["AGE"]}
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,173 @@
1
+ require "equalizer"
2
+ require "shale"
3
+
4
+ module NBA
5
+ # Represents a draft board pick
6
+ class DraftBoardPick < Shale::Mapper
7
+ include Equalizer.new(:person_id)
8
+
9
+ # @!attribute [rw] person_id
10
+ # Returns the person ID
11
+ # @api public
12
+ # @example
13
+ # pick.person_id #=> 1630162
14
+ # @return [Integer] the person ID
15
+ attribute :person_id, Shale::Type::Integer
16
+
17
+ # @!attribute [rw] player_name
18
+ # Returns the player name
19
+ # @api public
20
+ # @example
21
+ # pick.player_name #=> "Victor Wembanyama"
22
+ # @return [String] the player name
23
+ attribute :player_name, Shale::Type::String
24
+
25
+ # @!attribute [rw] season
26
+ # Returns the draft season
27
+ # @api public
28
+ # @example
29
+ # pick.season #=> "2023"
30
+ # @return [String] the season
31
+ attribute :season, Shale::Type::String
32
+
33
+ # @!attribute [rw] round_number
34
+ # Returns the draft round number
35
+ # @api public
36
+ # @example
37
+ # pick.round_number #=> 1
38
+ # @return [Integer] the round number
39
+ attribute :round_number, Shale::Type::Integer
40
+
41
+ # @!attribute [rw] round_pick
42
+ # Returns the pick number in the round
43
+ # @api public
44
+ # @example
45
+ # pick.round_pick #=> 1
46
+ # @return [Integer] the round pick
47
+ attribute :round_pick, Shale::Type::Integer
48
+
49
+ # @!attribute [rw] overall_pick
50
+ # Returns the overall pick number
51
+ # @api public
52
+ # @example
53
+ # pick.overall_pick #=> 1
54
+ # @return [Integer] the overall pick
55
+ attribute :overall_pick, Shale::Type::Integer
56
+
57
+ # @!attribute [rw] team_id
58
+ # Returns the team ID
59
+ # @api public
60
+ # @example
61
+ # pick.team_id #=> 1610612759
62
+ # @return [Integer] the team ID
63
+ attribute :team_id, Shale::Type::Integer
64
+
65
+ # @!attribute [rw] team_city
66
+ # Returns the team city
67
+ # @api public
68
+ # @example
69
+ # pick.team_city #=> "San Antonio"
70
+ # @return [String] the team city
71
+ attribute :team_city, Shale::Type::String
72
+
73
+ # @!attribute [rw] team_name
74
+ # Returns the team name
75
+ # @api public
76
+ # @example
77
+ # pick.team_name #=> "Spurs"
78
+ # @return [String] the team name
79
+ attribute :team_name, Shale::Type::String
80
+
81
+ # @!attribute [rw] team_abbreviation
82
+ # Returns the team abbreviation
83
+ # @api public
84
+ # @example
85
+ # pick.team_abbreviation #=> "SAS"
86
+ # @return [String] the team abbreviation
87
+ attribute :team_abbreviation, Shale::Type::String
88
+
89
+ # @!attribute [rw] organization
90
+ # Returns the organization name
91
+ # @api public
92
+ # @example
93
+ # pick.organization #=> "Metropolitans 92"
94
+ # @return [String] the organization
95
+ attribute :organization, Shale::Type::String
96
+
97
+ # @!attribute [rw] organization_type
98
+ # Returns the organization type
99
+ # @api public
100
+ # @example
101
+ # pick.organization_type #=> "International"
102
+ # @return [String] the organization type
103
+ attribute :organization_type, Shale::Type::String
104
+
105
+ # @!attribute [rw] height
106
+ # Returns the player height
107
+ # @api public
108
+ # @example
109
+ # pick.height #=> "7-4"
110
+ # @return [String] the height
111
+ attribute :height, Shale::Type::String
112
+
113
+ # @!attribute [rw] weight
114
+ # Returns the player weight
115
+ # @api public
116
+ # @example
117
+ # pick.weight #=> "210"
118
+ # @return [String] the weight
119
+ attribute :weight, Shale::Type::String
120
+
121
+ # @!attribute [rw] position
122
+ # Returns the player position
123
+ # @api public
124
+ # @example
125
+ # pick.position #=> "C"
126
+ # @return [String] the position
127
+ attribute :position, Shale::Type::String
128
+
129
+ # @!attribute [rw] jersey_number
130
+ # Returns the jersey number
131
+ # @api public
132
+ # @example
133
+ # pick.jersey_number #=> "1"
134
+ # @return [String] the jersey number
135
+ attribute :jersey_number, Shale::Type::String
136
+
137
+ # @!attribute [rw] birthdate
138
+ # Returns the birthdate
139
+ # @api public
140
+ # @example
141
+ # pick.birthdate #=> "2004-01-04"
142
+ # @return [String] the birthdate
143
+ attribute :birthdate, Shale::Type::String
144
+
145
+ # @!attribute [rw] age
146
+ # Returns the player age
147
+ # @api public
148
+ # @example
149
+ # pick.age #=> 19.0
150
+ # @return [Float] the age
151
+ attribute :age, Shale::Type::Float
152
+
153
+ # Returns the player object
154
+ #
155
+ # @api public
156
+ # @example
157
+ # pick.player #=> #<NBA::Player>
158
+ # @return [Player, nil] the player object
159
+ def player
160
+ Players.find(person_id)
161
+ end
162
+
163
+ # Returns the team object
164
+ #
165
+ # @api public
166
+ # @example
167
+ # pick.team #=> #<NBA::Team>
168
+ # @return [Team, nil] the team object
169
+ def team
170
+ Teams.find(team_id)
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,163 @@
1
+ require "equalizer"
2
+ require "shale"
3
+
4
+ module NBA
5
+ # Represents a draft combine anthropometric measurement
6
+ class DraftCombineAnthroMeasurement < Shale::Mapper
7
+ include Equalizer.new(:player_id)
8
+
9
+ # @!attribute [rw] temp_player_id
10
+ # Returns the temporary player ID
11
+ # @api public
12
+ # @example
13
+ # measurement.temp_player_id #=> 123456
14
+ # @return [Integer] the temporary player ID
15
+ attribute :temp_player_id, Shale::Type::Integer
16
+
17
+ # @!attribute [rw] player_id
18
+ # Returns the player ID
19
+ # @api public
20
+ # @example
21
+ # measurement.player_id #=> 1630162
22
+ # @return [Integer] the player ID
23
+ attribute :player_id, Shale::Type::Integer
24
+
25
+ # @!attribute [rw] first_name
26
+ # Returns the player's first name
27
+ # @api public
28
+ # @example
29
+ # measurement.first_name #=> "Victor"
30
+ # @return [String] the first name
31
+ attribute :first_name, Shale::Type::String
32
+
33
+ # @!attribute [rw] last_name
34
+ # Returns the player's last name
35
+ # @api public
36
+ # @example
37
+ # measurement.last_name #=> "Wembanyama"
38
+ # @return [String] the last name
39
+ attribute :last_name, Shale::Type::String
40
+
41
+ # @!attribute [rw] player_name
42
+ # Returns the player name
43
+ # @api public
44
+ # @example
45
+ # measurement.player_name #=> "Victor Wembanyama"
46
+ # @return [String] the player name
47
+ attribute :player_name, Shale::Type::String
48
+
49
+ # @!attribute [rw] position
50
+ # Returns the player's position
51
+ # @api public
52
+ # @example
53
+ # measurement.position #=> "C"
54
+ # @return [String] the position
55
+ attribute :position, Shale::Type::String
56
+
57
+ # @!attribute [rw] height_wo_shoes
58
+ # Returns the height without shoes in inches
59
+ # @api public
60
+ # @example
61
+ # measurement.height_wo_shoes #=> 85.5
62
+ # @return [Float] height without shoes
63
+ attribute :height_wo_shoes, Shale::Type::Float
64
+
65
+ # @!attribute [rw] height_wo_shoes_ft_in
66
+ # Returns the height without shoes in feet and inches
67
+ # @api public
68
+ # @example
69
+ # measurement.height_wo_shoes_ft_in #=> "7' 1.5\""
70
+ # @return [String] height without shoes in feet and inches
71
+ attribute :height_wo_shoes_ft_in, Shale::Type::String
72
+
73
+ # @!attribute [rw] height_w_shoes
74
+ # Returns the height with shoes in inches
75
+ # @api public
76
+ # @example
77
+ # measurement.height_w_shoes #=> 86.5
78
+ # @return [Float] height with shoes
79
+ attribute :height_w_shoes, Shale::Type::Float
80
+
81
+ # @!attribute [rw] height_w_shoes_ft_in
82
+ # Returns the height with shoes in feet and inches
83
+ # @api public
84
+ # @example
85
+ # measurement.height_w_shoes_ft_in #=> "7' 2.5\""
86
+ # @return [String] height with shoes in feet and inches
87
+ attribute :height_w_shoes_ft_in, Shale::Type::String
88
+
89
+ # @!attribute [rw] weight
90
+ # Returns the weight in pounds
91
+ # @api public
92
+ # @example
93
+ # measurement.weight #=> 209.0
94
+ # @return [Float] weight in pounds
95
+ attribute :weight, Shale::Type::Float
96
+
97
+ # @!attribute [rw] wingspan
98
+ # Returns the wingspan in inches
99
+ # @api public
100
+ # @example
101
+ # measurement.wingspan #=> 96.0
102
+ # @return [Float] wingspan in inches
103
+ attribute :wingspan, Shale::Type::Float
104
+
105
+ # @!attribute [rw] wingspan_ft_in
106
+ # Returns the wingspan in feet and inches
107
+ # @api public
108
+ # @example
109
+ # measurement.wingspan_ft_in #=> "8' 0\""
110
+ # @return [String] wingspan in feet and inches
111
+ attribute :wingspan_ft_in, Shale::Type::String
112
+
113
+ # @!attribute [rw] standing_reach
114
+ # Returns the standing reach in inches
115
+ # @api public
116
+ # @example
117
+ # measurement.standing_reach #=> 114.5
118
+ # @return [Float] standing reach in inches
119
+ attribute :standing_reach, Shale::Type::Float
120
+
121
+ # @!attribute [rw] standing_reach_ft_in
122
+ # Returns the standing reach in feet and inches
123
+ # @api public
124
+ # @example
125
+ # measurement.standing_reach_ft_in #=> "9' 6.5\""
126
+ # @return [String] standing reach in feet and inches
127
+ attribute :standing_reach_ft_in, Shale::Type::String
128
+
129
+ # @!attribute [rw] body_fat_pct
130
+ # Returns the body fat percentage
131
+ # @api public
132
+ # @example
133
+ # measurement.body_fat_pct #=> 4.8
134
+ # @return [Float] body fat percentage
135
+ attribute :body_fat_pct, Shale::Type::Float
136
+
137
+ # @!attribute [rw] hand_length
138
+ # Returns the hand length in inches
139
+ # @api public
140
+ # @example
141
+ # measurement.hand_length #=> 10.25
142
+ # @return [Float] hand length in inches
143
+ attribute :hand_length, Shale::Type::Float
144
+
145
+ # @!attribute [rw] hand_width
146
+ # Returns the hand width in inches
147
+ # @api public
148
+ # @example
149
+ # measurement.hand_width #=> 12.0
150
+ # @return [Float] hand width in inches
151
+ attribute :hand_width, Shale::Type::Float
152
+
153
+ # Returns the player object
154
+ #
155
+ # @api public
156
+ # @example
157
+ # measurement.player #=> #<NBA::Player>
158
+ # @return [Player, nil] the player object
159
+ def player
160
+ Players.find(player_id)
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,115 @@
1
+ require "equalizer"
2
+ require "shale"
3
+
4
+ module NBA
5
+ # Represents a draft combine drill result
6
+ class DraftCombineDrillResult < Shale::Mapper
7
+ include Equalizer.new(:player_id)
8
+
9
+ # @!attribute [rw] temp_player_id
10
+ # Returns the temporary player ID
11
+ # @api public
12
+ # @example
13
+ # result.temp_player_id #=> 1630162
14
+ # @return [Integer] the temporary player ID
15
+ attribute :temp_player_id, Shale::Type::Integer
16
+
17
+ # @!attribute [rw] player_id
18
+ # Returns the player ID
19
+ # @api public
20
+ # @example
21
+ # result.player_id #=> 1630162
22
+ # @return [Integer] the player ID
23
+ attribute :player_id, Shale::Type::Integer
24
+
25
+ # @!attribute [rw] first_name
26
+ # Returns the player's first name
27
+ # @api public
28
+ # @example
29
+ # result.first_name #=> "Victor"
30
+ # @return [String] the first name
31
+ attribute :first_name, Shale::Type::String
32
+
33
+ # @!attribute [rw] last_name
34
+ # Returns the player's last name
35
+ # @api public
36
+ # @example
37
+ # result.last_name #=> "Wembanyama"
38
+ # @return [String] the last name
39
+ attribute :last_name, Shale::Type::String
40
+
41
+ # @!attribute [rw] player_name
42
+ # Returns the player name
43
+ # @api public
44
+ # @example
45
+ # result.player_name #=> "Victor Wembanyama"
46
+ # @return [String] the player name
47
+ attribute :player_name, Shale::Type::String
48
+
49
+ # @!attribute [rw] position
50
+ # Returns the player's position
51
+ # @api public
52
+ # @example
53
+ # result.position #=> "C"
54
+ # @return [String] the position
55
+ attribute :position, Shale::Type::String
56
+
57
+ # @!attribute [rw] standing_vertical_leap
58
+ # Returns the standing vertical leap measurement in inches
59
+ # @api public
60
+ # @example
61
+ # result.standing_vertical_leap #=> 30.5
62
+ # @return [Float] standing vertical leap in inches
63
+ attribute :standing_vertical_leap, Shale::Type::Float
64
+
65
+ # @!attribute [rw] max_vertical_leap
66
+ # Returns the maximum vertical leap measurement in inches
67
+ # @api public
68
+ # @example
69
+ # result.max_vertical_leap #=> 37.0
70
+ # @return [Float] maximum vertical leap in inches
71
+ attribute :max_vertical_leap, Shale::Type::Float
72
+
73
+ # @!attribute [rw] lane_agility_time
74
+ # Returns the lane agility drill time in seconds
75
+ # @api public
76
+ # @example
77
+ # result.lane_agility_time #=> 10.5
78
+ # @return [Float] lane agility time in seconds
79
+ attribute :lane_agility_time, Shale::Type::Float
80
+
81
+ # @!attribute [rw] modified_lane_agility_time
82
+ # Returns the modified lane agility drill time in seconds
83
+ # @api public
84
+ # @example
85
+ # result.modified_lane_agility_time #=> 10.2
86
+ # @return [Float] modified lane agility time in seconds
87
+ attribute :modified_lane_agility_time, Shale::Type::Float
88
+
89
+ # @!attribute [rw] three_quarter_sprint
90
+ # Returns the three-quarter court sprint time in seconds
91
+ # @api public
92
+ # @example
93
+ # result.three_quarter_sprint #=> 3.2
94
+ # @return [Float] three-quarter sprint time in seconds
95
+ attribute :three_quarter_sprint, Shale::Type::Float
96
+
97
+ # @!attribute [rw] bench_press
98
+ # Returns the number of bench press repetitions
99
+ # @api public
100
+ # @example
101
+ # result.bench_press #=> 12
102
+ # @return [Integer] bench press repetitions
103
+ attribute :bench_press, Shale::Type::Integer
104
+
105
+ # Returns the player object
106
+ #
107
+ # @api public
108
+ # @example
109
+ # result.player #=> #<NBA::Player>
110
+ # @return [Player, nil] the player object
111
+ def player
112
+ Players.find(player_id)
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,112 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "draft_combine_drill_result"
5
+
6
+ module NBA
7
+ # Provides methods to retrieve draft combine drill results data
8
+ module DraftCombineDrillResults
9
+ # Result set name
10
+ # @return [String] the result set name
11
+ RESULTS = "Results".freeze
12
+
13
+ # Retrieves draft combine drill results for a season
14
+ #
15
+ # @api public
16
+ # @example
17
+ # results = NBA::DraftCombineDrillResults.all(season: 2019)
18
+ # results.each { |r| puts "#{r.player_name}: #{r.max_vertical_leap}" }
19
+ # @param season [Integer] the draft combine season year
20
+ # @param league [String, League] the league ID or League object (default NBA)
21
+ # @param client [Client] the API client to use
22
+ # @return [Collection] a collection of draft combine drill results
23
+ def self.all(season:, league: League::NBA, client: CLIENT)
24
+ league_id = Utils.extract_league_id(league)
25
+ path = build_path(season, league_id)
26
+ response = client.get(path)
27
+ parse_response(response)
28
+ end
29
+
30
+ # Builds the API request path
31
+ # @api private
32
+ # @return [String] the request path
33
+ def self.build_path(season, league_id)
34
+ "draftcombinedrillresults?LeagueID=#{league_id}&SeasonYear=#{season}"
35
+ end
36
+ private_class_method :build_path
37
+
38
+ # Parses the API response into result objects
39
+ # @api private
40
+ # @return [Collection] collection of results
41
+ def self.parse_response(response)
42
+ return Collection.new unless response
43
+
44
+ data = JSON.parse(response)
45
+ result_set = find_result_set(data)
46
+ return Collection.new unless result_set
47
+
48
+ headers = result_set["headers"]
49
+ rows = result_set["rowSet"]
50
+ return Collection.new unless headers && rows
51
+
52
+ results = rows.map { |row| build_result(headers, row) }
53
+ Collection.new(results)
54
+ end
55
+ private_class_method :parse_response
56
+
57
+ # Finds the result set in the response
58
+ # @api private
59
+ # @return [Hash, nil] the result set hash
60
+ def self.find_result_set(data)
61
+ result_sets = data["resultSets"]
62
+ return unless result_sets
63
+
64
+ result_sets.find { |rs| rs["name"].eql?(RESULTS) }
65
+ end
66
+ private_class_method :find_result_set
67
+
68
+ # Builds a DraftCombineDrillResult object from raw data
69
+ # @api private
70
+ # @return [DraftCombineDrillResult] the result object
71
+ def self.build_result(headers, row)
72
+ data = headers.zip(row).to_h
73
+ DraftCombineDrillResult.new(**ResultAttributes.extract(data))
74
+ end
75
+ private_class_method :build_result
76
+
77
+ # Extracts result attributes from data
78
+ # @api private
79
+ module ResultAttributes
80
+ # Extracts all result attributes from data
81
+ # @api private
82
+ # @param data [Hash] the row data
83
+ # @return [Hash] extracted attributes
84
+ def self.extract(data)
85
+ player(data).merge(drills(data))
86
+ end
87
+
88
+ # Extracts player attributes from data
89
+ # @api private
90
+ # @param data [Hash] the row data
91
+ # @return [Hash] player attributes
92
+ def self.player(data)
93
+ {temp_player_id: data["TEMP_PLAYER_ID"], player_id: data["PLAYER_ID"],
94
+ first_name: data["FIRST_NAME"], last_name: data["LAST_NAME"],
95
+ player_name: data["PLAYER_NAME"], position: data["POSITION"]}
96
+ end
97
+
98
+ # Extracts drill result attributes from data
99
+ # @api private
100
+ # @param data [Hash] the row data
101
+ # @return [Hash] drill result attributes
102
+ def self.drills(data)
103
+ {standing_vertical_leap: data["STANDING_VERTICAL_LEAP"],
104
+ max_vertical_leap: data["MAX_VERTICAL_LEAP"],
105
+ lane_agility_time: data["LANE_AGILITY_TIME"],
106
+ modified_lane_agility_time: data["MODIFIED_LANE_AGILITY_TIME"],
107
+ three_quarter_sprint: data["THREE_QUARTER_SPRINT"],
108
+ bench_press: data["BENCH_PRESS"]}
109
+ end
110
+ end
111
+ end
112
+ end