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.
- checksums.yaml +5 -5
- data/AGENTS.md +362 -0
- data/CHANGELOG.md +169 -0
- data/CLAUDE.md +1 -0
- data/LICENSE +21 -0
- data/README.md +501 -101
- data/bin/console +10 -0
- data/bin/setup +6 -0
- data/exe/nba +8 -0
- data/lib/nba/all_time_leader.rb +77 -0
- data/lib/nba/all_time_leaders.rb +185 -0
- data/lib/nba/assist_leader.rb +92 -0
- data/lib/nba/assist_leaders.rb +64 -0
- data/lib/nba/assist_tracker.rb +108 -0
- data/lib/nba/assist_tracker_entry.rb +206 -0
- data/lib/nba/award.rb +128 -0
- data/lib/nba/box_score.rb +2 -0
- data/lib/nba/box_score_advanced.rb +114 -0
- data/lib/nba/box_score_advanced_player_stat.rb +297 -0
- data/lib/nba/box_score_advanced_team_stat.rb +237 -0
- data/lib/nba/box_score_advanced_v3.rb +124 -0
- data/lib/nba/box_score_defensive_player_stat.rb +281 -0
- data/lib/nba/box_score_defensive_team_stat.rb +85 -0
- data/lib/nba/box_score_defensive_v2.rb +190 -0
- data/lib/nba/box_score_four_factors.rb +91 -0
- data/lib/nba/box_score_four_factors_player_stat.rb +185 -0
- data/lib/nba/box_score_four_factors_team_stat.rb +141 -0
- data/lib/nba/box_score_four_factors_v3.rb +133 -0
- data/lib/nba/box_score_hustle.rb +226 -0
- data/lib/nba/box_score_hustle_player_stat.rb +233 -0
- data/lib/nba/box_score_hustle_team_stat.rb +189 -0
- data/lib/nba/box_score_matchup_stat.rb +417 -0
- data/lib/nba/box_score_matchups_v3.rb +184 -0
- data/lib/nba/box_score_misc.rb +100 -0
- data/lib/nba/box_score_misc_player_stat.rb +217 -0
- data/lib/nba/box_score_misc_team_stat.rb +173 -0
- data/lib/nba/box_score_misc_v3.rb +163 -0
- data/lib/nba/box_score_player_stat.rb +273 -0
- data/lib/nba/box_score_player_track.rb +223 -0
- data/lib/nba/box_score_player_track_stat.rb +273 -0
- data/lib/nba/box_score_player_track_team_stat.rb +229 -0
- data/lib/nba/box_score_scoring.rb +103 -0
- data/lib/nba/box_score_scoring_player_stat.rb +241 -0
- data/lib/nba/box_score_scoring_team_stat.rb +197 -0
- data/lib/nba/box_score_scoring_v3.rb +170 -0
- data/lib/nba/box_score_similarity_score.rb +119 -0
- data/lib/nba/box_score_similarity_stat.rb +76 -0
- data/lib/nba/box_score_starter_bench_stat.rb +257 -0
- data/lib/nba/box_score_summary.rb +285 -0
- data/lib/nba/box_score_summary_v2.rb +202 -0
- data/lib/nba/box_score_summary_v3.rb +120 -0
- data/lib/nba/box_score_summary_v3_data.rb +419 -0
- data/lib/nba/box_score_team_stat.rb +229 -0
- data/lib/nba/box_score_traditional.rb +101 -0
- data/lib/nba/box_score_traditional_v3.rb +195 -0
- data/lib/nba/box_score_usage.rb +102 -0
- data/lib/nba/box_score_usage_player_stat.rb +265 -0
- data/lib/nba/box_score_usage_team_stat.rb +221 -0
- data/lib/nba/box_score_usage_v3.rb +169 -0
- data/lib/nba/box_score_v3_helpers.rb +144 -0
- data/lib/nba/career_stats.rb +217 -0
- data/lib/nba/cli/display/player_display.rb +98 -0
- data/lib/nba/cli/display.rb +178 -0
- data/lib/nba/cli/formatters/game_formatters.rb +86 -0
- data/lib/nba/cli/formatters/leaders_formatters.rb +26 -0
- data/lib/nba/cli/formatters/player_formatters.rb +52 -0
- data/lib/nba/cli/formatters/standings_formatters.rb +26 -0
- data/lib/nba/cli/formatters/team_formatters.rb +67 -0
- data/lib/nba/cli/formatters/time_formatters.rb +82 -0
- data/lib/nba/cli/formatters.rb +56 -0
- data/lib/nba/cli/helpers.rb +135 -0
- data/lib/nba/cli.rb +171 -20
- data/lib/nba/client.rb +35 -0
- data/lib/nba/collection.rb +89 -0
- data/lib/nba/college_player_stat.rb +200 -0
- data/lib/nba/common_player_info.rb +142 -0
- data/lib/nba/common_playoff_series.rb +90 -0
- data/lib/nba/common_team_years.rb +113 -0
- data/lib/nba/conference.rb +39 -0
- data/lib/nba/connection.rb +84 -0
- data/lib/nba/cume_stats_player.rb +358 -0
- data/lib/nba/cume_stats_player_game.rb +217 -0
- data/lib/nba/cume_stats_player_games.rb +99 -0
- data/lib/nba/cume_stats_player_games_entry.rb +25 -0
- data/lib/nba/cume_stats_player_total.rb +481 -0
- data/lib/nba/cume_stats_team.rb +349 -0
- data/lib/nba/cume_stats_team_games.rb +145 -0
- data/lib/nba/cume_stats_team_games_entry.rb +25 -0
- data/lib/nba/cume_stats_team_player.rb +485 -0
- data/lib/nba/cume_stats_team_total.rb +267 -0
- data/lib/nba/data.rb +73 -0
- data/lib/nba/defense_hub.rb +109 -0
- data/lib/nba/defense_hub_stat.rb +57 -0
- data/lib/nba/defensive_shot_stat.rb +102 -0
- data/lib/nba/division.rb +49 -0
- data/lib/nba/draft_board.rb +126 -0
- data/lib/nba/draft_board_pick.rb +173 -0
- data/lib/nba/draft_combine_anthro_measurement.rb +163 -0
- data/lib/nba/draft_combine_drill_result.rb +115 -0
- data/lib/nba/draft_combine_drill_results.rb +112 -0
- data/lib/nba/draft_combine_non_stationary_shooting.rb +268 -0
- data/lib/nba/draft_combine_non_stationary_shooting_result.rb +355 -0
- data/lib/nba/draft_combine_player_anthro.rb +133 -0
- data/lib/nba/draft_combine_spot_shooting.rb +243 -0
- data/lib/nba/draft_combine_spot_shooting_result.rb +419 -0
- data/lib/nba/draft_combine_stat.rb +211 -0
- data/lib/nba/draft_combine_stats.rb +160 -0
- data/lib/nba/draft_history.rb +142 -0
- data/lib/nba/draft_pick.rb +154 -0
- data/lib/nba/dunk_score_leader.rb +93 -0
- data/lib/nba/dunk_score_leaders.rb +77 -0
- data/lib/nba/estimated_metrics_stat.rb +152 -0
- data/lib/nba/fantasy_profile_stat.rb +142 -0
- data/lib/nba/fantasy_widget.rb +72 -0
- data/lib/nba/fantasy_widget_player.rb +98 -0
- data/lib/nba/found_game.rb +260 -0
- data/lib/nba/franchise.rb +136 -0
- data/lib/nba/franchise_history.rb +142 -0
- data/lib/nba/franchise_leader.rb +147 -0
- data/lib/nba/franchise_leaders.rb +162 -0
- data/lib/nba/franchise_player.rb +224 -0
- data/lib/nba/franchise_players.rb +147 -0
- data/lib/nba/game.rb +80 -64
- data/lib/nba/game_log.rb +349 -0
- data/lib/nba/game_rotation.rb +152 -0
- data/lib/nba/game_streak.rb +102 -0
- data/lib/nba/games.rb +46 -0
- data/lib/nba/home_page_leader.rb +99 -0
- data/lib/nba/home_page_leaders.rb +75 -0
- data/lib/nba/home_page_stat.rb +57 -0
- data/lib/nba/home_page_v2.rb +110 -0
- data/lib/nba/hustle_stats_box_score.rb +182 -0
- data/lib/nba/infographic_fan_duel_player.rb +139 -0
- data/lib/nba/infographic_fan_duel_player_stat.rb +311 -0
- data/lib/nba/ist_standing.rb +167 -0
- data/lib/nba/ist_standings.rb +81 -0
- data/lib/nba/leader.rb +103 -0
- data/lib/nba/leaders.rb +110 -0
- data/lib/nba/leaders_tile.rb +57 -0
- data/lib/nba/leaders_tiles.rb +90 -0
- data/lib/nba/league.rb +37 -0
- data/lib/nba/league_dash_lineup_stat.rb +270 -0
- data/lib/nba/league_dash_lineups.rb +177 -0
- data/lib/nba/league_dash_opp_pt_shot.rb +150 -0
- data/lib/nba/league_dash_player_bio_stat.rb +217 -0
- data/lib/nba/league_dash_player_bio_stats.rb +164 -0
- data/lib/nba/league_dash_player_clutch.rb +212 -0
- data/lib/nba/league_dash_player_clutch_stat.rb +271 -0
- data/lib/nba/league_dash_player_pt_shot.rb +152 -0
- data/lib/nba/league_dash_player_pt_shot_stat.rb +193 -0
- data/lib/nba/league_dash_player_shot_location_stat.rb +265 -0
- data/lib/nba/league_dash_player_shot_locations.rb +210 -0
- data/lib/nba/league_dash_player_stat.rb +306 -0
- data/lib/nba/league_dash_player_stats.rb +176 -0
- data/lib/nba/league_dash_pt_defend.rb +160 -0
- data/lib/nba/league_dash_pt_defend_stat.rb +145 -0
- data/lib/nba/league_dash_pt_stats.rb +152 -0
- data/lib/nba/league_dash_pt_stats_stat.rb +169 -0
- data/lib/nba/league_dash_pt_team_defend.rb +158 -0
- data/lib/nba/league_dash_pt_team_defend_stat.rb +110 -0
- data/lib/nba/league_dash_team_clutch.rb +211 -0
- data/lib/nba/league_dash_team_clutch_stat.rb +237 -0
- data/lib/nba/league_dash_team_pt_shot.rb +150 -0
- data/lib/nba/league_dash_team_pt_shot_stat.rb +166 -0
- data/lib/nba/league_dash_team_shot_location_stat.rb +230 -0
- data/lib/nba/league_dash_team_shot_locations.rb +208 -0
- data/lib/nba/league_dash_team_stat.rb +275 -0
- data/lib/nba/league_dash_team_stats.rb +172 -0
- data/lib/nba/league_game_finder.rb +170 -0
- data/lib/nba/league_game_log.rb +224 -0
- data/lib/nba/league_hustle_stats_player.rb +161 -0
- data/lib/nba/league_hustle_stats_player_stat.rb +253 -0
- data/lib/nba/league_hustle_stats_team.rb +157 -0
- data/lib/nba/league_hustle_stats_team_stat.rb +179 -0
- data/lib/nba/league_lineup_viz.rb +184 -0
- data/lib/nba/league_lineup_viz_stat.rb +214 -0
- data/lib/nba/league_player_on_details.rb +175 -0
- data/lib/nba/league_player_on_details_stat.rb +313 -0
- data/lib/nba/league_season_matchup_stat.rb +241 -0
- data/lib/nba/league_season_matchups.rb +181 -0
- data/lib/nba/league_standing.rb +284 -0
- data/lib/nba/league_standings.rb +159 -0
- data/lib/nba/league_wide_shot_stat.rb +62 -0
- data/lib/nba/live_action.rb +240 -0
- data/lib/nba/live_box_score.rb +143 -0
- data/lib/nba/live_connection.rb +84 -0
- data/lib/nba/live_game.rb +230 -0
- data/lib/nba/live_play_by_play.rb +120 -0
- data/lib/nba/live_player_stat.rb +276 -0
- data/lib/nba/live_scoreboard.rb +102 -0
- data/lib/nba/matchup_rollup.rb +98 -0
- data/lib/nba/matchups_rollup.rb +81 -0
- data/lib/nba/pass_stat.rb +209 -0
- data/lib/nba/play.rb +258 -0
- data/lib/nba/play_by_play.rb +85 -0
- data/lib/nba/play_by_play_v3.rb +91 -0
- data/lib/nba/play_type_stat.rb +206 -0
- data/lib/nba/player.rb +242 -24
- data/lib/nba/player_awards.rb +110 -0
- data/lib/nba/player_career_by_college.rb +86 -0
- data/lib/nba/player_career_by_college_rollup.rb +143 -0
- data/lib/nba/player_career_stats.rb +77 -0
- data/lib/nba/player_compare.rb +156 -0
- data/lib/nba/player_comparison_stat.rb +242 -0
- data/lib/nba/player_dash_pt_pass.rb +164 -0
- data/lib/nba/player_dash_pt_reb.rb +235 -0
- data/lib/nba/player_dash_pt_shot_defend.rb +119 -0
- data/lib/nba/player_dash_pt_shots.rb +279 -0
- data/lib/nba/player_dashboard.rb +259 -0
- data/lib/nba/player_dashboard_stat.rb +248 -0
- data/lib/nba/player_estimated_metrics.rb +84 -0
- data/lib/nba/player_fantasy_profile_bar_graph.rb +147 -0
- data/lib/nba/player_game_log.rb +72 -0
- data/lib/nba/player_game_logs.rb +117 -0
- data/lib/nba/player_game_streak_finder.rb +108 -0
- data/lib/nba/player_index.rb +135 -0
- data/lib/nba/player_index_entry.rb +266 -0
- data/lib/nba/player_info.rb +225 -0
- data/lib/nba/player_next_n_games.rb +64 -0
- data/lib/nba/player_profile_v2.rb +169 -0
- data/lib/nba/player_vs_player.rb +153 -0
- data/lib/nba/players.rb +107 -0
- data/lib/nba/playoff_matchup.rb +84 -0
- data/lib/nba/playoff_picture.rb +98 -0
- data/lib/nba/playoff_series.rb +76 -0
- data/lib/nba/position.rb +48 -0
- data/lib/nba/rebound_stat.rb +189 -0
- data/lib/nba/response_parser.rb +116 -0
- data/lib/nba/roster.rb +74 -0
- data/lib/nba/rotation_entry.rb +154 -0
- data/lib/nba/schedule.rb +183 -0
- data/lib/nba/schedule_international.rb +182 -0
- data/lib/nba/scheduled_game.rb +240 -0
- data/lib/nba/scoreboard.rb +183 -0
- data/lib/nba/scoreboard_v3.rb +104 -0
- data/lib/nba/shot.rb +208 -0
- data/lib/nba/shot_chart.rb +75 -0
- data/lib/nba/shot_chart_league_wide.rb +102 -0
- data/lib/nba/shot_chart_lineup_detail.rb +109 -0
- data/lib/nba/shot_stat.rb +174 -0
- data/lib/nba/standing.rb +129 -0
- data/lib/nba/standings.rb +75 -0
- data/lib/nba/static.rb +107 -0
- data/lib/nba/synergy_play_types.rb +211 -0
- data/lib/nba/team.rb +203 -127
- data/lib/nba/team_and_players_vs_players.rb +227 -0
- data/lib/nba/team_and_players_vs_players_stat.rb +155 -0
- data/lib/nba/team_dash_pt_pass.rb +157 -0
- data/lib/nba/team_dash_pt_reb.rb +216 -0
- data/lib/nba/team_dash_pt_shots.rb +244 -0
- data/lib/nba/team_dashboard.rb +275 -0
- data/lib/nba/team_dashboard_stat.rb +248 -0
- data/lib/nba/team_detail.rb +117 -0
- data/lib/nba/team_details.rb +173 -0
- data/lib/nba/team_estimated_metrics.rb +91 -0
- data/lib/nba/team_estimated_metrics_stat.rb +146 -0
- data/lib/nba/team_game_log.rb +143 -0
- data/lib/nba/team_game_log_entry.rb +246 -0
- data/lib/nba/team_game_log_stat.rb +275 -0
- data/lib/nba/team_game_logs.rb +163 -0
- data/lib/nba/team_game_streak.rb +111 -0
- data/lib/nba/team_game_streak_finder.rb +109 -0
- data/lib/nba/team_historical_leader.rb +207 -0
- data/lib/nba/team_historical_leaders.rb +98 -0
- data/lib/nba/team_historical_record.rb +139 -0
- data/lib/nba/team_info.rb +150 -0
- data/lib/nba/team_info_common.rb +177 -0
- data/lib/nba/team_on_off_overall_stat.rb +477 -0
- data/lib/nba/team_on_off_player_stat.rb +523 -0
- data/lib/nba/team_on_off_player_summary.rb +135 -0
- data/lib/nba/team_pass_stat.rb +183 -0
- data/lib/nba/team_player_dashboard.rb +212 -0
- data/lib/nba/team_player_on_off_details.rb +218 -0
- data/lib/nba/team_player_on_off_summary.rb +214 -0
- data/lib/nba/team_player_stat.rb +275 -0
- data/lib/nba/team_rebound_stat.rb +189 -0
- data/lib/nba/team_season_rank.rb +110 -0
- data/lib/nba/team_shot_stat.rb +173 -0
- data/lib/nba/team_vs_player.rb +151 -0
- data/lib/nba/team_vs_player_stat.rb +157 -0
- data/lib/nba/team_year.rb +55 -0
- data/lib/nba/team_year_by_year_stats.rb +152 -0
- data/lib/nba/team_year_stat.rb +282 -0
- data/lib/nba/teams.rb +33 -0
- data/lib/nba/upcoming_game.rb +115 -0
- data/lib/nba/utils.rb +94 -0
- data/lib/nba/version.rb +5 -2
- data/lib/nba/video_detail.rb +103 -0
- data/lib/nba/video_details.rb +118 -0
- data/lib/nba/video_details_asset.rb +115 -0
- data/lib/nba/video_details_asset_entry.rb +91 -0
- data/lib/nba/video_event.rb +83 -0
- data/lib/nba/video_event_asset.rb +91 -0
- data/lib/nba/video_events.rb +106 -0
- data/lib/nba/video_events_asset.rb +107 -0
- data/lib/nba/video_status.rb +129 -0
- data/lib/nba/video_status_entry.rb +161 -0
- data/lib/nba/vs_player_stat.rb +156 -0
- data/lib/nba/win_probability.rb +117 -0
- data/lib/nba/win_probability_point.rb +140 -0
- data/lib/nba.rb +249 -5
- data/sig/equalizer.rbs +3 -0
- data/sig/nba.rbs +7297 -0
- data/sig/shale.rbs +24 -0
- data/sig/thor.rbs +19 -0
- metadata +324 -95
- data/.gitignore +0 -18
- data/.travis.yml +0 -22
- data/Gemfile +0 -23
- data/LICENSE.md +0 -22
- data/Rakefile +0 -18
- data/bin/nba +0 -7
- data/cache/teams.json +0 -16529
- data/lib/faraday_middleware/scrape_game.rb +0 -41
- data/lib/nba/request.rb +0 -37
- data/nba.gemspec +0 -28
- data/spec/fixtures/games.html +0 -785
- data/spec/fixtures/teams.json +0 -16529
- data/spec/game_spec.rb +0 -40
- data/spec/spec_helper.rb +0 -25
- data/spec/team_spec.rb +0 -93
data/lib/nba/leaders.rb
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "leader"
|
|
5
|
+
require_relative "response_parser"
|
|
6
|
+
require_relative "utils"
|
|
7
|
+
|
|
8
|
+
module NBA
|
|
9
|
+
# Provides methods to retrieve NBA statistical leaders
|
|
10
|
+
module Leaders
|
|
11
|
+
# Points per game category
|
|
12
|
+
# @return [String] the category code
|
|
13
|
+
PTS = "PTS".freeze
|
|
14
|
+
# Rebounds per game category
|
|
15
|
+
# @return [String] the category code
|
|
16
|
+
REB = "REB".freeze
|
|
17
|
+
# Assists per game category
|
|
18
|
+
# @return [String] the category code
|
|
19
|
+
AST = "AST".freeze
|
|
20
|
+
# Steals per game category
|
|
21
|
+
# @return [String] the category code
|
|
22
|
+
STL = "STL".freeze
|
|
23
|
+
# Blocks per game category
|
|
24
|
+
# @return [String] the category code
|
|
25
|
+
BLK = "BLK".freeze
|
|
26
|
+
# Field goal percentage category
|
|
27
|
+
# @return [String] the category code
|
|
28
|
+
FG_PCT = "FG_PCT".freeze
|
|
29
|
+
# Three point percentage category
|
|
30
|
+
# @return [String] the category code
|
|
31
|
+
FG3_PCT = "FG3_PCT".freeze
|
|
32
|
+
# Free throw percentage category
|
|
33
|
+
# @return [String] the category code
|
|
34
|
+
FT_PCT = "FT_PCT".freeze
|
|
35
|
+
# Efficiency category
|
|
36
|
+
# @return [String] the category code
|
|
37
|
+
EFF = "EFF".freeze
|
|
38
|
+
|
|
39
|
+
# Categories that require Totals mode
|
|
40
|
+
PERCENTAGE_CATEGORIES = [FG_PCT, FG3_PCT, FT_PCT].freeze
|
|
41
|
+
private_constant :PERCENTAGE_CATEGORIES
|
|
42
|
+
|
|
43
|
+
# Retrieves league leaders for a statistical category
|
|
44
|
+
#
|
|
45
|
+
# @api public
|
|
46
|
+
# @example
|
|
47
|
+
# leaders = NBA::Leaders.find(category: NBA::Leaders::PTS)
|
|
48
|
+
# leaders.each { |leader| puts "#{leader.rank}. #{leader.player_name}: #{leader.value}" }
|
|
49
|
+
# @param category [String] the statistical category (PTS, REB, AST, etc.)
|
|
50
|
+
# @param season [Integer] the season year (defaults to current season)
|
|
51
|
+
# @param season_type [String] the season type (Regular Season, Playoffs)
|
|
52
|
+
# @param limit [Integer] the number of results to return (defaults to 10)
|
|
53
|
+
# @param client [Client] the API client to use
|
|
54
|
+
# @return [Collection] a collection of leaders
|
|
55
|
+
def self.find(category:, season: Utils.current_season, season_type: "Regular Season", limit: 10, client: CLIENT)
|
|
56
|
+
per_mode = PERCENTAGE_CATEGORIES.include?(category) ? "Totals" : "PerGame"
|
|
57
|
+
path = "leagueleaders?LeagueID=00&PerMode=#{per_mode}&Scope=S&Season=#{Utils.format_season(season)}" \
|
|
58
|
+
"&SeasonType=#{season_type}&StatCategory=#{category}"
|
|
59
|
+
parse_leaders_response(client.get(path), category, limit)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Parses the leaders API response (uses resultSet instead of resultSets)
|
|
63
|
+
#
|
|
64
|
+
# @api private
|
|
65
|
+
# @param response [String] the JSON response body
|
|
66
|
+
# @param category [String] the category requested
|
|
67
|
+
# @param limit [Integer] the limit of results
|
|
68
|
+
# @return [Collection] a collection of leaders
|
|
69
|
+
def self.parse_leaders_response(response, category, limit)
|
|
70
|
+
headers, rows = extract_result_set(response)
|
|
71
|
+
return Collection.new unless headers && rows
|
|
72
|
+
|
|
73
|
+
leaders = rows.take(limit).map do |row|
|
|
74
|
+
build_leader(ResponseParser.zip_to_hash(headers, row), category)
|
|
75
|
+
end
|
|
76
|
+
Collection.new(leaders)
|
|
77
|
+
end
|
|
78
|
+
private_class_method :parse_leaders_response
|
|
79
|
+
|
|
80
|
+
# Extracts result set from API response
|
|
81
|
+
# @api private
|
|
82
|
+
# @return [Array, nil]
|
|
83
|
+
def self.extract_result_set(response)
|
|
84
|
+
return unless response
|
|
85
|
+
|
|
86
|
+
result_set = JSON.parse(response)["resultSet"]
|
|
87
|
+
return unless result_set
|
|
88
|
+
|
|
89
|
+
[result_set["headers"], result_set["rowSet"]]
|
|
90
|
+
end
|
|
91
|
+
private_class_method :extract_result_set
|
|
92
|
+
|
|
93
|
+
# Builds a leader from API data
|
|
94
|
+
# @api private
|
|
95
|
+
# @return [Leader]
|
|
96
|
+
def self.build_leader(data, category)
|
|
97
|
+
Leader.new(**leader_identity(data), category: category, rank: data["RANK"], value: data[category])
|
|
98
|
+
end
|
|
99
|
+
private_class_method :build_leader
|
|
100
|
+
|
|
101
|
+
# Extracts leader identity attributes from data
|
|
102
|
+
# @api private
|
|
103
|
+
# @return [Hash]
|
|
104
|
+
def self.leader_identity(data)
|
|
105
|
+
{player_id: data["PLAYER_ID"], player_name: data["PLAYER"],
|
|
106
|
+
team_id: data["TEAM_ID"], team_abbreviation: data["TEAM"]}
|
|
107
|
+
end
|
|
108
|
+
private_class_method :leader_identity
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require "equalizer"
|
|
2
|
+
require "shale"
|
|
3
|
+
|
|
4
|
+
module NBA
|
|
5
|
+
# Represents a leaders tile entry
|
|
6
|
+
#
|
|
7
|
+
# @api public
|
|
8
|
+
# @example
|
|
9
|
+
# tile.rank #=> 1
|
|
10
|
+
# tile.team_abbreviation #=> "BOS"
|
|
11
|
+
# tile.pts #=> 120.5
|
|
12
|
+
class LeadersTile < Shale::Mapper
|
|
13
|
+
include Equalizer.new(:rank, :team_id)
|
|
14
|
+
|
|
15
|
+
# Returns the rank
|
|
16
|
+
# @api public
|
|
17
|
+
# @example
|
|
18
|
+
# tile.rank #=> 1
|
|
19
|
+
# @return [Integer, nil] the rank
|
|
20
|
+
attribute :rank, Shale::Type::Integer
|
|
21
|
+
|
|
22
|
+
# Returns the team ID
|
|
23
|
+
# @api public
|
|
24
|
+
# @example
|
|
25
|
+
# tile.team_id #=> 1610612738
|
|
26
|
+
# @return [Integer, nil] the team ID
|
|
27
|
+
attribute :team_id, Shale::Type::Integer
|
|
28
|
+
|
|
29
|
+
# Returns the team abbreviation
|
|
30
|
+
# @api public
|
|
31
|
+
# @example
|
|
32
|
+
# tile.team_abbreviation #=> "BOS"
|
|
33
|
+
# @return [String, nil] the team abbreviation
|
|
34
|
+
attribute :team_abbreviation, Shale::Type::String
|
|
35
|
+
|
|
36
|
+
# Returns the team name
|
|
37
|
+
# @api public
|
|
38
|
+
# @example
|
|
39
|
+
# tile.team_name #=> "Boston Celtics"
|
|
40
|
+
# @return [String, nil] the team name
|
|
41
|
+
attribute :team_name, Shale::Type::String
|
|
42
|
+
|
|
43
|
+
# Returns points
|
|
44
|
+
# @api public
|
|
45
|
+
# @example
|
|
46
|
+
# tile.pts #=> 120.5
|
|
47
|
+
# @return [Float, nil] points
|
|
48
|
+
attribute :pts, Shale::Type::Float
|
|
49
|
+
|
|
50
|
+
# Returns season year (for all-time/low records)
|
|
51
|
+
# @api public
|
|
52
|
+
# @example
|
|
53
|
+
# tile.season_year #=> "2023-24"
|
|
54
|
+
# @return [String, nil] season year (for all-time/low records)
|
|
55
|
+
attribute :season_year, Shale::Type::String
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "leaders_tile"
|
|
5
|
+
require_relative "league"
|
|
6
|
+
require_relative "response_parser"
|
|
7
|
+
require_relative "utils"
|
|
8
|
+
|
|
9
|
+
module NBA
|
|
10
|
+
# Provides methods to retrieve NBA leaders tiles statistics
|
|
11
|
+
module LeadersTiles
|
|
12
|
+
# Result set categories available in leaders tiles
|
|
13
|
+
RESULT_SETS = {
|
|
14
|
+
leaders: "LeadersTiles",
|
|
15
|
+
all_time_high: "AllTimeSeasonHigh",
|
|
16
|
+
last_season_high: "LastSeasonHigh",
|
|
17
|
+
low_season_high: "LowSeasonHigh"
|
|
18
|
+
}.freeze
|
|
19
|
+
|
|
20
|
+
# Retrieves leaders tiles for a result set category
|
|
21
|
+
#
|
|
22
|
+
# @api public
|
|
23
|
+
# @example
|
|
24
|
+
# tiles = NBA::LeadersTiles.all(result_set: :leaders, season: 2023)
|
|
25
|
+
# tiles.each { |t| puts "#{t.rank}. #{t.team_abbreviation}: #{t.pts}" }
|
|
26
|
+
# @param result_set [Symbol] the result set (:leaders, :all_time_high, etc.)
|
|
27
|
+
# @param season [Integer] the season year (defaults to current season)
|
|
28
|
+
# @param season_type [String] the season type (Regular Season, Playoffs, etc.)
|
|
29
|
+
# @param game_scope [String] the game scope (Season, Yesterday, etc.)
|
|
30
|
+
# @param player_or_team [String] player or team stats (Player, Team)
|
|
31
|
+
# @param player_scope [String] the player scope (All Players, Rookies)
|
|
32
|
+
# @param stat [String] the stat type (PTS, REB, AST, etc.)
|
|
33
|
+
# @param league [String, League] the league ID or League object
|
|
34
|
+
# @param client [Client] the API client to use
|
|
35
|
+
# @return [Collection] a collection of leaders tiles
|
|
36
|
+
def self.all(result_set: :leaders, season: Utils.current_season,
|
|
37
|
+
season_type: "Regular Season", game_scope: "Season", player_or_team: "Team",
|
|
38
|
+
player_scope: "All Players", stat: "PTS", league: League::NBA, client: CLIENT)
|
|
39
|
+
result_set_name = RESULT_SETS.fetch(result_set)
|
|
40
|
+
league_id = Utils.extract_league_id(league)
|
|
41
|
+
opts = {season: season, season_type: season_type, game_scope: game_scope,
|
|
42
|
+
player_or_team: player_or_team, player_scope: player_scope,
|
|
43
|
+
stat: stat, league_id: league_id}
|
|
44
|
+
response = client.get(build_path(opts))
|
|
45
|
+
parse_response(response, result_set_name)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Builds the API request path
|
|
49
|
+
# @api private
|
|
50
|
+
# @return [String] the request path
|
|
51
|
+
def self.build_path(opts)
|
|
52
|
+
"leaderstiles?GameScope=#{opts[:game_scope]}&LeagueID=#{opts[:league_id]}" \
|
|
53
|
+
"&PlayerOrTeam=#{opts[:player_or_team]}&PlayerScope=#{opts[:player_scope]}" \
|
|
54
|
+
"&Season=#{Utils.format_season(opts[:season])}&SeasonType=#{opts[:season_type]}" \
|
|
55
|
+
"&Stat=#{opts[:stat]}"
|
|
56
|
+
end
|
|
57
|
+
private_class_method :build_path
|
|
58
|
+
|
|
59
|
+
# Parses the API response
|
|
60
|
+
# @api private
|
|
61
|
+
# @param response [String, nil] the raw API response
|
|
62
|
+
# @param result_set_name [String] the result set name
|
|
63
|
+
# @return [Collection] parsed tiles
|
|
64
|
+
def self.parse_response(response, result_set_name)
|
|
65
|
+
ResponseParser.parse(response, result_set: result_set_name) { |data| build_tile(data) }
|
|
66
|
+
end
|
|
67
|
+
private_class_method :parse_response
|
|
68
|
+
|
|
69
|
+
# Builds a LeadersTile object from raw data
|
|
70
|
+
# @api private
|
|
71
|
+
# @param data [Hash] the row data
|
|
72
|
+
# @return [LeadersTile] the tile object
|
|
73
|
+
def self.build_tile(data)
|
|
74
|
+
LeadersTile.new(**tile_attributes(data))
|
|
75
|
+
end
|
|
76
|
+
private_class_method :build_tile
|
|
77
|
+
|
|
78
|
+
# Extracts tile attributes from data
|
|
79
|
+
# @api private
|
|
80
|
+
# @param data [Hash] the row data
|
|
81
|
+
# @return [Hash] tile attributes
|
|
82
|
+
def self.tile_attributes(data)
|
|
83
|
+
{rank: data["RANK"], team_id: data["TEAM_ID"],
|
|
84
|
+
team_abbreviation: data["TEAM_ABBREVIATION"],
|
|
85
|
+
team_name: data["TEAM_NAME"], pts: data["PTS"],
|
|
86
|
+
season_year: data["SEASON_YEAR"]}
|
|
87
|
+
end
|
|
88
|
+
private_class_method :tile_attributes
|
|
89
|
+
end
|
|
90
|
+
end
|
data/lib/nba/league.rb
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require "equalizer"
|
|
2
|
+
require "shale"
|
|
3
|
+
|
|
4
|
+
module NBA
|
|
5
|
+
# Represents a basketball league
|
|
6
|
+
class League < Shale::Mapper
|
|
7
|
+
include Equalizer.new(:id)
|
|
8
|
+
|
|
9
|
+
# NBA league ID
|
|
10
|
+
# @return [String] the NBA league ID
|
|
11
|
+
NBA = "00".freeze
|
|
12
|
+
|
|
13
|
+
# WNBA league ID
|
|
14
|
+
# @return [String] the WNBA league ID
|
|
15
|
+
WNBA = "10".freeze
|
|
16
|
+
|
|
17
|
+
# G League (NBA Development League) ID
|
|
18
|
+
# @return [String] the G League ID
|
|
19
|
+
G_LEAGUE = "20".freeze
|
|
20
|
+
|
|
21
|
+
# @!attribute [rw] id
|
|
22
|
+
# Returns the unique identifier for the league
|
|
23
|
+
# @api public
|
|
24
|
+
# @example
|
|
25
|
+
# league.id #=> "00"
|
|
26
|
+
# @return [String] the unique identifier for the league
|
|
27
|
+
attribute :id, Shale::Type::String
|
|
28
|
+
|
|
29
|
+
# @!attribute [rw] name
|
|
30
|
+
# Returns the name of the league
|
|
31
|
+
# @api public
|
|
32
|
+
# @example
|
|
33
|
+
# league.name #=> "NBA"
|
|
34
|
+
# @return [String] the name of the league
|
|
35
|
+
attribute :name, Shale::Type::String
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
require "equalizer"
|
|
2
|
+
require "shale"
|
|
3
|
+
require_relative "teams"
|
|
4
|
+
|
|
5
|
+
module NBA
|
|
6
|
+
# Represents a lineup's league dashboard statistics
|
|
7
|
+
#
|
|
8
|
+
# @api public
|
|
9
|
+
class LeagueDashLineupStat < Shale::Mapper
|
|
10
|
+
include Equalizer.new(:group_id, :team_id)
|
|
11
|
+
|
|
12
|
+
# @!attribute [rw] group_set
|
|
13
|
+
# Returns the group set (e.g., "5-man lineups")
|
|
14
|
+
# @api public
|
|
15
|
+
# @example
|
|
16
|
+
# stat.group_set #=> "5 Man Lineups"
|
|
17
|
+
# @return [String, nil] the group set
|
|
18
|
+
attribute :group_set, Shale::Type::String
|
|
19
|
+
|
|
20
|
+
# @!attribute [rw] group_id
|
|
21
|
+
# Returns the lineup group ID
|
|
22
|
+
# @api public
|
|
23
|
+
# @example
|
|
24
|
+
# stat.group_id #=> "201939-203110-1628369"
|
|
25
|
+
# @return [String, nil] the group ID
|
|
26
|
+
attribute :group_id, Shale::Type::String
|
|
27
|
+
|
|
28
|
+
# @!attribute [rw] group_name
|
|
29
|
+
# Returns the lineup group name
|
|
30
|
+
# @api public
|
|
31
|
+
# @example
|
|
32
|
+
# stat.group_name #=> "S. Curry - K. Thompson - A. Wiggins"
|
|
33
|
+
# @return [String, nil] the group name
|
|
34
|
+
attribute :group_name, Shale::Type::String
|
|
35
|
+
|
|
36
|
+
# @!attribute [rw] team_id
|
|
37
|
+
# Returns the team ID
|
|
38
|
+
# @api public
|
|
39
|
+
# @example
|
|
40
|
+
# stat.team_id #=> 1610612744
|
|
41
|
+
# @return [Integer, nil] the team ID
|
|
42
|
+
attribute :team_id, Shale::Type::Integer
|
|
43
|
+
|
|
44
|
+
# @!attribute [rw] team_abbreviation
|
|
45
|
+
# Returns the team abbreviation
|
|
46
|
+
# @api public
|
|
47
|
+
# @example
|
|
48
|
+
# stat.team_abbreviation #=> "GSW"
|
|
49
|
+
# @return [String, nil] the team abbreviation
|
|
50
|
+
attribute :team_abbreviation, Shale::Type::String
|
|
51
|
+
|
|
52
|
+
# @!attribute [rw] gp
|
|
53
|
+
# Returns games played
|
|
54
|
+
# @api public
|
|
55
|
+
# @example
|
|
56
|
+
# stat.gp #=> 45
|
|
57
|
+
# @return [Integer, nil] games played
|
|
58
|
+
attribute :gp, Shale::Type::Integer
|
|
59
|
+
|
|
60
|
+
# @!attribute [rw] w
|
|
61
|
+
# Returns wins
|
|
62
|
+
# @api public
|
|
63
|
+
# @example
|
|
64
|
+
# stat.w #=> 30
|
|
65
|
+
# @return [Integer, nil] wins
|
|
66
|
+
attribute :w, Shale::Type::Integer
|
|
67
|
+
|
|
68
|
+
# @!attribute [rw] l
|
|
69
|
+
# Returns losses
|
|
70
|
+
# @api public
|
|
71
|
+
# @example
|
|
72
|
+
# stat.l #=> 15
|
|
73
|
+
# @return [Integer, nil] losses
|
|
74
|
+
attribute :l, Shale::Type::Integer
|
|
75
|
+
|
|
76
|
+
# @!attribute [rw] w_pct
|
|
77
|
+
# Returns win percentage
|
|
78
|
+
# @api public
|
|
79
|
+
# @example
|
|
80
|
+
# stat.w_pct #=> 0.667
|
|
81
|
+
# @return [Float, nil] win percentage
|
|
82
|
+
attribute :w_pct, Shale::Type::Float
|
|
83
|
+
|
|
84
|
+
# @!attribute [rw] min
|
|
85
|
+
# Returns minutes played
|
|
86
|
+
# @api public
|
|
87
|
+
# @example
|
|
88
|
+
# stat.min #=> 245.5
|
|
89
|
+
# @return [Float, nil] minutes played
|
|
90
|
+
attribute :min, Shale::Type::Float
|
|
91
|
+
|
|
92
|
+
# @!attribute [rw] fgm
|
|
93
|
+
# Returns field goals made
|
|
94
|
+
# @api public
|
|
95
|
+
# @example
|
|
96
|
+
# stat.fgm #=> 8.5
|
|
97
|
+
# @return [Float, nil] field goals made
|
|
98
|
+
attribute :fgm, Shale::Type::Float
|
|
99
|
+
|
|
100
|
+
# @!attribute [rw] fga
|
|
101
|
+
# Returns field goals attempted
|
|
102
|
+
# @api public
|
|
103
|
+
# @example
|
|
104
|
+
# stat.fga #=> 17.2
|
|
105
|
+
# @return [Float, nil] field goals attempted
|
|
106
|
+
attribute :fga, Shale::Type::Float
|
|
107
|
+
|
|
108
|
+
# @!attribute [rw] fg_pct
|
|
109
|
+
# Returns field goal percentage
|
|
110
|
+
# @api public
|
|
111
|
+
# @example
|
|
112
|
+
# stat.fg_pct #=> 0.494
|
|
113
|
+
# @return [Float, nil] field goal percentage
|
|
114
|
+
attribute :fg_pct, Shale::Type::Float
|
|
115
|
+
|
|
116
|
+
# @!attribute [rw] fg3m
|
|
117
|
+
# Returns three-pointers made
|
|
118
|
+
# @api public
|
|
119
|
+
# @example
|
|
120
|
+
# stat.fg3m #=> 3.2
|
|
121
|
+
# @return [Float, nil] three-pointers made
|
|
122
|
+
attribute :fg3m, Shale::Type::Float
|
|
123
|
+
|
|
124
|
+
# @!attribute [rw] fg3a
|
|
125
|
+
# Returns three-pointers attempted
|
|
126
|
+
# @api public
|
|
127
|
+
# @example
|
|
128
|
+
# stat.fg3a #=> 8.5
|
|
129
|
+
# @return [Float, nil] three-pointers attempted
|
|
130
|
+
attribute :fg3a, Shale::Type::Float
|
|
131
|
+
|
|
132
|
+
# @!attribute [rw] fg3_pct
|
|
133
|
+
# Returns three-point percentage
|
|
134
|
+
# @api public
|
|
135
|
+
# @example
|
|
136
|
+
# stat.fg3_pct #=> 0.376
|
|
137
|
+
# @return [Float, nil] three-point percentage
|
|
138
|
+
attribute :fg3_pct, Shale::Type::Float
|
|
139
|
+
|
|
140
|
+
# @!attribute [rw] ftm
|
|
141
|
+
# Returns free throws made
|
|
142
|
+
# @api public
|
|
143
|
+
# @example
|
|
144
|
+
# stat.ftm #=> 3.1
|
|
145
|
+
# @return [Float, nil] free throws made
|
|
146
|
+
attribute :ftm, Shale::Type::Float
|
|
147
|
+
|
|
148
|
+
# @!attribute [rw] fta
|
|
149
|
+
# Returns free throws attempted
|
|
150
|
+
# @api public
|
|
151
|
+
# @example
|
|
152
|
+
# stat.fta #=> 3.8
|
|
153
|
+
# @return [Float, nil] free throws attempted
|
|
154
|
+
attribute :fta, Shale::Type::Float
|
|
155
|
+
|
|
156
|
+
# @!attribute [rw] ft_pct
|
|
157
|
+
# Returns free throw percentage
|
|
158
|
+
# @api public
|
|
159
|
+
# @example
|
|
160
|
+
# stat.ft_pct #=> 0.816
|
|
161
|
+
# @return [Float, nil] free throw percentage
|
|
162
|
+
attribute :ft_pct, Shale::Type::Float
|
|
163
|
+
|
|
164
|
+
# @!attribute [rw] oreb
|
|
165
|
+
# Returns offensive rebounds
|
|
166
|
+
# @api public
|
|
167
|
+
# @example
|
|
168
|
+
# stat.oreb #=> 1.8
|
|
169
|
+
# @return [Float, nil] offensive rebounds
|
|
170
|
+
attribute :oreb, Shale::Type::Float
|
|
171
|
+
|
|
172
|
+
# @!attribute [rw] dreb
|
|
173
|
+
# Returns defensive rebounds
|
|
174
|
+
# @api public
|
|
175
|
+
# @example
|
|
176
|
+
# stat.dreb #=> 6.2
|
|
177
|
+
# @return [Float, nil] defensive rebounds
|
|
178
|
+
attribute :dreb, Shale::Type::Float
|
|
179
|
+
|
|
180
|
+
# @!attribute [rw] reb
|
|
181
|
+
# Returns total rebounds
|
|
182
|
+
# @api public
|
|
183
|
+
# @example
|
|
184
|
+
# stat.reb #=> 8.0
|
|
185
|
+
# @return [Float, nil] total rebounds
|
|
186
|
+
attribute :reb, Shale::Type::Float
|
|
187
|
+
|
|
188
|
+
# @!attribute [rw] ast
|
|
189
|
+
# Returns assists
|
|
190
|
+
# @api public
|
|
191
|
+
# @example
|
|
192
|
+
# stat.ast #=> 5.5
|
|
193
|
+
# @return [Float, nil] assists
|
|
194
|
+
attribute :ast, Shale::Type::Float
|
|
195
|
+
|
|
196
|
+
# @!attribute [rw] tov
|
|
197
|
+
# Returns turnovers
|
|
198
|
+
# @api public
|
|
199
|
+
# @example
|
|
200
|
+
# stat.tov #=> 2.1
|
|
201
|
+
# @return [Float, nil] turnovers
|
|
202
|
+
attribute :tov, Shale::Type::Float
|
|
203
|
+
|
|
204
|
+
# @!attribute [rw] stl
|
|
205
|
+
# Returns steals
|
|
206
|
+
# @api public
|
|
207
|
+
# @example
|
|
208
|
+
# stat.stl #=> 1.5
|
|
209
|
+
# @return [Float, nil] steals
|
|
210
|
+
attribute :stl, Shale::Type::Float
|
|
211
|
+
|
|
212
|
+
# @!attribute [rw] blk
|
|
213
|
+
# Returns blocks
|
|
214
|
+
# @api public
|
|
215
|
+
# @example
|
|
216
|
+
# stat.blk #=> 0.8
|
|
217
|
+
# @return [Float, nil] blocks
|
|
218
|
+
attribute :blk, Shale::Type::Float
|
|
219
|
+
|
|
220
|
+
# @!attribute [rw] blka
|
|
221
|
+
# Returns blocked attempts
|
|
222
|
+
# @api public
|
|
223
|
+
# @example
|
|
224
|
+
# stat.blka #=> 0.5
|
|
225
|
+
# @return [Float, nil] blocked attempts
|
|
226
|
+
attribute :blka, Shale::Type::Float
|
|
227
|
+
|
|
228
|
+
# @!attribute [rw] pf
|
|
229
|
+
# Returns personal fouls
|
|
230
|
+
# @api public
|
|
231
|
+
# @example
|
|
232
|
+
# stat.pf #=> 2.3
|
|
233
|
+
# @return [Float, nil] personal fouls
|
|
234
|
+
attribute :pf, Shale::Type::Float
|
|
235
|
+
|
|
236
|
+
# @!attribute [rw] pfd
|
|
237
|
+
# Returns personal fouls drawn
|
|
238
|
+
# @api public
|
|
239
|
+
# @example
|
|
240
|
+
# stat.pfd #=> 3.1
|
|
241
|
+
# @return [Float, nil] personal fouls drawn
|
|
242
|
+
attribute :pfd, Shale::Type::Float
|
|
243
|
+
|
|
244
|
+
# @!attribute [rw] pts
|
|
245
|
+
# Returns points
|
|
246
|
+
# @api public
|
|
247
|
+
# @example
|
|
248
|
+
# stat.pts #=> 23.3
|
|
249
|
+
# @return [Float, nil] points
|
|
250
|
+
attribute :pts, Shale::Type::Float
|
|
251
|
+
|
|
252
|
+
# @!attribute [rw] plus_minus
|
|
253
|
+
# Returns plus/minus
|
|
254
|
+
# @api public
|
|
255
|
+
# @example
|
|
256
|
+
# stat.plus_minus #=> 8.5
|
|
257
|
+
# @return [Float, nil] plus/minus
|
|
258
|
+
attribute :plus_minus, Shale::Type::Float
|
|
259
|
+
|
|
260
|
+
# Returns the team
|
|
261
|
+
#
|
|
262
|
+
# @api public
|
|
263
|
+
# @example
|
|
264
|
+
# stat.team #=> #<NBA::Team id=1610612744 ...>
|
|
265
|
+
# @return [Team, nil] the team object
|
|
266
|
+
def team
|
|
267
|
+
Teams.find(team_id)
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
end
|