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
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
require "equalizer"
|
|
2
|
+
require "shale"
|
|
3
|
+
|
|
4
|
+
module NBA
|
|
5
|
+
# Represents an all-time statistical leader
|
|
6
|
+
class AllTimeLeader < Shale::Mapper
|
|
7
|
+
include Equalizer.new(:player_id, :category)
|
|
8
|
+
|
|
9
|
+
# @!attribute [rw] player_id
|
|
10
|
+
# Returns the player ID
|
|
11
|
+
# @api public
|
|
12
|
+
# @example
|
|
13
|
+
# leader.player_id #=> 2544
|
|
14
|
+
# @return [Integer] the player ID
|
|
15
|
+
attribute :player_id, Shale::Type::Integer
|
|
16
|
+
|
|
17
|
+
# @!attribute [rw] player_name
|
|
18
|
+
# Returns the player name
|
|
19
|
+
# @api public
|
|
20
|
+
# @example
|
|
21
|
+
# leader.player_name #=> "LeBron James"
|
|
22
|
+
# @return [String] the player name
|
|
23
|
+
attribute :player_name, Shale::Type::String
|
|
24
|
+
|
|
25
|
+
# @!attribute [rw] category
|
|
26
|
+
# Returns the statistical category
|
|
27
|
+
# @api public
|
|
28
|
+
# @example
|
|
29
|
+
# leader.category #=> "PTS"
|
|
30
|
+
# @return [String] the category
|
|
31
|
+
attribute :category, Shale::Type::String
|
|
32
|
+
|
|
33
|
+
# @!attribute [rw] value
|
|
34
|
+
# Returns the stat value
|
|
35
|
+
# @api public
|
|
36
|
+
# @example
|
|
37
|
+
# leader.value #=> 40474
|
|
38
|
+
# @return [Float] the value
|
|
39
|
+
attribute :value, Shale::Type::Float
|
|
40
|
+
|
|
41
|
+
# @!attribute [rw] rank
|
|
42
|
+
# Returns the ranking position
|
|
43
|
+
# @api public
|
|
44
|
+
# @example
|
|
45
|
+
# leader.rank #=> 1
|
|
46
|
+
# @return [Integer] the rank
|
|
47
|
+
attribute :rank, Shale::Type::Integer
|
|
48
|
+
|
|
49
|
+
# @!attribute [rw] is_active
|
|
50
|
+
# Returns whether the player is active
|
|
51
|
+
# @api public
|
|
52
|
+
# @example
|
|
53
|
+
# leader.is_active #=> true
|
|
54
|
+
# @return [Boolean] whether active
|
|
55
|
+
attribute :is_active, Shale::Type::Boolean
|
|
56
|
+
|
|
57
|
+
# Returns the player object
|
|
58
|
+
#
|
|
59
|
+
# @api public
|
|
60
|
+
# @example
|
|
61
|
+
# leader.player #=> #<NBA::Player>
|
|
62
|
+
# @return [Player, nil] the player object
|
|
63
|
+
def player
|
|
64
|
+
Players.find(player_id)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Returns whether the player is active
|
|
68
|
+
#
|
|
69
|
+
# @api public
|
|
70
|
+
# @example
|
|
71
|
+
# leader.active? #=> true
|
|
72
|
+
# @return [Boolean] true if active
|
|
73
|
+
def active?
|
|
74
|
+
is_active
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "all_time_leader"
|
|
5
|
+
|
|
6
|
+
module NBA
|
|
7
|
+
# Provides methods to retrieve all-time NBA statistical leaders
|
|
8
|
+
module AllTimeLeaders
|
|
9
|
+
# Points category
|
|
10
|
+
# @return [String] the category code
|
|
11
|
+
PTS = "PTS".freeze
|
|
12
|
+
# Rebounds category
|
|
13
|
+
# @return [String] the category code
|
|
14
|
+
REB = "REB".freeze
|
|
15
|
+
# Assists category
|
|
16
|
+
# @return [String] the category code
|
|
17
|
+
AST = "AST".freeze
|
|
18
|
+
# Steals category
|
|
19
|
+
# @return [String] the category code
|
|
20
|
+
STL = "STL".freeze
|
|
21
|
+
# Blocks category
|
|
22
|
+
# @return [String] the category code
|
|
23
|
+
BLK = "BLK".freeze
|
|
24
|
+
# Field goals made category
|
|
25
|
+
# @return [String] the category code
|
|
26
|
+
FGM = "FGM".freeze
|
|
27
|
+
# Field goals attempted category
|
|
28
|
+
# @return [String] the category code
|
|
29
|
+
FGA = "FGA".freeze
|
|
30
|
+
# Three pointers made category
|
|
31
|
+
# @return [String] the category code
|
|
32
|
+
FG3M = "FG3M".freeze
|
|
33
|
+
# Three pointers attempted category
|
|
34
|
+
# @return [String] the category code
|
|
35
|
+
FG3A = "FG3A".freeze
|
|
36
|
+
# Free throws made category
|
|
37
|
+
# @return [String] the category code
|
|
38
|
+
FTM = "FTM".freeze
|
|
39
|
+
# Free throws attempted category
|
|
40
|
+
# @return [String] the category code
|
|
41
|
+
FTA = "FTA".freeze
|
|
42
|
+
# Games played category
|
|
43
|
+
# @return [String] the category code
|
|
44
|
+
GP = "GP".freeze
|
|
45
|
+
# Turnovers category
|
|
46
|
+
# @return [String] the category code
|
|
47
|
+
TOV = "TOV".freeze
|
|
48
|
+
# Personal fouls category
|
|
49
|
+
# @return [String] the category code
|
|
50
|
+
PF = "PF".freeze
|
|
51
|
+
# Offensive rebounds category
|
|
52
|
+
# @return [String] the category code
|
|
53
|
+
OREB = "OREB".freeze
|
|
54
|
+
# Defensive rebounds category
|
|
55
|
+
# @return [String] the category code
|
|
56
|
+
DREB = "DREB".freeze
|
|
57
|
+
|
|
58
|
+
# Regular season type
|
|
59
|
+
# @return [String] the season type
|
|
60
|
+
REGULAR_SEASON = "Regular Season".freeze
|
|
61
|
+
# Playoffs season type
|
|
62
|
+
# @return [String] the season type
|
|
63
|
+
PLAYOFFS = "Playoffs".freeze
|
|
64
|
+
|
|
65
|
+
# Totals per mode
|
|
66
|
+
# @return [String] the per mode
|
|
67
|
+
TOTALS = "Totals".freeze
|
|
68
|
+
# Per game per mode
|
|
69
|
+
# @return [String] the per mode
|
|
70
|
+
PER_GAME = "PerGame".freeze
|
|
71
|
+
|
|
72
|
+
# Category to result set mapping
|
|
73
|
+
CATEGORY_RESULT_SETS = {
|
|
74
|
+
PTS => "PTSLeaders", REB => "REBLeaders", AST => "ASTLeaders",
|
|
75
|
+
STL => "STLLeaders", BLK => "BLKLeaders", FGM => "FGMLeaders",
|
|
76
|
+
FGA => "FGALeaders", FG3M => "FG3MLeaders", FG3A => "FG3ALeaders",
|
|
77
|
+
FTM => "FTMLeaders", FTA => "FTALeaders", GP => "GPLeaders",
|
|
78
|
+
TOV => "TOVLeaders", PF => "PFLeaders", OREB => "OREBLeaders",
|
|
79
|
+
DREB => "DREBLeaders"
|
|
80
|
+
}.freeze
|
|
81
|
+
private_constant :CATEGORY_RESULT_SETS
|
|
82
|
+
|
|
83
|
+
# Retrieves all-time leaders for a statistical category
|
|
84
|
+
#
|
|
85
|
+
# @api public
|
|
86
|
+
# @example
|
|
87
|
+
# leaders = NBA::AllTimeLeaders.find(category: NBA::AllTimeLeaders::PTS)
|
|
88
|
+
# leaders.each { |l| puts "#{l.rank}. #{l.player_name}: #{l.value.to_i}" }
|
|
89
|
+
# @param category [String] the statistical category (PTS, REB, AST, etc.)
|
|
90
|
+
# @param season_type [String] the season type (Regular Season, Playoffs)
|
|
91
|
+
# @param per_mode [String] the per mode (Totals, PerGame)
|
|
92
|
+
# @param limit [Integer] number of results to return (default 10)
|
|
93
|
+
# @param client [Client] the API client to use
|
|
94
|
+
# @return [Collection] a collection of all-time leaders
|
|
95
|
+
def self.find(category:, season_type: REGULAR_SEASON, per_mode: TOTALS, limit: 10, client: CLIENT)
|
|
96
|
+
path = build_path(season_type, per_mode, limit)
|
|
97
|
+
response = client.get(path)
|
|
98
|
+
parse_response(response, category, limit)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Builds the API path
|
|
102
|
+
# @api private
|
|
103
|
+
# @param season_type [String] the season type
|
|
104
|
+
# @param per_mode [String] the per mode
|
|
105
|
+
# @param limit [Integer] the limit
|
|
106
|
+
# @return [String] the path
|
|
107
|
+
def self.build_path(season_type, per_mode, limit)
|
|
108
|
+
"alltimeleadersgrids?LeagueID=00&PerMode=#{per_mode}&SeasonType=#{season_type}&TopX=#{limit}"
|
|
109
|
+
end
|
|
110
|
+
private_class_method :build_path
|
|
111
|
+
|
|
112
|
+
# Parses the API response
|
|
113
|
+
# @api private
|
|
114
|
+
# @param response [String, nil] the JSON response
|
|
115
|
+
# @param category [String] the category
|
|
116
|
+
# @param limit [Integer] the limit
|
|
117
|
+
# @return [Collection] collection of leaders
|
|
118
|
+
def self.parse_response(response, category, limit)
|
|
119
|
+
return Collection.new unless response
|
|
120
|
+
|
|
121
|
+
data = JSON.parse(response)
|
|
122
|
+
result_set = find_result_set(data, CATEGORY_RESULT_SETS[category])
|
|
123
|
+
return Collection.new unless result_set
|
|
124
|
+
|
|
125
|
+
build_leaders(result_set, category, limit)
|
|
126
|
+
end
|
|
127
|
+
private_class_method :parse_response
|
|
128
|
+
|
|
129
|
+
# Finds a result set by name
|
|
130
|
+
# @api private
|
|
131
|
+
# @param data [Hash] the parsed JSON
|
|
132
|
+
# @param name [String] the result set name
|
|
133
|
+
# @return [Hash, nil] the result set
|
|
134
|
+
def self.find_result_set(data, name)
|
|
135
|
+
result_sets = data["resultSets"]
|
|
136
|
+
return unless result_sets
|
|
137
|
+
|
|
138
|
+
result_sets.find { |rs| rs.fetch("name").eql?(name) }
|
|
139
|
+
end
|
|
140
|
+
private_class_method :find_result_set
|
|
141
|
+
|
|
142
|
+
# Builds leaders collection from result set
|
|
143
|
+
# @api private
|
|
144
|
+
# @param result_set [Hash] the result set
|
|
145
|
+
# @param category [String] the category
|
|
146
|
+
# @param limit [Integer] the limit
|
|
147
|
+
# @return [Collection] collection of leaders
|
|
148
|
+
def self.build_leaders(result_set, category, limit)
|
|
149
|
+
headers = result_set["headers"]
|
|
150
|
+
rows = result_set["rowSet"]
|
|
151
|
+
return Collection.new unless headers && rows
|
|
152
|
+
|
|
153
|
+
leaders = rows.take(limit).map.with_index(1) do |row, rank|
|
|
154
|
+
build_leader(headers, row, category, rank)
|
|
155
|
+
end
|
|
156
|
+
Collection.new(leaders)
|
|
157
|
+
end
|
|
158
|
+
private_class_method :build_leaders
|
|
159
|
+
|
|
160
|
+
# Builds a single leader
|
|
161
|
+
# @api private
|
|
162
|
+
# @param headers [Array<String>] the headers
|
|
163
|
+
# @param row [Array] the row data
|
|
164
|
+
# @param category [String] the category
|
|
165
|
+
# @param rank [Integer] the rank
|
|
166
|
+
# @return [AllTimeLeader] the leader
|
|
167
|
+
def self.build_leader(headers, row, category, rank)
|
|
168
|
+
data = headers.zip(row).to_h
|
|
169
|
+
AllTimeLeader.new(**leader_attributes(data, category, rank))
|
|
170
|
+
end
|
|
171
|
+
private_class_method :build_leader
|
|
172
|
+
|
|
173
|
+
# Extracts leader attributes from data
|
|
174
|
+
# @api private
|
|
175
|
+
# @param data [Hash] the raw data
|
|
176
|
+
# @param category [String] the category
|
|
177
|
+
# @param rank [Integer] the rank
|
|
178
|
+
# @return [Hash] the attributes
|
|
179
|
+
def self.leader_attributes(data, category, rank)
|
|
180
|
+
{player_id: data.fetch("PLAYER_ID"), player_name: data.fetch("PLAYER_NAME"), category: category,
|
|
181
|
+
value: data.fetch(category), rank: rank, is_active: data.fetch("IS_ACTIVE_FLAG").eql?("Y")}
|
|
182
|
+
end
|
|
183
|
+
private_class_method :leader_attributes
|
|
184
|
+
end
|
|
185
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
require "equalizer"
|
|
2
|
+
require "shale"
|
|
3
|
+
require_relative "players"
|
|
4
|
+
require_relative "teams"
|
|
5
|
+
|
|
6
|
+
module NBA
|
|
7
|
+
# Represents an assist leader entry
|
|
8
|
+
class AssistLeader < Shale::Mapper
|
|
9
|
+
include Equalizer.new(:player_id, :rank)
|
|
10
|
+
|
|
11
|
+
# @!attribute [rw] player_id
|
|
12
|
+
# Returns the player ID
|
|
13
|
+
# @api public
|
|
14
|
+
# @example
|
|
15
|
+
# leader.player_id #=> 201566
|
|
16
|
+
# @return [Integer] the player ID
|
|
17
|
+
attribute :player_id, Shale::Type::Integer
|
|
18
|
+
|
|
19
|
+
# @!attribute [rw] player_name
|
|
20
|
+
# Returns the player name
|
|
21
|
+
# @api public
|
|
22
|
+
# @example
|
|
23
|
+
# leader.player_name #=> "Russell Westbrook"
|
|
24
|
+
# @return [String] the player name
|
|
25
|
+
attribute :player_name, Shale::Type::String
|
|
26
|
+
|
|
27
|
+
# @!attribute [rw] team_id
|
|
28
|
+
# Returns the team ID
|
|
29
|
+
# @api public
|
|
30
|
+
# @example
|
|
31
|
+
# leader.team_id #=> 1610612746
|
|
32
|
+
# @return [Integer] the team ID
|
|
33
|
+
attribute :team_id, Shale::Type::Integer
|
|
34
|
+
|
|
35
|
+
# @!attribute [rw] team_abbreviation
|
|
36
|
+
# Returns the team abbreviation
|
|
37
|
+
# @api public
|
|
38
|
+
# @example
|
|
39
|
+
# leader.team_abbreviation #=> "LAC"
|
|
40
|
+
# @return [String] the team abbreviation
|
|
41
|
+
attribute :team_abbreviation, Shale::Type::String
|
|
42
|
+
|
|
43
|
+
# @!attribute [rw] rank
|
|
44
|
+
# Returns the rank in the category
|
|
45
|
+
# @api public
|
|
46
|
+
# @example
|
|
47
|
+
# leader.rank #=> 1
|
|
48
|
+
# @return [Integer] the rank
|
|
49
|
+
attribute :rank, Shale::Type::Integer
|
|
50
|
+
|
|
51
|
+
# @!attribute [rw] ast
|
|
52
|
+
# Returns the total assists
|
|
53
|
+
# @api public
|
|
54
|
+
# @example
|
|
55
|
+
# leader.ast #=> 654
|
|
56
|
+
# @return [Integer] the total assists
|
|
57
|
+
attribute :ast, Shale::Type::Integer
|
|
58
|
+
|
|
59
|
+
# Returns the player object for this leader
|
|
60
|
+
#
|
|
61
|
+
# @api public
|
|
62
|
+
# @example
|
|
63
|
+
# leader.player #=> #<NBA::Player>
|
|
64
|
+
# @return [Player, nil] the hydrated player object
|
|
65
|
+
def player
|
|
66
|
+
Players.find(player_id)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Returns the team object for this leader
|
|
70
|
+
#
|
|
71
|
+
# @api public
|
|
72
|
+
# @example
|
|
73
|
+
# leader.team #=> #<NBA::Team>
|
|
74
|
+
# @return [Team, nil] the team object
|
|
75
|
+
def team
|
|
76
|
+
Teams.find(team_id)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
json do
|
|
80
|
+
map "player_id", to: :player_id
|
|
81
|
+
map "playerId", to: :player_id
|
|
82
|
+
map "player_name", to: :player_name
|
|
83
|
+
map "playerName", to: :player_name
|
|
84
|
+
map "team_id", to: :team_id
|
|
85
|
+
map "teamId", to: :team_id
|
|
86
|
+
map "team_abbreviation", to: :team_abbreviation
|
|
87
|
+
map "teamAbbreviation", to: :team_abbreviation
|
|
88
|
+
map "rank", to: :rank
|
|
89
|
+
map "ast", to: :ast
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "assist_leader"
|
|
5
|
+
require_relative "response_parser"
|
|
6
|
+
require_relative "utils"
|
|
7
|
+
|
|
8
|
+
module NBA
|
|
9
|
+
# Provides methods to retrieve NBA assist leaders
|
|
10
|
+
module AssistLeaders
|
|
11
|
+
# Result set name for assist leaders
|
|
12
|
+
# @return [String] the result set name
|
|
13
|
+
RESULT_SET = "AssistLeaders".freeze
|
|
14
|
+
|
|
15
|
+
# Retrieves assist leaders for a season
|
|
16
|
+
#
|
|
17
|
+
# @api public
|
|
18
|
+
# @example
|
|
19
|
+
# leaders = NBA::AssistLeaders.all(season: 2023)
|
|
20
|
+
# leaders.each { |leader| puts "#{leader.rank}. #{leader.player_name}: #{leader.ast}" }
|
|
21
|
+
# @param season [Integer] the season year (defaults to current season)
|
|
22
|
+
# @param season_type [String] the season type (Regular Season, Playoffs, etc.)
|
|
23
|
+
# @param per_mode [String] the per mode (Totals, PerGame)
|
|
24
|
+
# @param player_or_team [String] player or team stats (Player, Team)
|
|
25
|
+
# @param league [String, League] the league ID or League object (default NBA)
|
|
26
|
+
# @param client [Client] the API client to use
|
|
27
|
+
# @return [Collection] a collection of assist leaders
|
|
28
|
+
def self.all(season: Utils.current_season, season_type: "Regular Season", per_mode: "Totals",
|
|
29
|
+
player_or_team: "Player", league: League::NBA, client: CLIENT)
|
|
30
|
+
league_id = Utils.extract_league_id(league)
|
|
31
|
+
path = build_path(season, season_type, per_mode, player_or_team, league_id)
|
|
32
|
+
ResponseParser.parse(client.get(path), result_set: RESULT_SET) { |data| build_leader(data) }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Builds the API request path
|
|
36
|
+
# @api private
|
|
37
|
+
# @return [String] the request path
|
|
38
|
+
def self.build_path(season, season_type, per_mode, player_or_team, league_id)
|
|
39
|
+
"assistleaders?LeagueID=#{league_id}&PerMode=#{per_mode}&PlayerOrTeam=#{player_or_team}" \
|
|
40
|
+
"&Season=#{Utils.format_season(season)}&SeasonType=#{season_type}"
|
|
41
|
+
end
|
|
42
|
+
private_class_method :build_path
|
|
43
|
+
|
|
44
|
+
# Builds an AssistLeader object from raw data
|
|
45
|
+
# @api private
|
|
46
|
+
# @param data [Hash] the row data
|
|
47
|
+
# @return [AssistLeader] the leader object
|
|
48
|
+
def self.build_leader(data)
|
|
49
|
+
AssistLeader.new(**leader_attributes(data))
|
|
50
|
+
end
|
|
51
|
+
private_class_method :build_leader
|
|
52
|
+
|
|
53
|
+
# Extracts leader attributes from data
|
|
54
|
+
# @api private
|
|
55
|
+
# @param data [Hash] the row data
|
|
56
|
+
# @return [Hash] leader attributes
|
|
57
|
+
def self.leader_attributes(data)
|
|
58
|
+
{player_id: data["PLAYER_ID"], player_name: data["PLAYER_NAME"],
|
|
59
|
+
team_id: data["TEAM_ID"], team_abbreviation: data["TEAM_ABBREVIATION"],
|
|
60
|
+
rank: data["RANK"], ast: data["AST"]}
|
|
61
|
+
end
|
|
62
|
+
private_class_method :leader_attributes
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "assist_tracker_entry"
|
|
5
|
+
require_relative "response_parser"
|
|
6
|
+
require_relative "utils"
|
|
7
|
+
|
|
8
|
+
module NBA
|
|
9
|
+
# Provides methods to retrieve NBA assist tracker data (who passes to who)
|
|
10
|
+
module AssistTracker
|
|
11
|
+
# Result set name for assist tracker
|
|
12
|
+
# @return [String] the result set name
|
|
13
|
+
RESULT_SET = "AssistTracker".freeze
|
|
14
|
+
|
|
15
|
+
# Retrieves assist tracker data for a season
|
|
16
|
+
#
|
|
17
|
+
# @api public
|
|
18
|
+
# @example
|
|
19
|
+
# entries = NBA::AssistTracker.all(season: 2023)
|
|
20
|
+
# entries.each { |e| puts "#{e.player_name} -> #{e.pass_to}: #{e.ast} assists" }
|
|
21
|
+
# @param season [Integer] the season year (defaults to current season)
|
|
22
|
+
# @param season_type [String] the season type (Regular Season, Playoffs, etc.)
|
|
23
|
+
# @param per_mode [String] the per mode (Totals, PerGame)
|
|
24
|
+
# @param league [String, League] the league ID or League object (default NBA)
|
|
25
|
+
# @param client [Client] the API client to use
|
|
26
|
+
# @return [Collection] a collection of assist tracker entries
|
|
27
|
+
def self.all(season: Utils.current_season, season_type: "Regular Season", per_mode: "Totals",
|
|
28
|
+
league: League::NBA, client: CLIENT)
|
|
29
|
+
league_id = Utils.extract_league_id(league)
|
|
30
|
+
path = build_path(season, season_type, per_mode, league_id)
|
|
31
|
+
ResponseParser.parse(client.get(path), result_set: RESULT_SET) { |data| build_entry(data) }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Builds the API request path
|
|
35
|
+
# @api private
|
|
36
|
+
# @return [String] the request path
|
|
37
|
+
def self.build_path(season, season_type, per_mode, league_id)
|
|
38
|
+
"assisttracker?LeagueID=#{league_id}&PerMode=#{per_mode}" \
|
|
39
|
+
"&Season=#{Utils.format_season(season)}&SeasonType=#{season_type}"
|
|
40
|
+
end
|
|
41
|
+
private_class_method :build_path
|
|
42
|
+
|
|
43
|
+
# Builds an AssistTrackerEntry object from raw data
|
|
44
|
+
# @api private
|
|
45
|
+
# @param data [Hash] the row data
|
|
46
|
+
# @return [AssistTrackerEntry] the entry object
|
|
47
|
+
def self.build_entry(data)
|
|
48
|
+
AssistTrackerEntry.new(**player_attrs(data), **pass_attrs(data), **shooting_attrs(data))
|
|
49
|
+
end
|
|
50
|
+
private_class_method :build_entry
|
|
51
|
+
|
|
52
|
+
# Extracts player attributes from data
|
|
53
|
+
# @api private
|
|
54
|
+
# @param data [Hash] the row data
|
|
55
|
+
# @return [Hash] player attributes
|
|
56
|
+
def self.player_attrs(data)
|
|
57
|
+
{player_id: data["PLAYER_ID"], player_name: data["PLAYER_NAME"],
|
|
58
|
+
team_id: data["TEAM_ID"], team_abbreviation: data["TEAM_ABBREVIATION"]}
|
|
59
|
+
end
|
|
60
|
+
private_class_method :player_attrs
|
|
61
|
+
|
|
62
|
+
# Extracts pass attributes from data
|
|
63
|
+
# @api private
|
|
64
|
+
# @param data [Hash] the row data
|
|
65
|
+
# @return [Hash] pass attributes
|
|
66
|
+
def self.pass_attrs(data)
|
|
67
|
+
{pass_to: data["PASS_TO"], pass_to_player_id: data["PASS_TO_PLAYER_ID"],
|
|
68
|
+
frequency: data["FREQUENCY"], pass: data["PASS"], ast: data["AST"]}
|
|
69
|
+
end
|
|
70
|
+
private_class_method :pass_attrs
|
|
71
|
+
|
|
72
|
+
# Extracts shooting attributes from data
|
|
73
|
+
# @api private
|
|
74
|
+
# @param data [Hash] the row data
|
|
75
|
+
# @return [Hash] shooting attributes
|
|
76
|
+
def self.shooting_attrs(data)
|
|
77
|
+
fg_attrs(data).merge(fg2_attrs(data)).merge(fg3_attrs(data))
|
|
78
|
+
end
|
|
79
|
+
private_class_method :shooting_attrs
|
|
80
|
+
|
|
81
|
+
# Extracts field goal attributes from data
|
|
82
|
+
# @api private
|
|
83
|
+
# @param data [Hash] the row data
|
|
84
|
+
# @return [Hash] field goal attributes
|
|
85
|
+
def self.fg_attrs(data)
|
|
86
|
+
{fg_m: data["FGM"], fg_a: data["FGA"], fg_pct: data["FG_PCT"]}
|
|
87
|
+
end
|
|
88
|
+
private_class_method :fg_attrs
|
|
89
|
+
|
|
90
|
+
# Extracts 2-point field goal attributes from data
|
|
91
|
+
# @api private
|
|
92
|
+
# @param data [Hash] the row data
|
|
93
|
+
# @return [Hash] 2-point field goal attributes
|
|
94
|
+
def self.fg2_attrs(data)
|
|
95
|
+
{fg2m: data["FG2M"], fg2a: data["FG2A"], fg2_pct: data["FG2_PCT"]}
|
|
96
|
+
end
|
|
97
|
+
private_class_method :fg2_attrs
|
|
98
|
+
|
|
99
|
+
# Extracts 3-point field goal attributes from data
|
|
100
|
+
# @api private
|
|
101
|
+
# @param data [Hash] the row data
|
|
102
|
+
# @return [Hash] 3-point field goal attributes
|
|
103
|
+
def self.fg3_attrs(data)
|
|
104
|
+
{fg3m: data["FG3M"], fg3a: data["FG3A"], fg3_pct: data["FG3_PCT"]}
|
|
105
|
+
end
|
|
106
|
+
private_class_method :fg3_attrs
|
|
107
|
+
end
|
|
108
|
+
end
|