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,246 @@
1
+ module NBA
2
+ # Represents a single team game log entry
3
+ class TeamGameLogEntry < Shale::Mapper
4
+ include Equalizer.new(:game_id, :team_id)
5
+
6
+ # @!attribute [rw] team_id
7
+ # Returns the team ID
8
+ # @api public
9
+ # @example
10
+ # log.team_id #=> 1610612744
11
+ # @return [Integer] the team ID
12
+ attribute :team_id, Shale::Type::Integer
13
+
14
+ # @!attribute [rw] game_id
15
+ # Returns the game ID
16
+ # @api public
17
+ # @example
18
+ # log.game_id #=> "0022400001"
19
+ # @return [String] the game ID
20
+ attribute :game_id, Shale::Type::String
21
+
22
+ # @!attribute [rw] game_date
23
+ # Returns the game date
24
+ # @api public
25
+ # @example
26
+ # log.game_date #=> "OCT 22, 2024"
27
+ # @return [String] the game date
28
+ attribute :game_date, Shale::Type::String
29
+
30
+ # @!attribute [rw] matchup
31
+ # Returns the matchup description
32
+ # @api public
33
+ # @example
34
+ # log.matchup #=> "GSW vs. LAL"
35
+ # @return [String] the matchup
36
+ attribute :matchup, Shale::Type::String
37
+
38
+ # @!attribute [rw] wl
39
+ # Returns the win/loss result
40
+ # @api public
41
+ # @example
42
+ # log.wl #=> "W"
43
+ # @return [String] the win/loss indicator
44
+ attribute :wl, Shale::Type::String
45
+
46
+ # @!attribute [rw] min
47
+ # Returns the minutes played
48
+ # @api public
49
+ # @example
50
+ # log.min #=> 240
51
+ # @return [Integer] the minutes played
52
+ attribute :min, Shale::Type::Integer
53
+
54
+ # @!attribute [rw] fgm
55
+ # Returns field goals made
56
+ # @api public
57
+ # @example
58
+ # log.fgm #=> 42
59
+ # @return [Integer] field goals made
60
+ attribute :fgm, Shale::Type::Integer
61
+
62
+ # @!attribute [rw] fga
63
+ # Returns field goals attempted
64
+ # @api public
65
+ # @example
66
+ # log.fga #=> 88
67
+ # @return [Integer] field goals attempted
68
+ attribute :fga, Shale::Type::Integer
69
+
70
+ # @!attribute [rw] fg_pct
71
+ # Returns field goal percentage
72
+ # @api public
73
+ # @example
74
+ # log.fg_pct #=> 0.477
75
+ # @return [Float] field goal percentage
76
+ attribute :fg_pct, Shale::Type::Float
77
+
78
+ # @!attribute [rw] fg3m
79
+ # Returns three-pointers made
80
+ # @api public
81
+ # @example
82
+ # log.fg3m #=> 15
83
+ # @return [Integer] three-pointers made
84
+ attribute :fg3m, Shale::Type::Integer
85
+
86
+ # @!attribute [rw] fg3a
87
+ # Returns three-pointers attempted
88
+ # @api public
89
+ # @example
90
+ # log.fg3a #=> 40
91
+ # @return [Integer] three-pointers attempted
92
+ attribute :fg3a, Shale::Type::Integer
93
+
94
+ # @!attribute [rw] fg3_pct
95
+ # Returns three-point percentage
96
+ # @api public
97
+ # @example
98
+ # log.fg3_pct #=> 0.375
99
+ # @return [Float] three-point percentage
100
+ attribute :fg3_pct, Shale::Type::Float
101
+
102
+ # @!attribute [rw] ftm
103
+ # Returns free throws made
104
+ # @api public
105
+ # @example
106
+ # log.ftm #=> 20
107
+ # @return [Integer] free throws made
108
+ attribute :ftm, Shale::Type::Integer
109
+
110
+ # @!attribute [rw] fta
111
+ # Returns free throws attempted
112
+ # @api public
113
+ # @example
114
+ # log.fta #=> 25
115
+ # @return [Integer] free throws attempted
116
+ attribute :fta, Shale::Type::Integer
117
+
118
+ # @!attribute [rw] ft_pct
119
+ # Returns free throw percentage
120
+ # @api public
121
+ # @example
122
+ # log.ft_pct #=> 0.800
123
+ # @return [Float] free throw percentage
124
+ attribute :ft_pct, Shale::Type::Float
125
+
126
+ # @!attribute [rw] oreb
127
+ # Returns offensive rebounds
128
+ # @api public
129
+ # @example
130
+ # log.oreb #=> 10
131
+ # @return [Integer] offensive rebounds
132
+ attribute :oreb, Shale::Type::Integer
133
+
134
+ # @!attribute [rw] dreb
135
+ # Returns defensive rebounds
136
+ # @api public
137
+ # @example
138
+ # log.dreb #=> 35
139
+ # @return [Integer] defensive rebounds
140
+ attribute :dreb, Shale::Type::Integer
141
+
142
+ # @!attribute [rw] reb
143
+ # Returns total rebounds
144
+ # @api public
145
+ # @example
146
+ # log.reb #=> 45
147
+ # @return [Integer] total rebounds
148
+ attribute :reb, Shale::Type::Integer
149
+
150
+ # @!attribute [rw] ast
151
+ # Returns assists
152
+ # @api public
153
+ # @example
154
+ # log.ast #=> 28
155
+ # @return [Integer] assists
156
+ attribute :ast, Shale::Type::Integer
157
+
158
+ # @!attribute [rw] stl
159
+ # Returns steals
160
+ # @api public
161
+ # @example
162
+ # log.stl #=> 8
163
+ # @return [Integer] steals
164
+ attribute :stl, Shale::Type::Integer
165
+
166
+ # @!attribute [rw] blk
167
+ # Returns blocks
168
+ # @api public
169
+ # @example
170
+ # log.blk #=> 5
171
+ # @return [Integer] blocks
172
+ attribute :blk, Shale::Type::Integer
173
+
174
+ # @!attribute [rw] tov
175
+ # Returns turnovers
176
+ # @api public
177
+ # @example
178
+ # log.tov #=> 12
179
+ # @return [Integer] turnovers
180
+ attribute :tov, Shale::Type::Integer
181
+
182
+ # @!attribute [rw] pf
183
+ # Returns personal fouls
184
+ # @api public
185
+ # @example
186
+ # log.pf #=> 18
187
+ # @return [Integer] personal fouls
188
+ attribute :pf, Shale::Type::Integer
189
+
190
+ # @!attribute [rw] pts
191
+ # Returns points
192
+ # @api public
193
+ # @example
194
+ # log.pts #=> 119
195
+ # @return [Integer] points
196
+ attribute :pts, Shale::Type::Integer
197
+
198
+ # @!attribute [rw] plus_minus
199
+ # Returns plus/minus
200
+ # @api public
201
+ # @example
202
+ # log.plus_minus #=> 12
203
+ # @return [Integer] plus/minus
204
+ attribute :plus_minus, Shale::Type::Integer
205
+
206
+ # Returns whether the game was a win
207
+ #
208
+ # @api public
209
+ # @example
210
+ # log.win? #=> true
211
+ # @return [Boolean] whether the game was a win
212
+ def win?
213
+ wl.eql?("W")
214
+ end
215
+
216
+ # Returns whether the game was a loss
217
+ #
218
+ # @api public
219
+ # @example
220
+ # log.loss? #=> false
221
+ # @return [Boolean] whether the game was a loss
222
+ def loss?
223
+ wl.eql?("L")
224
+ end
225
+
226
+ # Returns the team object for this game log
227
+ #
228
+ # @api public
229
+ # @example
230
+ # log.team #=> #<NBA::Team>
231
+ # @return [Team, nil] the team object
232
+ def team
233
+ Teams.find(team_id)
234
+ end
235
+
236
+ # Returns the game object for this log entry
237
+ #
238
+ # @api public
239
+ # @example
240
+ # log.game #=> #<NBA::Game>
241
+ # @return [Game, nil] the game object
242
+ def game
243
+ Games.find(game_id)
244
+ end
245
+ end
246
+ end
@@ -0,0 +1,275 @@
1
+ require "equalizer"
2
+ require "shale"
3
+
4
+ module NBA
5
+ # Represents a single team game log entry from the batch endpoint
6
+ #
7
+ # @api public
8
+ class TeamGameLogStat < Shale::Mapper
9
+ include Equalizer.new(:game_id, :team_id)
10
+
11
+ # @!attribute [rw] season_year
12
+ # Returns the season year
13
+ # @api public
14
+ # @example
15
+ # log.season_year #=> "2024-25"
16
+ # @return [String] the season year
17
+ attribute :season_year, Shale::Type::String
18
+
19
+ # @!attribute [rw] team_id
20
+ # Returns the team ID
21
+ # @api public
22
+ # @example
23
+ # log.team_id #=> 1610612744
24
+ # @return [Integer] the team ID
25
+ attribute :team_id, Shale::Type::Integer
26
+
27
+ # @!attribute [rw] team_abbreviation
28
+ # Returns the team abbreviation
29
+ # @api public
30
+ # @example
31
+ # log.team_abbreviation #=> "GSW"
32
+ # @return [String] the team abbreviation
33
+ attribute :team_abbreviation, Shale::Type::String
34
+
35
+ # @!attribute [rw] team_name
36
+ # Returns the team name
37
+ # @api public
38
+ # @example
39
+ # log.team_name #=> "Warriors"
40
+ # @return [String] the team name
41
+ attribute :team_name, Shale::Type::String
42
+
43
+ # @!attribute [rw] game_id
44
+ # Returns the game ID
45
+ # @api public
46
+ # @example
47
+ # log.game_id #=> "0022400001"
48
+ # @return [String] the game ID
49
+ attribute :game_id, Shale::Type::String
50
+
51
+ # @!attribute [rw] game_date
52
+ # Returns the game date
53
+ # @api public
54
+ # @example
55
+ # log.game_date #=> "2024-10-22T00:00:00"
56
+ # @return [String] the game date
57
+ attribute :game_date, Shale::Type::String
58
+
59
+ # @!attribute [rw] matchup
60
+ # Returns the matchup description
61
+ # @api public
62
+ # @example
63
+ # log.matchup #=> "GSW vs. LAL"
64
+ # @return [String] the matchup
65
+ attribute :matchup, Shale::Type::String
66
+
67
+ # @!attribute [rw] wl
68
+ # Returns the win/loss indicator
69
+ # @api public
70
+ # @example
71
+ # log.wl #=> "W"
72
+ # @return [String] W for win, L for loss
73
+ attribute :wl, Shale::Type::String
74
+
75
+ # @!attribute [rw] min
76
+ # Returns the minutes played
77
+ # @api public
78
+ # @example
79
+ # log.min #=> 240
80
+ # @return [Integer] the minutes played
81
+ attribute :min, Shale::Type::Integer
82
+
83
+ # @!attribute [rw] fgm
84
+ # Returns the field goals made
85
+ # @api public
86
+ # @example
87
+ # log.fgm #=> 42
88
+ # @return [Integer] field goals made
89
+ attribute :fgm, Shale::Type::Integer
90
+
91
+ # @!attribute [rw] fga
92
+ # Returns the field goals attempted
93
+ # @api public
94
+ # @example
95
+ # log.fga #=> 88
96
+ # @return [Integer] field goals attempted
97
+ attribute :fga, Shale::Type::Integer
98
+
99
+ # @!attribute [rw] fg_pct
100
+ # Returns the field goal percentage
101
+ # @api public
102
+ # @example
103
+ # log.fg_pct #=> 0.477
104
+ # @return [Float] field goal percentage
105
+ attribute :fg_pct, Shale::Type::Float
106
+
107
+ # @!attribute [rw] fg3m
108
+ # Returns the three-pointers made
109
+ # @api public
110
+ # @example
111
+ # log.fg3m #=> 15
112
+ # @return [Integer] three-pointers made
113
+ attribute :fg3m, Shale::Type::Integer
114
+
115
+ # @!attribute [rw] fg3a
116
+ # Returns the three-pointers attempted
117
+ # @api public
118
+ # @example
119
+ # log.fg3a #=> 38
120
+ # @return [Integer] three-pointers attempted
121
+ attribute :fg3a, Shale::Type::Integer
122
+
123
+ # @!attribute [rw] fg3_pct
124
+ # Returns the three-point percentage
125
+ # @api public
126
+ # @example
127
+ # log.fg3_pct #=> 0.395
128
+ # @return [Float] three-point percentage
129
+ attribute :fg3_pct, Shale::Type::Float
130
+
131
+ # @!attribute [rw] ftm
132
+ # Returns the free throws made
133
+ # @api public
134
+ # @example
135
+ # log.ftm #=> 19
136
+ # @return [Integer] free throws made
137
+ attribute :ftm, Shale::Type::Integer
138
+
139
+ # @!attribute [rw] fta
140
+ # Returns the free throws attempted
141
+ # @api public
142
+ # @example
143
+ # log.fta #=> 22
144
+ # @return [Integer] free throws attempted
145
+ attribute :fta, Shale::Type::Integer
146
+
147
+ # @!attribute [rw] ft_pct
148
+ # Returns the free throw percentage
149
+ # @api public
150
+ # @example
151
+ # log.ft_pct #=> 0.864
152
+ # @return [Float] free throw percentage
153
+ attribute :ft_pct, Shale::Type::Float
154
+
155
+ # @!attribute [rw] oreb
156
+ # Returns the offensive rebounds
157
+ # @api public
158
+ # @example
159
+ # log.oreb #=> 10
160
+ # @return [Integer] offensive rebounds
161
+ attribute :oreb, Shale::Type::Integer
162
+
163
+ # @!attribute [rw] dreb
164
+ # Returns the defensive rebounds
165
+ # @api public
166
+ # @example
167
+ # log.dreb #=> 35
168
+ # @return [Integer] defensive rebounds
169
+ attribute :dreb, Shale::Type::Integer
170
+
171
+ # @!attribute [rw] reb
172
+ # Returns the total rebounds
173
+ # @api public
174
+ # @example
175
+ # log.reb #=> 45
176
+ # @return [Integer] total rebounds
177
+ attribute :reb, Shale::Type::Integer
178
+
179
+ # @!attribute [rw] ast
180
+ # Returns the assists
181
+ # @api public
182
+ # @example
183
+ # log.ast #=> 28
184
+ # @return [Integer] assists
185
+ attribute :ast, Shale::Type::Integer
186
+
187
+ # @!attribute [rw] stl
188
+ # Returns the steals
189
+ # @api public
190
+ # @example
191
+ # log.stl #=> 9
192
+ # @return [Integer] steals
193
+ attribute :stl, Shale::Type::Integer
194
+
195
+ # @!attribute [rw] blk
196
+ # Returns the blocks
197
+ # @api public
198
+ # @example
199
+ # log.blk #=> 6
200
+ # @return [Integer] blocks
201
+ attribute :blk, Shale::Type::Integer
202
+
203
+ # @!attribute [rw] tov
204
+ # Returns the turnovers
205
+ # @api public
206
+ # @example
207
+ # log.tov #=> 14
208
+ # @return [Integer] turnovers
209
+ attribute :tov, Shale::Type::Integer
210
+
211
+ # @!attribute [rw] pf
212
+ # Returns the personal fouls
213
+ # @api public
214
+ # @example
215
+ # log.pf #=> 20
216
+ # @return [Integer] personal fouls
217
+ attribute :pf, Shale::Type::Integer
218
+
219
+ # @!attribute [rw] pts
220
+ # Returns the points scored
221
+ # @api public
222
+ # @example
223
+ # log.pts #=> 118
224
+ # @return [Integer] points
225
+ attribute :pts, Shale::Type::Integer
226
+
227
+ # @!attribute [rw] plus_minus
228
+ # Returns the plus/minus
229
+ # @api public
230
+ # @example
231
+ # log.plus_minus #=> 9
232
+ # @return [Integer] plus/minus
233
+ attribute :plus_minus, Shale::Type::Integer
234
+
235
+ # Returns whether the game was a win
236
+ #
237
+ # @api public
238
+ # @example
239
+ # log.win? #=> true
240
+ # @return [Boolean] true if the game was a win
241
+ def win?
242
+ wl.eql?("W")
243
+ end
244
+
245
+ # Returns whether the game was a loss
246
+ #
247
+ # @api public
248
+ # @example
249
+ # log.loss? #=> false
250
+ # @return [Boolean] true if the game was a loss
251
+ def loss?
252
+ wl.eql?("L")
253
+ end
254
+
255
+ # Returns the game object for this log entry
256
+ #
257
+ # @api public
258
+ # @example
259
+ # log.game #=> #<NBA::Game>
260
+ # @return [Game, nil] the game object
261
+ def game
262
+ Games.find(game_id)
263
+ end
264
+
265
+ # Returns the team object for this log entry
266
+ #
267
+ # @api public
268
+ # @example
269
+ # log.team #=> #<NBA::Team>
270
+ # @return [Team, nil] the team object
271
+ def team
272
+ Teams.find(team_id)
273
+ end
274
+ end
275
+ end
@@ -0,0 +1,163 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "team_game_log_stat"
5
+ require_relative "utils"
6
+
7
+ module NBA
8
+ # Provides methods to retrieve team game logs in batch
9
+ #
10
+ # @api public
11
+ module TeamGameLogs
12
+ # Regular season type
13
+ # @return [String] the season type
14
+ REGULAR_SEASON = "Regular Season".freeze
15
+
16
+ # Playoffs season type
17
+ # @return [String] the season type
18
+ PLAYOFFS = "Playoffs".freeze
19
+
20
+ # Per game mode
21
+ # @return [String] the per mode
22
+ PER_GAME = "PerGame".freeze
23
+
24
+ # Totals mode
25
+ # @return [String] the per mode
26
+ TOTALS = "Totals".freeze
27
+
28
+ # Result set name
29
+ # @return [String] the result set name
30
+ RESULT_SET_NAME = "TeamGameLogs".freeze
31
+
32
+ # Retrieves game logs for all teams matching the criteria
33
+ #
34
+ # @api public
35
+ # @example
36
+ # logs = NBA::TeamGameLogs.all(season: 2024)
37
+ # logs.each { |log| puts "#{log.game_date}: #{log.team_name} - #{log.pts} pts" }
38
+ # @param season [Integer] the season year (defaults to current season)
39
+ # @param season_type [String] the season type (Regular Season, Playoffs)
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 team game logs
44
+ def self.all(season: Utils.current_season, season_type: REGULAR_SEASON, team: nil,
45
+ per_mode: PER_GAME, client: CLIENT)
46
+ path = build_path(season, season_type, team, per_mode)
47
+ response = client.get(path)
48
+ parse_response(response)
49
+ end
50
+
51
+ # Builds the API path
52
+ #
53
+ # @api private
54
+ # @return [String] the API path
55
+ def self.build_path(season, season_type, team, per_mode)
56
+ path = "teamgamelogs?LeagueID=00&Season=#{Utils.format_season(season)}" \
57
+ "&SeasonType=#{season_type}&PerModeSimple=#{per_mode}"
58
+ path += "&TeamID=#{Utils.extract_id(team)}" if team
59
+ path
60
+ end
61
+ private_class_method :build_path
62
+
63
+ # Parses the API response
64
+ #
65
+ # @api private
66
+ # @param response [String] the JSON response body
67
+ # @return [Collection] a collection of team game logs
68
+ def self.parse_response(response)
69
+ return Collection.new unless response
70
+
71
+ data = JSON.parse(response)
72
+ result_set = find_result_set(data)
73
+ return Collection.new unless result_set
74
+
75
+ headers = result_set["headers"]
76
+ rows = result_set["rowSet"]
77
+ return Collection.new unless headers && rows
78
+
79
+ logs = rows.map { |row| build_game_log(headers, row) }
80
+ Collection.new(logs)
81
+ end
82
+ private_class_method :parse_response
83
+
84
+ # Finds the result set
85
+ #
86
+ # @api private
87
+ # @param data [Hash] the parsed JSON data
88
+ # @return [Hash, nil] the result set
89
+ def self.find_result_set(data)
90
+ result_sets = data["resultSets"]
91
+ return unless result_sets
92
+
93
+ result_sets.find { |rs| rs["name"].eql?(RESULT_SET_NAME) }
94
+ end
95
+ private_class_method :find_result_set
96
+
97
+ # Builds a game log from API data
98
+ #
99
+ # @api private
100
+ # @param headers [Array<String>] the column headers
101
+ # @param row [Array] the row data
102
+ # @return [TeamGameLogStat]
103
+ def self.build_game_log(headers, row)
104
+ data = headers.zip(row).to_h
105
+ TeamGameLogStat.new(**game_log_attributes(data))
106
+ end
107
+ private_class_method :build_game_log
108
+
109
+ # Combines all game log attributes
110
+ #
111
+ # @api private
112
+ # @param data [Hash] the raw data
113
+ # @return [Hash] combined attributes
114
+ def self.game_log_attributes(data)
115
+ game_info(data).merge(team_info(data), shooting_stats(data), counting_stats(data))
116
+ end
117
+ private_class_method :game_log_attributes
118
+
119
+ # Extracts game information from data
120
+ #
121
+ # @api private
122
+ # @return [Hash]
123
+ def self.game_info(data)
124
+ {season_year: data["SEASON_YEAR"], game_id: data["GAME_ID"],
125
+ game_date: data["GAME_DATE"], matchup: data["MATCHUP"],
126
+ wl: data["WL"], min: data["MIN"]}
127
+ end
128
+ private_class_method :game_info
129
+
130
+ # Extracts team information from data
131
+ #
132
+ # @api private
133
+ # @return [Hash]
134
+ def self.team_info(data)
135
+ {team_id: data["TEAM_ID"], team_abbreviation: data["TEAM_ABBREVIATION"],
136
+ team_name: data["TEAM_NAME"]}
137
+ end
138
+ private_class_method :team_info
139
+
140
+ # Extracts shooting statistics from data
141
+ #
142
+ # @api private
143
+ # @return [Hash]
144
+ def self.shooting_stats(data)
145
+ {fgm: data["FGM"], fga: data["FGA"], fg_pct: data["FG_PCT"],
146
+ fg3m: data["FG3M"], fg3a: data["FG3A"], fg3_pct: data["FG3_PCT"],
147
+ ftm: data["FTM"], fta: data["FTA"], ft_pct: data["FT_PCT"]}
148
+ end
149
+ private_class_method :shooting_stats
150
+
151
+ # Extracts counting statistics from data
152
+ #
153
+ # @api private
154
+ # @return [Hash]
155
+ def self.counting_stats(data)
156
+ {oreb: data["OREB"], dreb: data["DREB"], reb: data["REB"],
157
+ ast: data["AST"], stl: data["STL"], blk: data["BLK"],
158
+ tov: data["TOV"], pf: data["PF"], pts: data["PTS"],
159
+ plus_minus: data["PLUS_MINUS"]}
160
+ end
161
+ private_class_method :counting_stats
162
+ end
163
+ end