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,177 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "league_dash_lineup_stat"
|
|
5
|
+
require_relative "utils"
|
|
6
|
+
|
|
7
|
+
module NBA
|
|
8
|
+
# Provides methods to retrieve league-wide lineup statistics
|
|
9
|
+
#
|
|
10
|
+
# @api public
|
|
11
|
+
module LeagueDashLineups
|
|
12
|
+
# Result set name for lineups
|
|
13
|
+
# @return [String] the result set name
|
|
14
|
+
LINEUPS = "Lineups".freeze
|
|
15
|
+
|
|
16
|
+
# Regular season type constant
|
|
17
|
+
# @return [String] the season type
|
|
18
|
+
REGULAR_SEASON = "Regular Season".freeze
|
|
19
|
+
|
|
20
|
+
# Playoffs season type constant
|
|
21
|
+
# @return [String] the season type
|
|
22
|
+
PLAYOFFS = "Playoffs".freeze
|
|
23
|
+
|
|
24
|
+
# Per game mode constant
|
|
25
|
+
# @return [String] the per mode
|
|
26
|
+
PER_GAME = "PerGame".freeze
|
|
27
|
+
|
|
28
|
+
# Totals mode constant
|
|
29
|
+
# @return [String] the per mode
|
|
30
|
+
TOTALS = "Totals".freeze
|
|
31
|
+
|
|
32
|
+
# Per 100 possessions mode constant
|
|
33
|
+
# @return [String] the per mode
|
|
34
|
+
PER_100 = "Per100Possessions".freeze
|
|
35
|
+
|
|
36
|
+
# Group quantity for 5-man lineups
|
|
37
|
+
# @return [Integer] the group quantity
|
|
38
|
+
FIVE_MAN = 5
|
|
39
|
+
|
|
40
|
+
# Group quantity for 4-man lineups
|
|
41
|
+
# @return [Integer] the group quantity
|
|
42
|
+
FOUR_MAN = 4
|
|
43
|
+
|
|
44
|
+
# Group quantity for 3-man lineups
|
|
45
|
+
# @return [Integer] the group quantity
|
|
46
|
+
THREE_MAN = 3
|
|
47
|
+
|
|
48
|
+
# Group quantity for 2-man lineups
|
|
49
|
+
# @return [Integer] the group quantity
|
|
50
|
+
TWO_MAN = 2
|
|
51
|
+
|
|
52
|
+
# Retrieves all league-wide lineup statistics
|
|
53
|
+
#
|
|
54
|
+
# @api public
|
|
55
|
+
# @example
|
|
56
|
+
# stats = NBA::LeagueDashLineups.all(season: 2024)
|
|
57
|
+
# stats.first.group_name #=> "S. Curry - K. Thompson - ..."
|
|
58
|
+
# @param season [Integer] the season year
|
|
59
|
+
# @param season_type [String] the season type
|
|
60
|
+
# @param per_mode [String] the per mode
|
|
61
|
+
# @param group_quantity [Integer] the lineup size
|
|
62
|
+
# @param client [Client] the API client to use
|
|
63
|
+
# @return [Collection] a collection of lineup statistics
|
|
64
|
+
def self.all(season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME,
|
|
65
|
+
group_quantity: FIVE_MAN, client: CLIENT)
|
|
66
|
+
path = build_path(season, season_type: season_type, per_mode: per_mode, group_quantity: group_quantity)
|
|
67
|
+
response = client.get(path)
|
|
68
|
+
parse_response(response)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Builds the API request path
|
|
72
|
+
#
|
|
73
|
+
# @api private
|
|
74
|
+
# @return [String] the request path
|
|
75
|
+
def self.build_path(season, opts)
|
|
76
|
+
season_str = Utils.format_season(season)
|
|
77
|
+
"leaguedashlineups?LeagueID=00&Season=#{season_str}&SeasonType=#{opts.fetch(:season_type)}" \
|
|
78
|
+
"&PerMode=#{opts.fetch(:per_mode)}&GroupQuantity=#{opts.fetch(:group_quantity)}" \
|
|
79
|
+
"&MeasureType=Base&PlusMinus=N&PaceAdjust=N&Rank=N"
|
|
80
|
+
end
|
|
81
|
+
private_class_method :build_path
|
|
82
|
+
|
|
83
|
+
# Parses the API response into stat objects
|
|
84
|
+
#
|
|
85
|
+
# @api private
|
|
86
|
+
# @return [Collection] collection of lineup stats
|
|
87
|
+
def self.parse_response(response)
|
|
88
|
+
return Collection.new if response.nil? || response.empty?
|
|
89
|
+
|
|
90
|
+
data = JSON.parse(response)
|
|
91
|
+
result_set = find_result_set(data)
|
|
92
|
+
build_stats(result_set)
|
|
93
|
+
end
|
|
94
|
+
private_class_method :parse_response
|
|
95
|
+
|
|
96
|
+
# Finds the result set by name
|
|
97
|
+
#
|
|
98
|
+
# @api private
|
|
99
|
+
# @return [Hash, nil] the result set hash or nil if not found
|
|
100
|
+
def self.find_result_set(data)
|
|
101
|
+
result_sets = data["resultSets"]
|
|
102
|
+
return unless result_sets
|
|
103
|
+
|
|
104
|
+
result_sets.find { |rs| rs["name"].eql?(LINEUPS) }
|
|
105
|
+
end
|
|
106
|
+
private_class_method :find_result_set
|
|
107
|
+
|
|
108
|
+
# Builds stats collection from result set
|
|
109
|
+
#
|
|
110
|
+
# @api private
|
|
111
|
+
# @return [Collection] the stats collection
|
|
112
|
+
def self.build_stats(result_set)
|
|
113
|
+
return Collection.new unless result_set
|
|
114
|
+
|
|
115
|
+
headers = result_set["headers"]
|
|
116
|
+
rows = result_set["rowSet"]
|
|
117
|
+
return Collection.new unless headers && rows
|
|
118
|
+
|
|
119
|
+
Collection.new(rows.map { |row| build_stat(headers.zip(row).to_h) })
|
|
120
|
+
end
|
|
121
|
+
private_class_method :build_stats
|
|
122
|
+
|
|
123
|
+
# Builds a single stat object from API data
|
|
124
|
+
#
|
|
125
|
+
# @api private
|
|
126
|
+
# @return [LeagueDashLineupStat] the stat object
|
|
127
|
+
def self.build_stat(data)
|
|
128
|
+
LeagueDashLineupStat.new(**identity_info(data), **record_info(data), **shooting_info(data),
|
|
129
|
+
**counting_info(data))
|
|
130
|
+
end
|
|
131
|
+
private_class_method :build_stat
|
|
132
|
+
|
|
133
|
+
# Extracts identity information from data
|
|
134
|
+
#
|
|
135
|
+
# @api private
|
|
136
|
+
# @return [Hash] the identity information hash
|
|
137
|
+
def self.identity_info(data)
|
|
138
|
+
{group_set: data["GROUP_SET"], group_id: data["GROUP_ID"],
|
|
139
|
+
group_name: data["GROUP_NAME"], team_id: data["TEAM_ID"],
|
|
140
|
+
team_abbreviation: data["TEAM_ABBREVIATION"]}
|
|
141
|
+
end
|
|
142
|
+
private_class_method :identity_info
|
|
143
|
+
|
|
144
|
+
# Extracts record information from data
|
|
145
|
+
#
|
|
146
|
+
# @api private
|
|
147
|
+
# @return [Hash] the record information hash
|
|
148
|
+
def self.record_info(data)
|
|
149
|
+
{gp: data["GP"], w: data["W"], l: data["L"],
|
|
150
|
+
w_pct: data["W_PCT"], min: data["MIN"]}
|
|
151
|
+
end
|
|
152
|
+
private_class_method :record_info
|
|
153
|
+
|
|
154
|
+
# Extracts shooting information from data
|
|
155
|
+
#
|
|
156
|
+
# @api private
|
|
157
|
+
# @return [Hash] the shooting information hash
|
|
158
|
+
def self.shooting_info(data)
|
|
159
|
+
{fgm: data["FGM"], fga: data["FGA"], fg_pct: data["FG_PCT"],
|
|
160
|
+
fg3m: data["FG3M"], fg3a: data["FG3A"], fg3_pct: data["FG3_PCT"],
|
|
161
|
+
ftm: data["FTM"], fta: data["FTA"], ft_pct: data["FT_PCT"]}
|
|
162
|
+
end
|
|
163
|
+
private_class_method :shooting_info
|
|
164
|
+
|
|
165
|
+
# Extracts counting information from data
|
|
166
|
+
#
|
|
167
|
+
# @api private
|
|
168
|
+
# @return [Hash] the counting information hash
|
|
169
|
+
def self.counting_info(data)
|
|
170
|
+
{oreb: data["OREB"], dreb: data["DREB"], reb: data["REB"],
|
|
171
|
+
ast: data["AST"], tov: data["TOV"], stl: data["STL"],
|
|
172
|
+
blk: data["BLK"], blka: data["BLKA"], pf: data["PF"],
|
|
173
|
+
pfd: data["PFD"], pts: data["PTS"], plus_minus: data["PLUS_MINUS"]}
|
|
174
|
+
end
|
|
175
|
+
private_class_method :counting_info
|
|
176
|
+
end
|
|
177
|
+
end
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "league_dash_team_pt_shot_stat"
|
|
5
|
+
require_relative "utils"
|
|
6
|
+
|
|
7
|
+
module NBA
|
|
8
|
+
# Provides methods to retrieve league-wide opponent tracking shot statistics (defensive)
|
|
9
|
+
#
|
|
10
|
+
# @api public
|
|
11
|
+
module LeagueDashOppPtShot
|
|
12
|
+
# Result set name for league dash opponent PT shots
|
|
13
|
+
# @return [String] the result set name
|
|
14
|
+
LEAGUE_DASH_PT_SHOTS = "LeagueDashPTShots".freeze
|
|
15
|
+
|
|
16
|
+
# Regular season type constant
|
|
17
|
+
# @return [String] the season type
|
|
18
|
+
REGULAR_SEASON = "Regular Season".freeze
|
|
19
|
+
|
|
20
|
+
# Playoffs season type constant
|
|
21
|
+
# @return [String] the season type
|
|
22
|
+
PLAYOFFS = "Playoffs".freeze
|
|
23
|
+
|
|
24
|
+
# Per game mode constant
|
|
25
|
+
# @return [String] the per mode
|
|
26
|
+
PER_GAME = "PerGame".freeze
|
|
27
|
+
|
|
28
|
+
# Totals mode constant
|
|
29
|
+
# @return [String] the per mode
|
|
30
|
+
TOTALS = "Totals".freeze
|
|
31
|
+
|
|
32
|
+
# Retrieves all league-wide opponent tracking shot statistics
|
|
33
|
+
#
|
|
34
|
+
# @api public
|
|
35
|
+
# @example
|
|
36
|
+
# stats = NBA::LeagueDashOppPtShot.all(season: 2024)
|
|
37
|
+
# stats.first.fg_pct #=> 0.472
|
|
38
|
+
# @param season [Integer] the season year
|
|
39
|
+
# @param season_type [String] the season type
|
|
40
|
+
# @param per_mode [String] the per mode
|
|
41
|
+
# @param client [Client] the API client to use
|
|
42
|
+
# @return [Collection] a collection of opponent tracking shot statistics
|
|
43
|
+
def self.all(season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
|
|
44
|
+
path = build_path(season, season_type: season_type, per_mode: per_mode)
|
|
45
|
+
response = client.get(path)
|
|
46
|
+
parse_response(response)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Builds the API request path
|
|
50
|
+
#
|
|
51
|
+
# @api private
|
|
52
|
+
# @return [String] the request path
|
|
53
|
+
def self.build_path(season, opts)
|
|
54
|
+
season_str = Utils.format_season(season)
|
|
55
|
+
"leaguedashoppptshot?LeagueID=00&Season=#{season_str}" \
|
|
56
|
+
"&SeasonType=#{opts.fetch(:season_type)}&PerMode=#{opts.fetch(:per_mode)}"
|
|
57
|
+
end
|
|
58
|
+
private_class_method :build_path
|
|
59
|
+
|
|
60
|
+
# Parses the API response into stat objects
|
|
61
|
+
#
|
|
62
|
+
# @api private
|
|
63
|
+
# @return [Collection] collection of opponent PT shot stats
|
|
64
|
+
def self.parse_response(response)
|
|
65
|
+
return Collection.new if response.nil? || response.empty?
|
|
66
|
+
|
|
67
|
+
data = JSON.parse(response)
|
|
68
|
+
result_set = find_result_set(data)
|
|
69
|
+
build_stats(result_set)
|
|
70
|
+
end
|
|
71
|
+
private_class_method :parse_response
|
|
72
|
+
|
|
73
|
+
# Finds the result set by name
|
|
74
|
+
#
|
|
75
|
+
# @api private
|
|
76
|
+
# @return [Hash, nil] the result set hash or nil if not found
|
|
77
|
+
def self.find_result_set(data)
|
|
78
|
+
result_sets = data["resultSets"]
|
|
79
|
+
return unless result_sets
|
|
80
|
+
|
|
81
|
+
result_sets.find { |rs| rs["name"].eql?(LEAGUE_DASH_PT_SHOTS) }
|
|
82
|
+
end
|
|
83
|
+
private_class_method :find_result_set
|
|
84
|
+
|
|
85
|
+
# Builds stats collection from result set
|
|
86
|
+
#
|
|
87
|
+
# @api private
|
|
88
|
+
# @return [Collection] the stats collection
|
|
89
|
+
def self.build_stats(result_set)
|
|
90
|
+
return Collection.new unless result_set
|
|
91
|
+
|
|
92
|
+
headers = result_set["headers"]
|
|
93
|
+
rows = result_set["rowSet"]
|
|
94
|
+
return Collection.new unless headers && rows
|
|
95
|
+
|
|
96
|
+
Collection.new(rows.map { |row| build_stat(headers.zip(row).to_h) })
|
|
97
|
+
end
|
|
98
|
+
private_class_method :build_stats
|
|
99
|
+
|
|
100
|
+
# Builds a single stat object from API data
|
|
101
|
+
#
|
|
102
|
+
# @api private
|
|
103
|
+
# @return [LeagueDashTeamPtShotStat] the stat object
|
|
104
|
+
def self.build_stat(data)
|
|
105
|
+
LeagueDashTeamPtShotStat.new(**identity_info(data), **shooting_info(data), **two_point_info(data),
|
|
106
|
+
**three_point_info(data))
|
|
107
|
+
end
|
|
108
|
+
private_class_method :build_stat
|
|
109
|
+
|
|
110
|
+
# Extracts identity information from data
|
|
111
|
+
#
|
|
112
|
+
# @api private
|
|
113
|
+
# @return [Hash] the identity information hash
|
|
114
|
+
def self.identity_info(data)
|
|
115
|
+
{team_id: data["TEAM_ID"], team_name: data["TEAM_NAME"],
|
|
116
|
+
team_abbreviation: data["TEAM_ABBREVIATION"], gp: data["GP"], g: data["G"]}
|
|
117
|
+
end
|
|
118
|
+
private_class_method :identity_info
|
|
119
|
+
|
|
120
|
+
# Extracts shooting information from data
|
|
121
|
+
#
|
|
122
|
+
# @api private
|
|
123
|
+
# @return [Hash] the shooting information hash
|
|
124
|
+
def self.shooting_info(data)
|
|
125
|
+
{fga_frequency: data["FGA_FREQUENCY"], fgm: data["FGM"],
|
|
126
|
+
fga: data["FGA"], fg_pct: data["FG_PCT"], efg_pct: data["EFG_PCT"]}
|
|
127
|
+
end
|
|
128
|
+
private_class_method :shooting_info
|
|
129
|
+
|
|
130
|
+
# Extracts 2-point shooting information from data
|
|
131
|
+
#
|
|
132
|
+
# @api private
|
|
133
|
+
# @return [Hash] the 2-point shooting information hash
|
|
134
|
+
def self.two_point_info(data)
|
|
135
|
+
{fg2a_frequency: data["FG2A_FREQUENCY"], fg2m: data["FG2M"],
|
|
136
|
+
fg2a: data["FG2A"], fg2_pct: data["FG2_PCT"]}
|
|
137
|
+
end
|
|
138
|
+
private_class_method :two_point_info
|
|
139
|
+
|
|
140
|
+
# Extracts 3-point shooting information from data
|
|
141
|
+
#
|
|
142
|
+
# @api private
|
|
143
|
+
# @return [Hash] the 3-point shooting information hash
|
|
144
|
+
def self.three_point_info(data)
|
|
145
|
+
{fg3a_frequency: data["FG3A_FREQUENCY"], fg3m: data["FG3M"],
|
|
146
|
+
fg3a: data["FG3A"], fg3_pct: data["FG3_PCT"]}
|
|
147
|
+
end
|
|
148
|
+
private_class_method :three_point_info
|
|
149
|
+
end
|
|
150
|
+
end
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
require "equalizer"
|
|
2
|
+
require "shale"
|
|
3
|
+
require_relative "players"
|
|
4
|
+
require_relative "teams"
|
|
5
|
+
|
|
6
|
+
module NBA
|
|
7
|
+
# Represents league-wide player biographical statistics
|
|
8
|
+
#
|
|
9
|
+
# @api public
|
|
10
|
+
class LeagueDashPlayerBioStat < Shale::Mapper
|
|
11
|
+
include Equalizer.new(:player_id, :team_id)
|
|
12
|
+
|
|
13
|
+
# @!attribute [rw] player_id
|
|
14
|
+
# Returns the player ID
|
|
15
|
+
# @api public
|
|
16
|
+
# @example
|
|
17
|
+
# stat.player_id #=> 201939
|
|
18
|
+
# @return [Integer, nil] the player's ID
|
|
19
|
+
attribute :player_id, Shale::Type::Integer
|
|
20
|
+
|
|
21
|
+
# @!attribute [rw] player_name
|
|
22
|
+
# Returns the player name
|
|
23
|
+
# @api public
|
|
24
|
+
# @example
|
|
25
|
+
# stat.player_name #=> "Stephen Curry"
|
|
26
|
+
# @return [String, nil] the player's name
|
|
27
|
+
attribute :player_name, Shale::Type::String
|
|
28
|
+
|
|
29
|
+
# @!attribute [rw] team_id
|
|
30
|
+
# Returns the team ID
|
|
31
|
+
# @api public
|
|
32
|
+
# @example
|
|
33
|
+
# stat.team_id #=> 1610612744
|
|
34
|
+
# @return [Integer, nil] the team's ID
|
|
35
|
+
attribute :team_id, Shale::Type::Integer
|
|
36
|
+
|
|
37
|
+
# @!attribute [rw] team_abbreviation
|
|
38
|
+
# Returns the team abbreviation
|
|
39
|
+
# @api public
|
|
40
|
+
# @example
|
|
41
|
+
# stat.team_abbreviation #=> "GSW"
|
|
42
|
+
# @return [String, nil] the team's abbreviation
|
|
43
|
+
attribute :team_abbreviation, Shale::Type::String
|
|
44
|
+
|
|
45
|
+
# @!attribute [rw] age
|
|
46
|
+
# Returns the player's age
|
|
47
|
+
# @api public
|
|
48
|
+
# @example
|
|
49
|
+
# stat.age #=> 36
|
|
50
|
+
# @return [Float, nil] the player's age
|
|
51
|
+
attribute :age, Shale::Type::Float
|
|
52
|
+
|
|
53
|
+
# @!attribute [rw] player_height
|
|
54
|
+
# Returns the player's height as a formatted string
|
|
55
|
+
# @api public
|
|
56
|
+
# @example
|
|
57
|
+
# stat.player_height #=> "6-2"
|
|
58
|
+
# @return [String, nil] the player's height
|
|
59
|
+
attribute :player_height, Shale::Type::String
|
|
60
|
+
|
|
61
|
+
# @!attribute [rw] player_height_inches
|
|
62
|
+
# Returns the player's height in inches
|
|
63
|
+
# @api public
|
|
64
|
+
# @example
|
|
65
|
+
# stat.player_height_inches #=> 74
|
|
66
|
+
# @return [Integer, nil] the player's height in inches
|
|
67
|
+
attribute :player_height_inches, Shale::Type::Integer
|
|
68
|
+
|
|
69
|
+
# @!attribute [rw] player_weight
|
|
70
|
+
# Returns the player's weight in pounds
|
|
71
|
+
# @api public
|
|
72
|
+
# @example
|
|
73
|
+
# stat.player_weight #=> 185
|
|
74
|
+
# @return [Integer, nil] the player's weight
|
|
75
|
+
attribute :player_weight, Shale::Type::Integer
|
|
76
|
+
|
|
77
|
+
# @!attribute [rw] college
|
|
78
|
+
# Returns the player's college
|
|
79
|
+
# @api public
|
|
80
|
+
# @example
|
|
81
|
+
# stat.college #=> "Davidson"
|
|
82
|
+
# @return [String, nil] the player's college
|
|
83
|
+
attribute :college, Shale::Type::String
|
|
84
|
+
|
|
85
|
+
# @!attribute [rw] country
|
|
86
|
+
# Returns the player's country
|
|
87
|
+
# @api public
|
|
88
|
+
# @example
|
|
89
|
+
# stat.country #=> "USA"
|
|
90
|
+
# @return [String, nil] the player's country
|
|
91
|
+
attribute :country, Shale::Type::String
|
|
92
|
+
|
|
93
|
+
# @!attribute [rw] draft_year
|
|
94
|
+
# Returns the player's draft year
|
|
95
|
+
# @api public
|
|
96
|
+
# @example
|
|
97
|
+
# stat.draft_year #=> "2009"
|
|
98
|
+
# @return [String, nil] the player's draft year
|
|
99
|
+
attribute :draft_year, Shale::Type::String
|
|
100
|
+
|
|
101
|
+
# @!attribute [rw] draft_round
|
|
102
|
+
# Returns the player's draft round
|
|
103
|
+
# @api public
|
|
104
|
+
# @example
|
|
105
|
+
# stat.draft_round #=> "1"
|
|
106
|
+
# @return [String, nil] the player's draft round
|
|
107
|
+
attribute :draft_round, Shale::Type::String
|
|
108
|
+
|
|
109
|
+
# @!attribute [rw] draft_number
|
|
110
|
+
# Returns the player's draft number
|
|
111
|
+
# @api public
|
|
112
|
+
# @example
|
|
113
|
+
# stat.draft_number #=> "7"
|
|
114
|
+
# @return [String, nil] the player's draft number
|
|
115
|
+
attribute :draft_number, Shale::Type::String
|
|
116
|
+
|
|
117
|
+
# @!attribute [rw] gp
|
|
118
|
+
# Returns games played
|
|
119
|
+
# @api public
|
|
120
|
+
# @example
|
|
121
|
+
# stat.gp #=> 74
|
|
122
|
+
# @return [Integer, nil] games played
|
|
123
|
+
attribute :gp, Shale::Type::Integer
|
|
124
|
+
|
|
125
|
+
# @!attribute [rw] pts
|
|
126
|
+
# Returns points per game
|
|
127
|
+
# @api public
|
|
128
|
+
# @example
|
|
129
|
+
# stat.pts #=> 26.4
|
|
130
|
+
# @return [Float, nil] points per game
|
|
131
|
+
attribute :pts, Shale::Type::Float
|
|
132
|
+
|
|
133
|
+
# @!attribute [rw] reb
|
|
134
|
+
# Returns rebounds per game
|
|
135
|
+
# @api public
|
|
136
|
+
# @example
|
|
137
|
+
# stat.reb #=> 5.2
|
|
138
|
+
# @return [Float, nil] rebounds per game
|
|
139
|
+
attribute :reb, Shale::Type::Float
|
|
140
|
+
|
|
141
|
+
# @!attribute [rw] ast
|
|
142
|
+
# Returns assists per game
|
|
143
|
+
# @api public
|
|
144
|
+
# @example
|
|
145
|
+
# stat.ast #=> 6.1
|
|
146
|
+
# @return [Float, nil] assists per game
|
|
147
|
+
attribute :ast, Shale::Type::Float
|
|
148
|
+
|
|
149
|
+
# @!attribute [rw] net_rating
|
|
150
|
+
# Returns net rating
|
|
151
|
+
# @api public
|
|
152
|
+
# @example
|
|
153
|
+
# stat.net_rating #=> 8.5
|
|
154
|
+
# @return [Float, nil] net rating
|
|
155
|
+
attribute :net_rating, Shale::Type::Float
|
|
156
|
+
|
|
157
|
+
# @!attribute [rw] oreb_pct
|
|
158
|
+
# Returns offensive rebound percentage
|
|
159
|
+
# @api public
|
|
160
|
+
# @example
|
|
161
|
+
# stat.oreb_pct #=> 0.025
|
|
162
|
+
# @return [Float, nil] offensive rebound percentage
|
|
163
|
+
attribute :oreb_pct, Shale::Type::Float
|
|
164
|
+
|
|
165
|
+
# @!attribute [rw] dreb_pct
|
|
166
|
+
# Returns defensive rebound percentage
|
|
167
|
+
# @api public
|
|
168
|
+
# @example
|
|
169
|
+
# stat.dreb_pct #=> 0.112
|
|
170
|
+
# @return [Float, nil] defensive rebound percentage
|
|
171
|
+
attribute :dreb_pct, Shale::Type::Float
|
|
172
|
+
|
|
173
|
+
# @!attribute [rw] usg_pct
|
|
174
|
+
# Returns usage percentage
|
|
175
|
+
# @api public
|
|
176
|
+
# @example
|
|
177
|
+
# stat.usg_pct #=> 0.298
|
|
178
|
+
# @return [Float, nil] usage percentage
|
|
179
|
+
attribute :usg_pct, Shale::Type::Float
|
|
180
|
+
|
|
181
|
+
# @!attribute [rw] ts_pct
|
|
182
|
+
# Returns true shooting percentage
|
|
183
|
+
# @api public
|
|
184
|
+
# @example
|
|
185
|
+
# stat.ts_pct #=> 0.621
|
|
186
|
+
# @return [Float, nil] true shooting percentage
|
|
187
|
+
attribute :ts_pct, Shale::Type::Float
|
|
188
|
+
|
|
189
|
+
# @!attribute [rw] ast_pct
|
|
190
|
+
# Returns assist percentage
|
|
191
|
+
# @api public
|
|
192
|
+
# @example
|
|
193
|
+
# stat.ast_pct #=> 0.312
|
|
194
|
+
# @return [Float, nil] assist percentage
|
|
195
|
+
attribute :ast_pct, Shale::Type::Float
|
|
196
|
+
|
|
197
|
+
# Returns the player
|
|
198
|
+
#
|
|
199
|
+
# @api public
|
|
200
|
+
# @example
|
|
201
|
+
# stat.player #=> #<NBA::Player id=201939 ...>
|
|
202
|
+
# @return [Player, nil] the player object
|
|
203
|
+
def player
|
|
204
|
+
Players.find(player_id)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Returns the team
|
|
208
|
+
#
|
|
209
|
+
# @api public
|
|
210
|
+
# @example
|
|
211
|
+
# stat.team #=> #<NBA::Team id=1610612744 ...>
|
|
212
|
+
# @return [Team, nil] the team object
|
|
213
|
+
def team
|
|
214
|
+
Teams.find(team_id)
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
require_relative "league_dash_player_bio_stat"
|
|
5
|
+
require_relative "utils"
|
|
6
|
+
|
|
7
|
+
module NBA
|
|
8
|
+
# Provides methods to retrieve league-wide player biographical statistics
|
|
9
|
+
#
|
|
10
|
+
# @api public
|
|
11
|
+
module LeagueDashPlayerBioStats
|
|
12
|
+
# Result set name for league dash player bio stats
|
|
13
|
+
# @return [String] the result set name
|
|
14
|
+
LEAGUE_DASH_PLAYER_BIO_STATS = "LeagueDashPlayerBioStats".freeze
|
|
15
|
+
|
|
16
|
+
# Regular season type constant
|
|
17
|
+
# @return [String] the season type
|
|
18
|
+
REGULAR_SEASON = "Regular Season".freeze
|
|
19
|
+
|
|
20
|
+
# Playoffs season type constant
|
|
21
|
+
# @return [String] the season type
|
|
22
|
+
PLAYOFFS = "Playoffs".freeze
|
|
23
|
+
|
|
24
|
+
# Per game mode constant
|
|
25
|
+
# @return [String] the per mode
|
|
26
|
+
PER_GAME = "PerGame".freeze
|
|
27
|
+
|
|
28
|
+
# Totals mode constant
|
|
29
|
+
# @return [String] the per mode
|
|
30
|
+
TOTALS = "Totals".freeze
|
|
31
|
+
|
|
32
|
+
# Retrieves all league-wide player biographical statistics
|
|
33
|
+
#
|
|
34
|
+
# @api public
|
|
35
|
+
# @example
|
|
36
|
+
# stats = NBA::LeagueDashPlayerBioStats.all(season: 2024)
|
|
37
|
+
# stats.first.college #=> "Davidson"
|
|
38
|
+
# @param season [Integer] the season year
|
|
39
|
+
# @param season_type [String] the season type
|
|
40
|
+
# @param per_mode [String] the per mode
|
|
41
|
+
# @param client [Client] the API client to use
|
|
42
|
+
# @return [Collection] a collection of player biographical statistics
|
|
43
|
+
def self.all(season: Utils.current_season, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
|
|
44
|
+
path = build_path(season, season_type: season_type, per_mode: per_mode)
|
|
45
|
+
response = client.get(path)
|
|
46
|
+
parse_response(response)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Builds the API request path
|
|
50
|
+
#
|
|
51
|
+
# @api private
|
|
52
|
+
# @return [String] the request path
|
|
53
|
+
def self.build_path(season, opts)
|
|
54
|
+
season_str = Utils.format_season(season)
|
|
55
|
+
"leaguedashplayerbiostats?LeagueID=00&Season=#{season_str}" \
|
|
56
|
+
"&SeasonType=#{opts.fetch(:season_type)}&PerMode=#{opts.fetch(:per_mode)}"
|
|
57
|
+
end
|
|
58
|
+
private_class_method :build_path
|
|
59
|
+
|
|
60
|
+
# Parses the API response into stat objects
|
|
61
|
+
#
|
|
62
|
+
# @api private
|
|
63
|
+
# @return [Collection] collection of player bio stats
|
|
64
|
+
def self.parse_response(response)
|
|
65
|
+
return Collection.new if response.nil? || response.empty?
|
|
66
|
+
|
|
67
|
+
data = JSON.parse(response)
|
|
68
|
+
result_set = find_result_set(data)
|
|
69
|
+
build_stats(result_set)
|
|
70
|
+
end
|
|
71
|
+
private_class_method :parse_response
|
|
72
|
+
|
|
73
|
+
# Finds the result set by name
|
|
74
|
+
#
|
|
75
|
+
# @api private
|
|
76
|
+
# @return [Hash, nil] the result set hash or nil if not found
|
|
77
|
+
def self.find_result_set(data)
|
|
78
|
+
result_sets = data["resultSets"]
|
|
79
|
+
return unless result_sets
|
|
80
|
+
|
|
81
|
+
result_sets.find { |rs| rs["name"].eql?(LEAGUE_DASH_PLAYER_BIO_STATS) }
|
|
82
|
+
end
|
|
83
|
+
private_class_method :find_result_set
|
|
84
|
+
|
|
85
|
+
# Builds stats collection from result set
|
|
86
|
+
#
|
|
87
|
+
# @api private
|
|
88
|
+
# @return [Collection] the stats collection
|
|
89
|
+
def self.build_stats(result_set)
|
|
90
|
+
return Collection.new unless result_set
|
|
91
|
+
|
|
92
|
+
headers = result_set["headers"]
|
|
93
|
+
rows = result_set["rowSet"]
|
|
94
|
+
return Collection.new unless headers && rows
|
|
95
|
+
|
|
96
|
+
Collection.new(rows.map { |row| build_stat(headers.zip(row).to_h) })
|
|
97
|
+
end
|
|
98
|
+
private_class_method :build_stats
|
|
99
|
+
|
|
100
|
+
# Builds a single stat object from API data
|
|
101
|
+
#
|
|
102
|
+
# @api private
|
|
103
|
+
# @return [LeagueDashPlayerBioStat] the stat object
|
|
104
|
+
def self.build_stat(data)
|
|
105
|
+
LeagueDashPlayerBioStat.new(**identity_info(data), **physical_info(data), **draft_info(data),
|
|
106
|
+
**stat_info(data), **advanced_info(data))
|
|
107
|
+
end
|
|
108
|
+
private_class_method :build_stat
|
|
109
|
+
|
|
110
|
+
# Extracts identity information from data
|
|
111
|
+
#
|
|
112
|
+
# @api private
|
|
113
|
+
# @return [Hash] the identity information hash
|
|
114
|
+
def self.identity_info(data)
|
|
115
|
+
{player_id: data["PLAYER_ID"], player_name: data["PLAYER_NAME"],
|
|
116
|
+
team_id: data["TEAM_ID"], team_abbreviation: data["TEAM_ABBREVIATION"],
|
|
117
|
+
age: data["AGE"]}
|
|
118
|
+
end
|
|
119
|
+
private_class_method :identity_info
|
|
120
|
+
|
|
121
|
+
# Extracts physical information from data
|
|
122
|
+
#
|
|
123
|
+
# @api private
|
|
124
|
+
# @return [Hash] the physical information hash
|
|
125
|
+
def self.physical_info(data)
|
|
126
|
+
{player_height: data["PLAYER_HEIGHT"],
|
|
127
|
+
player_height_inches: data["PLAYER_HEIGHT_INCHES"],
|
|
128
|
+
player_weight: data["PLAYER_WEIGHT"], college: data["COLLEGE"],
|
|
129
|
+
country: data["COUNTRY"]}
|
|
130
|
+
end
|
|
131
|
+
private_class_method :physical_info
|
|
132
|
+
|
|
133
|
+
# Extracts draft information from data
|
|
134
|
+
#
|
|
135
|
+
# @api private
|
|
136
|
+
# @return [Hash] the draft information hash
|
|
137
|
+
def self.draft_info(data)
|
|
138
|
+
{draft_year: data["DRAFT_YEAR"], draft_round: data["DRAFT_ROUND"],
|
|
139
|
+
draft_number: data["DRAFT_NUMBER"]}
|
|
140
|
+
end
|
|
141
|
+
private_class_method :draft_info
|
|
142
|
+
|
|
143
|
+
# Extracts basic stat information from data
|
|
144
|
+
#
|
|
145
|
+
# @api private
|
|
146
|
+
# @return [Hash] the stat information hash
|
|
147
|
+
def self.stat_info(data)
|
|
148
|
+
{gp: data["GP"], pts: data["PTS"], reb: data["REB"],
|
|
149
|
+
ast: data["AST"]}
|
|
150
|
+
end
|
|
151
|
+
private_class_method :stat_info
|
|
152
|
+
|
|
153
|
+
# Extracts advanced stat information from data
|
|
154
|
+
#
|
|
155
|
+
# @api private
|
|
156
|
+
# @return [Hash] the advanced stat information hash
|
|
157
|
+
def self.advanced_info(data)
|
|
158
|
+
{net_rating: data["NET_RATING"], oreb_pct: data["OREB_PCT"],
|
|
159
|
+
dreb_pct: data["DREB_PCT"], usg_pct: data["USG_PCT"],
|
|
160
|
+
ts_pct: data["TS_PCT"], ast_pct: data["AST_PCT"]}
|
|
161
|
+
end
|
|
162
|
+
private_class_method :advanced_info
|
|
163
|
+
end
|
|
164
|
+
end
|