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,150 @@
1
+ require "equalizer"
2
+ require "shale"
3
+ require_relative "teams"
4
+
5
+ module NBA
6
+ # Represents team information from the TeamInfoCommon endpoint
7
+ #
8
+ # @api public
9
+ class TeamInfo < Shale::Mapper
10
+ include Equalizer.new(:team_id, :season_year)
11
+
12
+ # @!attribute [rw] team_id
13
+ # Returns the team ID
14
+ # @api public
15
+ # @example
16
+ # info.team_id #=> 1610612744
17
+ # @return [Integer, nil] the team's ID
18
+ attribute :team_id, Shale::Type::Integer
19
+
20
+ # @!attribute [rw] season_year
21
+ # Returns the season year
22
+ # @api public
23
+ # @example
24
+ # info.season_year #=> "2024-25"
25
+ # @return [String, nil] the season year
26
+ attribute :season_year, Shale::Type::String
27
+
28
+ # @!attribute [rw] team_city
29
+ # Returns the team city
30
+ # @api public
31
+ # @example
32
+ # info.team_city #=> "Golden State"
33
+ # @return [String, nil] the team's city
34
+ attribute :team_city, Shale::Type::String
35
+
36
+ # @!attribute [rw] team_name
37
+ # Returns the team name
38
+ # @api public
39
+ # @example
40
+ # info.team_name #=> "Warriors"
41
+ # @return [String, nil] the team's name
42
+ attribute :team_name, Shale::Type::String
43
+
44
+ # @!attribute [rw] team_abbreviation
45
+ # Returns the team abbreviation
46
+ # @api public
47
+ # @example
48
+ # info.team_abbreviation #=> "GSW"
49
+ # @return [String, nil] the team's abbreviation
50
+ attribute :team_abbreviation, Shale::Type::String
51
+
52
+ # @!attribute [rw] team_conference
53
+ # Returns the team conference
54
+ # @api public
55
+ # @example
56
+ # info.team_conference #=> "West"
57
+ # @return [String, nil] the team's conference
58
+ attribute :team_conference, Shale::Type::String
59
+
60
+ # @!attribute [rw] team_division
61
+ # Returns the team division
62
+ # @api public
63
+ # @example
64
+ # info.team_division #=> "Pacific"
65
+ # @return [String, nil] the team's division
66
+ attribute :team_division, Shale::Type::String
67
+
68
+ # @!attribute [rw] team_code
69
+ # Returns the team code
70
+ # @api public
71
+ # @example
72
+ # info.team_code #=> "warriors"
73
+ # @return [String, nil] the team's code
74
+ attribute :team_code, Shale::Type::String
75
+
76
+ # @!attribute [rw] team_slug
77
+ # Returns the team slug
78
+ # @api public
79
+ # @example
80
+ # info.team_slug #=> "warriors"
81
+ # @return [String, nil] the team's slug
82
+ attribute :team_slug, Shale::Type::String
83
+
84
+ # @!attribute [rw] w
85
+ # Returns wins
86
+ # @api public
87
+ # @example
88
+ # info.w #=> 46
89
+ # @return [Integer, nil] wins
90
+ attribute :w, Shale::Type::Integer
91
+
92
+ # @!attribute [rw] l
93
+ # Returns losses
94
+ # @api public
95
+ # @example
96
+ # info.l #=> 36
97
+ # @return [Integer, nil] losses
98
+ attribute :l, Shale::Type::Integer
99
+
100
+ # @!attribute [rw] pct
101
+ # Returns win percentage
102
+ # @api public
103
+ # @example
104
+ # info.pct #=> 0.561
105
+ # @return [Float, nil] win percentage
106
+ attribute :pct, Shale::Type::Float
107
+
108
+ # @!attribute [rw] conf_rank
109
+ # Returns conference rank
110
+ # @api public
111
+ # @example
112
+ # info.conf_rank #=> 4
113
+ # @return [Integer, nil] conference rank
114
+ attribute :conf_rank, Shale::Type::Integer
115
+
116
+ # @!attribute [rw] div_rank
117
+ # Returns division rank
118
+ # @api public
119
+ # @example
120
+ # info.div_rank #=> 2
121
+ # @return [Integer, nil] division rank
122
+ attribute :div_rank, Shale::Type::Integer
123
+
124
+ # @!attribute [rw] min_year
125
+ # Returns the minimum year (franchise founding year)
126
+ # @api public
127
+ # @example
128
+ # info.min_year #=> "1946"
129
+ # @return [String, nil] the minimum year
130
+ attribute :min_year, Shale::Type::String
131
+
132
+ # @!attribute [rw] max_year
133
+ # Returns the maximum year
134
+ # @api public
135
+ # @example
136
+ # info.max_year #=> "2024"
137
+ # @return [String, nil] the maximum year
138
+ attribute :max_year, Shale::Type::String
139
+
140
+ # Returns the team associated with this info
141
+ #
142
+ # @api public
143
+ # @example
144
+ # info.team #=> #<NBA::Team ...>
145
+ # @return [Team, nil] the Team object
146
+ def team
147
+ Teams.find(team_id)
148
+ end
149
+ end
150
+ end
@@ -0,0 +1,177 @@
1
+ require "json"
2
+ require_relative "client"
3
+ require_relative "collection"
4
+ require_relative "team_info"
5
+ require_relative "team_season_rank"
6
+ require_relative "utils"
7
+
8
+ module NBA
9
+ # Provides methods to retrieve team information and season rankings
10
+ #
11
+ # @api public
12
+ module TeamInfoCommon
13
+ # Result set name for team info
14
+ # @return [String] the result set name
15
+ TEAM_INFO_COMMON = "TeamInfoCommon".freeze
16
+
17
+ # Result set name for team season ranks
18
+ # @return [String] the result set name
19
+ TEAM_SEASON_RANKS = "TeamSeasonRanks".freeze
20
+
21
+ # Result set name for available seasons
22
+ # @return [String] the result set name
23
+ AVAILABLE_SEASONS = "AvailableSeasons".freeze
24
+
25
+ # Retrieves team information
26
+ #
27
+ # @api public
28
+ # @example
29
+ # info = NBA::TeamInfoCommon.find(team: NBA::Team::GSW)
30
+ # puts "#{info.team_city} #{info.team_name}: #{info.w}-#{info.l}"
31
+ # @param team [Integer, Team] the team ID or Team object
32
+ # @param season [Integer, nil] the season year (defaults to current season)
33
+ # @param season_type [String, nil] the season type
34
+ # @param client [Client] the API client to use
35
+ # @return [TeamInfo, nil] the team information
36
+ def self.find(team:, season: Utils.current_season, season_type: nil, client: CLIENT)
37
+ path = build_path(team, season, season_type)
38
+ response = client.get(path)
39
+ parse_info_response(response)
40
+ end
41
+
42
+ # Retrieves team season rankings
43
+ #
44
+ # @api public
45
+ # @example
46
+ # ranks = NBA::TeamInfoCommon.ranks(team: NBA::Team::GSW)
47
+ # puts "Points rank: #{ranks.pts_rank} (#{ranks.pts_pg} PPG)"
48
+ # @param team [Integer, Team] the team ID or Team object
49
+ # @param season [Integer, nil] the season year (defaults to current season)
50
+ # @param season_type [String, nil] the season type
51
+ # @param client [Client] the API client to use
52
+ # @return [TeamSeasonRank, nil] the team season rankings
53
+ def self.ranks(team:, season: Utils.current_season, season_type: nil, client: CLIENT)
54
+ path = build_path(team, season, season_type)
55
+ response = client.get(path)
56
+ parse_ranks_response(response)
57
+ end
58
+
59
+ # Retrieves available seasons for a team
60
+ #
61
+ # @api public
62
+ # @example
63
+ # seasons = NBA::TeamInfoCommon.available_seasons(team: NBA::Team::GSW)
64
+ # seasons.each { |s| puts s }
65
+ # @param team [Integer, Team] the team ID or Team object
66
+ # @param client [Client] the API client to use
67
+ # @return [Collection] a collection of season IDs
68
+ def self.available_seasons(team:, client: CLIENT)
69
+ path = build_path(team, nil, nil)
70
+ response = client.get(path)
71
+ parse_seasons_response(response)
72
+ end
73
+
74
+ # Builds the API path
75
+ #
76
+ # @api private
77
+ # @return [String] the request path
78
+ def self.build_path(team, season, season_type)
79
+ team_id = Utils.extract_id(team)
80
+ path = "teaminfocommon?TeamID=#{team_id}&LeagueID=00"
81
+ path += "&Season=#{Utils.format_season(season)}" if season
82
+ path += "&SeasonType=#{season_type}" if season_type
83
+ path
84
+ end
85
+ private_class_method :build_path
86
+
87
+ # Parses the API response into team info
88
+ #
89
+ # @api private
90
+ # @return [TeamInfo, nil] the team info
91
+ def self.parse_info_response(response)
92
+ return unless response
93
+
94
+ data = JSON.parse(response)
95
+ result_set = find_result_set(data, TEAM_INFO_COMMON)
96
+ return unless result_set
97
+
98
+ headers = result_set["headers"]
99
+ row = result_set.dig("rowSet", 0)
100
+ return unless headers && row
101
+
102
+ build_team_info(headers.zip(row).to_h)
103
+ end
104
+ private_class_method :parse_info_response
105
+
106
+ # Parses the API response into team season ranks
107
+ #
108
+ # @api private
109
+ # @return [TeamSeasonRank, nil] the team season ranks
110
+ def self.parse_ranks_response(response)
111
+ return unless response
112
+
113
+ data = JSON.parse(response)
114
+ result_set = find_result_set(data, TEAM_SEASON_RANKS)
115
+ return unless result_set
116
+
117
+ headers = result_set["headers"]
118
+ row = result_set.dig("rowSet", 0)
119
+ return unless headers && row
120
+
121
+ build_team_season_rank(headers.zip(row).to_h)
122
+ end
123
+ private_class_method :parse_ranks_response
124
+
125
+ # Parses the API response into available seasons
126
+ #
127
+ # @api private
128
+ # @return [Collection] collection of season IDs
129
+ def self.parse_seasons_response(response)
130
+ return Collection.new unless response
131
+
132
+ data = JSON.parse(response)
133
+ result_set = find_result_set(data, AVAILABLE_SEASONS)
134
+ return Collection.new unless result_set
135
+
136
+ rows = result_set["rowSet"]
137
+ return Collection.new unless rows
138
+
139
+ Collection.new(rows.map(&:first))
140
+ end
141
+ private_class_method :parse_seasons_response
142
+
143
+ # Finds a result set by name
144
+ #
145
+ # @api private
146
+ # @return [Hash, nil] the result set hash or nil if not found
147
+ def self.find_result_set(data, result_set_name)
148
+ result_sets = data["resultSets"]
149
+ return unless result_sets
150
+
151
+ result_sets.find { |rs| rs["name"].eql?(result_set_name) }
152
+ end
153
+ private_class_method :find_result_set
154
+
155
+ # Builds a team info object from API data
156
+ # @api private
157
+ # @return [TeamInfo] the team info object
158
+ def self.build_team_info(data)
159
+ TeamInfo.new(team_id: data["TEAM_ID"], team_city: data["TEAM_CITY"], team_name: data["TEAM_NAME"],
160
+ team_abbreviation: data["TEAM_ABBREVIATION"], team_conference: data["TEAM_CONFERENCE"],
161
+ team_division: data["TEAM_DIVISION"], team_code: data["TEAM_CODE"], team_slug: data["TEAM_SLUG"],
162
+ w: data["W"], l: data["L"], pct: data["PCT"], conf_rank: data["CONF_RANK"], div_rank: data["DIV_RANK"],
163
+ min_year: data["MIN_YEAR"], max_year: data["MAX_YEAR"], season_year: data["SEASON_YEAR"])
164
+ end
165
+ private_class_method :build_team_info
166
+
167
+ # Builds a team season rank object from API data
168
+ # @api private
169
+ # @return [TeamSeasonRank] the team season rank object
170
+ def self.build_team_season_rank(data)
171
+ TeamSeasonRank.new(league_id: data["LEAGUE_ID"], season_id: data["SEASON_ID"], team_id: data["TEAM_ID"],
172
+ pts_rank: data["PTS_RANK"], pts_pg: data["PTS_PG"], reb_rank: data["REB_RANK"], reb_pg: data["REB_PG"],
173
+ ast_rank: data["AST_RANK"], ast_pg: data["AST_PG"], opp_pts_rank: data["OPP_PTS_RANK"], opp_pts_pg: data["OPP_PTS_PG"])
174
+ end
175
+ private_class_method :build_team_season_rank
176
+ end
177
+ end