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,217 @@
1
+ require "shale"
2
+ require "equalizer"
3
+
4
+ module NBA
5
+ # Represents a player's miscellaneous box score statistics for a game
6
+ class BoxScoreMiscPlayerStat < Shale::Mapper
7
+ include Equalizer.new(:game_id, :player_id)
8
+
9
+ # @!attribute [rw] game_id
10
+ # Returns the game ID
11
+ # @api public
12
+ # @example
13
+ # stat.game_id #=> "0022400565"
14
+ # @return [String] the game ID
15
+ attribute :game_id, Shale::Type::String
16
+
17
+ # @!attribute [rw] team_id
18
+ # Returns the team ID
19
+ # @api public
20
+ # @example
21
+ # stat.team_id #=> 1610612744
22
+ # @return [Integer] the team ID
23
+ attribute :team_id, Shale::Type::Integer
24
+
25
+ # @!attribute [rw] team_abbreviation
26
+ # Returns the team abbreviation
27
+ # @api public
28
+ # @example
29
+ # stat.team_abbreviation #=> "GSW"
30
+ # @return [String] the team abbreviation
31
+ attribute :team_abbreviation, Shale::Type::String
32
+
33
+ # @!attribute [rw] team_city
34
+ # Returns the team city
35
+ # @api public
36
+ # @example
37
+ # stat.team_city #=> "Golden State"
38
+ # @return [String] the team city
39
+ attribute :team_city, Shale::Type::String
40
+
41
+ # @!attribute [rw] player_id
42
+ # Returns the player ID
43
+ # @api public
44
+ # @example
45
+ # stat.player_id #=> 201939
46
+ # @return [Integer] the player ID
47
+ attribute :player_id, Shale::Type::Integer
48
+
49
+ # @!attribute [rw] player_name
50
+ # Returns the player name
51
+ # @api public
52
+ # @example
53
+ # stat.player_name #=> "Stephen Curry"
54
+ # @return [String] the player name
55
+ attribute :player_name, Shale::Type::String
56
+
57
+ # @!attribute [rw] start_position
58
+ # Returns the starting position
59
+ # @api public
60
+ # @example
61
+ # stat.start_position #=> "G"
62
+ # @return [String] the starting position
63
+ attribute :start_position, Shale::Type::String
64
+
65
+ # @!attribute [rw] comment
66
+ # Returns any comment (e.g., "DNP - Rest")
67
+ # @api public
68
+ # @example
69
+ # stat.comment #=> "DNP - Rest"
70
+ # @return [String] the comment
71
+ attribute :comment, Shale::Type::String
72
+
73
+ # @!attribute [rw] min
74
+ # Returns minutes played
75
+ # @api public
76
+ # @example
77
+ # stat.min #=> "35:24"
78
+ # @return [String] the minutes played
79
+ attribute :min, Shale::Type::String
80
+
81
+ # @!attribute [rw] pts_off_tov
82
+ # Returns points off turnovers
83
+ # @api public
84
+ # @example
85
+ # stat.pts_off_tov #=> 12
86
+ # @return [Integer] points off turnovers
87
+ attribute :pts_off_tov, Shale::Type::Integer
88
+
89
+ # @!attribute [rw] pts_2nd_chance
90
+ # Returns second chance points
91
+ # @api public
92
+ # @example
93
+ # stat.pts_2nd_chance #=> 8
94
+ # @return [Integer] second chance points
95
+ attribute :pts_2nd_chance, Shale::Type::Integer
96
+
97
+ # @!attribute [rw] pts_fb
98
+ # Returns fast break points
99
+ # @api public
100
+ # @example
101
+ # stat.pts_fb #=> 15
102
+ # @return [Integer] fast break points
103
+ attribute :pts_fb, Shale::Type::Integer
104
+
105
+ # @!attribute [rw] pts_paint
106
+ # Returns points in the paint
107
+ # @api public
108
+ # @example
109
+ # stat.pts_paint #=> 42
110
+ # @return [Integer] points in the paint
111
+ attribute :pts_paint, Shale::Type::Integer
112
+
113
+ # @!attribute [rw] opp_pts_off_tov
114
+ # Returns opponent points off turnovers
115
+ # @api public
116
+ # @example
117
+ # stat.opp_pts_off_tov #=> 10
118
+ # @return [Integer] opponent points off turnovers
119
+ attribute :opp_pts_off_tov, Shale::Type::Integer
120
+
121
+ # @!attribute [rw] opp_pts_2nd_chance
122
+ # Returns opponent second chance points
123
+ # @api public
124
+ # @example
125
+ # stat.opp_pts_2nd_chance #=> 6
126
+ # @return [Integer] opponent second chance points
127
+ attribute :opp_pts_2nd_chance, Shale::Type::Integer
128
+
129
+ # @!attribute [rw] opp_pts_fb
130
+ # Returns opponent fast break points
131
+ # @api public
132
+ # @example
133
+ # stat.opp_pts_fb #=> 9
134
+ # @return [Integer] opponent fast break points
135
+ attribute :opp_pts_fb, Shale::Type::Integer
136
+
137
+ # @!attribute [rw] opp_pts_paint
138
+ # Returns opponent points in the paint
139
+ # @api public
140
+ # @example
141
+ # stat.opp_pts_paint #=> 38
142
+ # @return [Integer] opponent points in the paint
143
+ attribute :opp_pts_paint, Shale::Type::Integer
144
+
145
+ # @!attribute [rw] blk
146
+ # Returns blocks
147
+ # @api public
148
+ # @example
149
+ # stat.blk #=> 2
150
+ # @return [Integer] blocks
151
+ attribute :blk, Shale::Type::Integer
152
+
153
+ # @!attribute [rw] blka
154
+ # Returns blocked attempts
155
+ # @api public
156
+ # @example
157
+ # stat.blka #=> 1
158
+ # @return [Integer] blocked attempts
159
+ attribute :blka, Shale::Type::Integer
160
+
161
+ # @!attribute [rw] pf
162
+ # Returns personal fouls
163
+ # @api public
164
+ # @example
165
+ # stat.pf #=> 3
166
+ # @return [Integer] personal fouls
167
+ attribute :pf, Shale::Type::Integer
168
+
169
+ # @!attribute [rw] pfd
170
+ # Returns personal fouls drawn
171
+ # @api public
172
+ # @example
173
+ # stat.pfd #=> 4
174
+ # @return [Integer] personal fouls drawn
175
+ attribute :pfd, Shale::Type::Integer
176
+
177
+ # Returns the player object
178
+ #
179
+ # @api public
180
+ # @example
181
+ # stat.player #=> #<NBA::Player>
182
+ # @return [Player, nil] the player object
183
+ def player
184
+ Players.find(player_id)
185
+ end
186
+
187
+ # Returns the team object
188
+ #
189
+ # @api public
190
+ # @example
191
+ # stat.team #=> #<NBA::Team>
192
+ # @return [Team, nil] the team object
193
+ def team
194
+ Teams.find(team_id)
195
+ end
196
+
197
+ # Returns whether the player started the game
198
+ #
199
+ # @api public
200
+ # @example
201
+ # stat.starter? #=> true
202
+ # @return [Boolean] true if the player started
203
+ def starter?
204
+ !start_position.nil? && !start_position.empty?
205
+ end
206
+
207
+ # Returns the game object for this box score
208
+ #
209
+ # @api public
210
+ # @example
211
+ # stat.game #=> #<NBA::Game>
212
+ # @return [Game, nil] the game object
213
+ def game
214
+ Games.find(game_id)
215
+ end
216
+ end
217
+ end
@@ -0,0 +1,173 @@
1
+ require "shale"
2
+ require "equalizer"
3
+
4
+ module NBA
5
+ # Represents a team's miscellaneous box score statistics for a game
6
+ class BoxScoreMiscTeamStat < Shale::Mapper
7
+ include Equalizer.new(:game_id, :team_id)
8
+
9
+ # @!attribute [rw] game_id
10
+ # Returns the game ID
11
+ # @api public
12
+ # @example
13
+ # stat.game_id #=> "0022400565"
14
+ # @return [String] the game ID
15
+ attribute :game_id, Shale::Type::String
16
+
17
+ # @!attribute [rw] team_id
18
+ # Returns the team ID
19
+ # @api public
20
+ # @example
21
+ # stat.team_id #=> 1610612744
22
+ # @return [Integer] the team ID
23
+ attribute :team_id, Shale::Type::Integer
24
+
25
+ # @!attribute [rw] team_name
26
+ # Returns the team name
27
+ # @api public
28
+ # @example
29
+ # stat.team_name #=> "Warriors"
30
+ # @return [String] the team name
31
+ attribute :team_name, Shale::Type::String
32
+
33
+ # @!attribute [rw] team_abbreviation
34
+ # Returns the team abbreviation
35
+ # @api public
36
+ # @example
37
+ # stat.team_abbreviation #=> "GSW"
38
+ # @return [String] the team abbreviation
39
+ attribute :team_abbreviation, Shale::Type::String
40
+
41
+ # @!attribute [rw] team_city
42
+ # Returns the team city
43
+ # @api public
44
+ # @example
45
+ # stat.team_city #=> "Golden State"
46
+ # @return [String] the team city
47
+ attribute :team_city, Shale::Type::String
48
+
49
+ # @!attribute [rw] min
50
+ # Returns total minutes played
51
+ # @api public
52
+ # @example
53
+ # stat.min #=> "240:00"
54
+ # @return [String] the minutes
55
+ attribute :min, Shale::Type::String
56
+
57
+ # @!attribute [rw] pts_off_tov
58
+ # Returns points off turnovers
59
+ # @api public
60
+ # @example
61
+ # stat.pts_off_tov #=> 18
62
+ # @return [Integer] points off turnovers
63
+ attribute :pts_off_tov, Shale::Type::Integer
64
+
65
+ # @!attribute [rw] pts_2nd_chance
66
+ # Returns second chance points
67
+ # @api public
68
+ # @example
69
+ # stat.pts_2nd_chance #=> 14
70
+ # @return [Integer] second chance points
71
+ attribute :pts_2nd_chance, Shale::Type::Integer
72
+
73
+ # @!attribute [rw] pts_fb
74
+ # Returns fast break points
75
+ # @api public
76
+ # @example
77
+ # stat.pts_fb #=> 22
78
+ # @return [Integer] fast break points
79
+ attribute :pts_fb, Shale::Type::Integer
80
+
81
+ # @!attribute [rw] pts_paint
82
+ # Returns points in the paint
83
+ # @api public
84
+ # @example
85
+ # stat.pts_paint #=> 54
86
+ # @return [Integer] points in the paint
87
+ attribute :pts_paint, Shale::Type::Integer
88
+
89
+ # @!attribute [rw] opp_pts_off_tov
90
+ # Returns opponent points off turnovers
91
+ # @api public
92
+ # @example
93
+ # stat.opp_pts_off_tov #=> 15
94
+ # @return [Integer] opponent points off turnovers
95
+ attribute :opp_pts_off_tov, Shale::Type::Integer
96
+
97
+ # @!attribute [rw] opp_pts_2nd_chance
98
+ # Returns opponent second chance points
99
+ # @api public
100
+ # @example
101
+ # stat.opp_pts_2nd_chance #=> 11
102
+ # @return [Integer] opponent second chance points
103
+ attribute :opp_pts_2nd_chance, Shale::Type::Integer
104
+
105
+ # @!attribute [rw] opp_pts_fb
106
+ # Returns opponent fast break points
107
+ # @api public
108
+ # @example
109
+ # stat.opp_pts_fb #=> 16
110
+ # @return [Integer] opponent fast break points
111
+ attribute :opp_pts_fb, Shale::Type::Integer
112
+
113
+ # @!attribute [rw] opp_pts_paint
114
+ # Returns opponent points in the paint
115
+ # @api public
116
+ # @example
117
+ # stat.opp_pts_paint #=> 48
118
+ # @return [Integer] opponent points in the paint
119
+ attribute :opp_pts_paint, Shale::Type::Integer
120
+
121
+ # @!attribute [rw] blk
122
+ # Returns blocks
123
+ # @api public
124
+ # @example
125
+ # stat.blk #=> 7
126
+ # @return [Integer] blocks
127
+ attribute :blk, Shale::Type::Integer
128
+
129
+ # @!attribute [rw] blka
130
+ # Returns blocked attempts
131
+ # @api public
132
+ # @example
133
+ # stat.blka #=> 5
134
+ # @return [Integer] blocked attempts
135
+ attribute :blka, Shale::Type::Integer
136
+
137
+ # @!attribute [rw] pf
138
+ # Returns personal fouls
139
+ # @api public
140
+ # @example
141
+ # stat.pf #=> 21
142
+ # @return [Integer] personal fouls
143
+ attribute :pf, Shale::Type::Integer
144
+
145
+ # @!attribute [rw] pfd
146
+ # Returns personal fouls drawn
147
+ # @api public
148
+ # @example
149
+ # stat.pfd #=> 19
150
+ # @return [Integer] personal fouls drawn
151
+ attribute :pfd, Shale::Type::Integer
152
+
153
+ # Returns the team object
154
+ #
155
+ # @api public
156
+ # @example
157
+ # stat.team #=> #<NBA::Team>
158
+ # @return [Team, nil] the team object
159
+ def team
160
+ Teams.find(team_id)
161
+ end
162
+
163
+ # Returns the game object for this box score
164
+ #
165
+ # @api public
166
+ # @example
167
+ # stat.game #=> #<NBA::Game>
168
+ # @return [Game, nil] the game object
169
+ def game
170
+ Games.find(game_id)
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,163 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "box_score_misc_player_stat"
5
+ require_relative "box_score_misc_team_stat"
6
+ require_relative "box_score_v3_helpers"
7
+ require_relative "utils"
8
+
9
+ module NBA
10
+ # Provides methods to retrieve miscellaneous box score statistics using V3 API
11
+ module BoxScoreMiscV3
12
+ # @return [String] JSON key for miscellaneous box score data
13
+ BOX_SCORE_KEY = "boxScoreMisc".freeze
14
+ # @return [String] JSON key for player statistics
15
+ PLAYER_STATS = "PlayerStats".freeze
16
+ # @return [String] JSON key for team statistics
17
+ TEAM_STATS = "TeamStats".freeze
18
+
19
+ # Retrieves misc player box score stats for a game
20
+ #
21
+ # @api public
22
+ # @example
23
+ # stats = NBA::BoxScoreMiscV3.player_stats(game: "0022400001")
24
+ # stats.each { |stat| puts "#{stat.player_name}: #{stat.pts_paint}" }
25
+ # @param game [String, Integer] the game ID
26
+ # @param start_period [Integer] the starting period
27
+ # @param end_period [Integer] the ending period
28
+ # @param client [Client] the API client to use
29
+ # @return [Collection] a collection of player misc stats
30
+ def self.player_stats(game:, start_period: 0, end_period: 0, client: CLIENT)
31
+ game_id = Utils.extract_id(game)
32
+ response = client.get(build_path(game_id, start_period, end_period))
33
+ parse_player_response(response, game_id)
34
+ end
35
+
36
+ # Retrieves misc team box score stats for a game
37
+ #
38
+ # @api public
39
+ # @example
40
+ # stats = NBA::BoxScoreMiscV3.team_stats(game: "0022400001")
41
+ # stats.each { |stat| puts "#{stat.team_abbreviation}: #{stat.pts_paint}" }
42
+ # @param game [String, Integer] the game ID
43
+ # @param start_period [Integer] the starting period
44
+ # @param end_period [Integer] the ending period
45
+ # @param client [Client] the API client to use
46
+ # @return [Collection] a collection of team misc stats
47
+ def self.team_stats(game:, start_period: 0, end_period: 0, client: CLIENT)
48
+ game_id = Utils.extract_id(game)
49
+ response = client.get(build_path(game_id, start_period, end_period))
50
+ parse_team_response(response, game_id)
51
+ end
52
+
53
+ # Builds the API request path
54
+ # @api private
55
+ # @return [String] the request path
56
+ def self.build_path(game_id, start_period, end_period)
57
+ "boxscoremiscv3?GameID=#{game_id}&StartPeriod=#{start_period}" \
58
+ "&EndPeriod=#{end_period}&StartRange=0&EndRange=0&RangeType=0"
59
+ end
60
+ private_class_method :build_path
61
+
62
+ # Parses the API response into player stat objects
63
+ # @api private
64
+ # @return [Collection] collection of player stats
65
+ def self.parse_player_response(response, game_id)
66
+ return Collection.new unless response
67
+
68
+ data = JSON.parse(response)
69
+ players = BoxScoreV3Helpers.extract_players(data, BOX_SCORE_KEY)
70
+ return Collection.new unless players
71
+
72
+ Collection.new(players.map { |p| build_player_stat(p, game_id) })
73
+ end
74
+ private_class_method :parse_player_response
75
+
76
+ # Parses the API response into team stat objects
77
+ # @api private
78
+ # @return [Collection] collection of team stats
79
+ def self.parse_team_response(response, game_id)
80
+ return Collection.new unless response
81
+
82
+ data = JSON.parse(response)
83
+ teams = BoxScoreV3Helpers.extract_teams(data, BOX_SCORE_KEY)
84
+ return Collection.new unless teams
85
+
86
+ Collection.new(teams.map { |t| build_team_stat(t, game_id) })
87
+ end
88
+ private_class_method :parse_team_response
89
+
90
+ # Builds a player stat object from raw data
91
+ # @api private
92
+ # @return [BoxScoreMiscPlayerStat] the player stat object
93
+ def self.build_player_stat(player, game_id)
94
+ stats = player.fetch("statistics", {})
95
+ BoxScoreMiscPlayerStat.new(
96
+ **BoxScoreV3Helpers.player_identity(player, game_id),
97
+ min: stats["minutes"],
98
+ **misc_stats(stats)
99
+ )
100
+ end
101
+ private_class_method :build_player_stat
102
+
103
+ # Builds a team stat object from raw data
104
+ # @api private
105
+ # @return [BoxScoreMiscTeamStat] the team stat object
106
+ def self.build_team_stat(team, game_id)
107
+ stats = team.fetch("statistics", {})
108
+ BoxScoreMiscTeamStat.new(
109
+ **BoxScoreV3Helpers.team_identity(team, game_id),
110
+ min: stats["minutes"],
111
+ **misc_stats(stats)
112
+ )
113
+ end
114
+ private_class_method :build_team_stat
115
+
116
+ # Extracts miscellaneous statistics from raw data
117
+ # @api private
118
+ # @return [Hash] miscellaneous statistics
119
+ def self.misc_stats(stats)
120
+ points_stats(stats).merge(opponent_stats(stats), block_foul_stats(stats))
121
+ end
122
+ private_class_method :misc_stats
123
+
124
+ # Extracts points statistics from raw data
125
+ # @api private
126
+ # @return [Hash] points statistics
127
+ def self.points_stats(stats)
128
+ {
129
+ pts_off_tov: stats["pointsOffTurnovers"],
130
+ pts_2nd_chance: stats["pointsSecondChance"],
131
+ pts_fb: stats["pointsFastBreak"],
132
+ pts_paint: stats["pointsPaint"]
133
+ }
134
+ end
135
+ private_class_method :points_stats
136
+
137
+ # Extracts opponent statistics from raw data
138
+ # @api private
139
+ # @return [Hash] opponent statistics
140
+ def self.opponent_stats(stats)
141
+ {
142
+ opp_pts_off_tov: stats["oppPointsOffTurnovers"],
143
+ opp_pts_2nd_chance: stats["oppPointsSecondChance"],
144
+ opp_pts_fb: stats["oppPointsFastBreak"],
145
+ opp_pts_paint: stats["oppPointsPaint"]
146
+ }
147
+ end
148
+ private_class_method :opponent_stats
149
+
150
+ # Extracts block and foul statistics from raw data
151
+ # @api private
152
+ # @return [Hash] block and foul statistics
153
+ def self.block_foul_stats(stats)
154
+ {
155
+ blk: stats["blocks"],
156
+ blka: stats["blocksAgainst"],
157
+ pf: stats["foulsPersonal"],
158
+ pfd: stats["foulsDrawn"]
159
+ }
160
+ end
161
+ private_class_method :block_foul_stats
162
+ end
163
+ end