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,152 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require_relative "client"
|
|
3
|
+
require_relative "collection"
|
|
4
|
+
|
|
5
|
+
require_relative "team_year_stat"
|
|
6
|
+
|
|
7
|
+
module NBA
|
|
8
|
+
# Provides methods to retrieve team year-by-year statistics
|
|
9
|
+
module TeamYearByYearStats
|
|
10
|
+
# Result set name for team stats
|
|
11
|
+
# @return [String] the result set name
|
|
12
|
+
TEAM_STATS = "TeamStats".freeze
|
|
13
|
+
|
|
14
|
+
# Season type constant for regular season
|
|
15
|
+
# @return [String] the season type
|
|
16
|
+
REGULAR_SEASON = "Regular Season".freeze
|
|
17
|
+
|
|
18
|
+
# Season type constant for playoffs
|
|
19
|
+
# @return [String] the season type
|
|
20
|
+
PLAYOFFS = "Playoffs".freeze
|
|
21
|
+
|
|
22
|
+
# Per mode constant for per game stats
|
|
23
|
+
# @return [String] the per mode
|
|
24
|
+
PER_GAME = "PerGame".freeze
|
|
25
|
+
|
|
26
|
+
# Per mode constant for totals
|
|
27
|
+
# @return [String] the per mode
|
|
28
|
+
TOTALS = "Totals".freeze
|
|
29
|
+
|
|
30
|
+
# Retrieves year-by-year statistics for a team
|
|
31
|
+
#
|
|
32
|
+
# @api public
|
|
33
|
+
# @example
|
|
34
|
+
# stats = NBA::TeamYearByYearStats.find(team: NBA::Team::GSW)
|
|
35
|
+
# stats.each { |s| puts "#{s.year}: #{s.wins}-#{s.losses}" }
|
|
36
|
+
# @param team [Integer, Team] the team ID or Team object
|
|
37
|
+
# @param season_type [String] the season type
|
|
38
|
+
# @param per_mode [String] the per mode
|
|
39
|
+
# @param client [Client] the API client to use
|
|
40
|
+
# @return [Collection] a collection of year-by-year stats
|
|
41
|
+
def self.find(team:, season_type: REGULAR_SEASON, per_mode: PER_GAME, client: CLIENT)
|
|
42
|
+
team_id = extract_team_id(team)
|
|
43
|
+
path = build_path(team_id, season_type, per_mode)
|
|
44
|
+
response = client.get(path)
|
|
45
|
+
parse_response(response)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Builds the API request path
|
|
49
|
+
# @api private
|
|
50
|
+
# @return [String] the request path
|
|
51
|
+
def self.build_path(team_id, season_type, per_mode)
|
|
52
|
+
encoded_type = season_type
|
|
53
|
+
"teamyearbyyearstats?TeamID=#{team_id}&SeasonType=#{encoded_type}&PerMode=#{per_mode}&LeagueID=00"
|
|
54
|
+
end
|
|
55
|
+
private_class_method :build_path
|
|
56
|
+
|
|
57
|
+
# Parses the API response into year stat objects
|
|
58
|
+
# @api private
|
|
59
|
+
# @return [Collection] collection of year stats
|
|
60
|
+
def self.parse_response(response)
|
|
61
|
+
return Collection.new unless response
|
|
62
|
+
|
|
63
|
+
data = JSON.parse(response)
|
|
64
|
+
result_set = find_result_set(data)
|
|
65
|
+
return Collection.new unless result_set
|
|
66
|
+
|
|
67
|
+
headers = result_set["headers"]
|
|
68
|
+
rows = result_set["rowSet"]
|
|
69
|
+
return Collection.new unless headers && rows
|
|
70
|
+
|
|
71
|
+
stats = rows.map { |row| build_year_stat(headers, row) }
|
|
72
|
+
Collection.new(stats)
|
|
73
|
+
end
|
|
74
|
+
private_class_method :parse_response
|
|
75
|
+
|
|
76
|
+
# Finds the team stats result set in the response
|
|
77
|
+
# @api private
|
|
78
|
+
# @return [Hash, nil] the result set hash
|
|
79
|
+
def self.find_result_set(data)
|
|
80
|
+
result_sets = data["resultSets"]
|
|
81
|
+
return unless result_sets
|
|
82
|
+
|
|
83
|
+
result_sets.find { |rs| rs["name"].eql?(TEAM_STATS) }
|
|
84
|
+
end
|
|
85
|
+
private_class_method :find_result_set
|
|
86
|
+
|
|
87
|
+
# Builds a TeamYearStat object from raw data
|
|
88
|
+
# @api private
|
|
89
|
+
# @return [TeamYearStat] the year stat object
|
|
90
|
+
def self.build_year_stat(headers, row)
|
|
91
|
+
data = headers.zip(row).to_h
|
|
92
|
+
TeamYearStat.new(**year_stat_attributes(data))
|
|
93
|
+
end
|
|
94
|
+
private_class_method :build_year_stat
|
|
95
|
+
|
|
96
|
+
# Combines all year stat attributes
|
|
97
|
+
# @api private
|
|
98
|
+
# @return [Hash] the combined attributes
|
|
99
|
+
def self.year_stat_attributes(data)
|
|
100
|
+
identity_attributes(data).merge(record_attributes(data), shooting_attributes(data), counting_attributes(data))
|
|
101
|
+
end
|
|
102
|
+
private_class_method :year_stat_attributes
|
|
103
|
+
|
|
104
|
+
# Extracts identity attributes from data
|
|
105
|
+
# @api private
|
|
106
|
+
# @return [Hash] identity attributes
|
|
107
|
+
def self.identity_attributes(data)
|
|
108
|
+
{team_id: data["TEAM_ID"], team_city: data["TEAM_CITY"],
|
|
109
|
+
team_name: data["TEAM_NAME"], year: data["YEAR"], gp: data["GP"]}
|
|
110
|
+
end
|
|
111
|
+
private_class_method :identity_attributes
|
|
112
|
+
|
|
113
|
+
# Extracts record attributes from data
|
|
114
|
+
# @api private
|
|
115
|
+
# @return [Hash] record attributes
|
|
116
|
+
def self.record_attributes(data)
|
|
117
|
+
{wins: data["WINS"], losses: data["LOSSES"], win_pct: data["WIN_PCT"],
|
|
118
|
+
conf_rank: data["CONF_RANK"], div_rank: data["DIV_RANK"],
|
|
119
|
+
po_wins: data["PO_WINS"], po_losses: data["PO_LOSSES"],
|
|
120
|
+
nba_finals_appearance: data["NBA_FINALS_APPEARANCE"]}
|
|
121
|
+
end
|
|
122
|
+
private_class_method :record_attributes
|
|
123
|
+
|
|
124
|
+
# Extracts shooting attributes from data
|
|
125
|
+
# @api private
|
|
126
|
+
# @return [Hash] shooting attributes
|
|
127
|
+
def self.shooting_attributes(data)
|
|
128
|
+
{fgm: data["FGM"], fga: data["FGA"], fg_pct: data["FG_PCT"],
|
|
129
|
+
fg3m: data["FG3M"], fg3a: data["FG3A"], fg3_pct: data["FG3_PCT"],
|
|
130
|
+
ftm: data["FTM"], fta: data["FTA"], ft_pct: data["FT_PCT"]}
|
|
131
|
+
end
|
|
132
|
+
private_class_method :shooting_attributes
|
|
133
|
+
|
|
134
|
+
# Extracts counting stats attributes from data
|
|
135
|
+
# @api private
|
|
136
|
+
# @return [Hash] counting attributes
|
|
137
|
+
def self.counting_attributes(data)
|
|
138
|
+
{oreb: data["OREB"], dreb: data["DREB"], reb: data["REB"],
|
|
139
|
+
ast: data["AST"], pf: data["PF"], stl: data["STL"],
|
|
140
|
+
tov: data["TOV"], blk: data["BLK"], pts: data["PTS"], pts_rank: data["PTS_RANK"]}
|
|
141
|
+
end
|
|
142
|
+
private_class_method :counting_attributes
|
|
143
|
+
|
|
144
|
+
# Extracts team ID from team object or integer
|
|
145
|
+
# @api private
|
|
146
|
+
# @return [Integer] the team ID
|
|
147
|
+
def self.extract_team_id(team)
|
|
148
|
+
team.instance_of?(Team) ? team.id : team
|
|
149
|
+
end
|
|
150
|
+
private_class_method :extract_team_id
|
|
151
|
+
end
|
|
152
|
+
end
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
module NBA
|
|
2
|
+
# Represents a team's year-by-year statistics
|
|
3
|
+
class TeamYearStat < Shale::Mapper
|
|
4
|
+
include Equalizer.new(:team_id, :year)
|
|
5
|
+
|
|
6
|
+
# @!attribute [rw] team_id
|
|
7
|
+
# Returns the team ID
|
|
8
|
+
# @api public
|
|
9
|
+
# @example
|
|
10
|
+
# stat.team_id #=> 1610612744
|
|
11
|
+
# @return [Integer] the team ID
|
|
12
|
+
attribute :team_id, Shale::Type::Integer
|
|
13
|
+
|
|
14
|
+
# @!attribute [rw] team_city
|
|
15
|
+
# Returns the team city
|
|
16
|
+
# @api public
|
|
17
|
+
# @example
|
|
18
|
+
# stat.team_city #=> "Golden State"
|
|
19
|
+
# @return [String] the team city
|
|
20
|
+
attribute :team_city, Shale::Type::String
|
|
21
|
+
|
|
22
|
+
# @!attribute [rw] team_name
|
|
23
|
+
# Returns the team name
|
|
24
|
+
# @api public
|
|
25
|
+
# @example
|
|
26
|
+
# stat.team_name #=> "Warriors"
|
|
27
|
+
# @return [String] the team name
|
|
28
|
+
attribute :team_name, Shale::Type::String
|
|
29
|
+
|
|
30
|
+
# @!attribute [rw] year
|
|
31
|
+
# Returns the year
|
|
32
|
+
# @api public
|
|
33
|
+
# @example
|
|
34
|
+
# stat.year #=> "2024-25"
|
|
35
|
+
# @return [String] the year
|
|
36
|
+
attribute :year, Shale::Type::String
|
|
37
|
+
|
|
38
|
+
# @!attribute [rw] gp
|
|
39
|
+
# Returns games played
|
|
40
|
+
# @api public
|
|
41
|
+
# @example
|
|
42
|
+
# stat.gp #=> 82
|
|
43
|
+
# @return [Integer] games played
|
|
44
|
+
attribute :gp, Shale::Type::Integer
|
|
45
|
+
|
|
46
|
+
# @!attribute [rw] wins
|
|
47
|
+
# Returns wins
|
|
48
|
+
# @api public
|
|
49
|
+
# @example
|
|
50
|
+
# stat.wins #=> 46
|
|
51
|
+
# @return [Integer] wins
|
|
52
|
+
attribute :wins, Shale::Type::Integer
|
|
53
|
+
|
|
54
|
+
# @!attribute [rw] losses
|
|
55
|
+
# Returns losses
|
|
56
|
+
# @api public
|
|
57
|
+
# @example
|
|
58
|
+
# stat.losses #=> 36
|
|
59
|
+
# @return [Integer] losses
|
|
60
|
+
attribute :losses, Shale::Type::Integer
|
|
61
|
+
|
|
62
|
+
# @!attribute [rw] win_pct
|
|
63
|
+
# Returns win percentage
|
|
64
|
+
# @api public
|
|
65
|
+
# @example
|
|
66
|
+
# stat.win_pct #=> 0.561
|
|
67
|
+
# @return [Float] win percentage
|
|
68
|
+
attribute :win_pct, Shale::Type::Float
|
|
69
|
+
|
|
70
|
+
# @!attribute [rw] conf_rank
|
|
71
|
+
# Returns conference rank
|
|
72
|
+
# @api public
|
|
73
|
+
# @example
|
|
74
|
+
# stat.conf_rank #=> 10
|
|
75
|
+
# @return [Integer] conference rank
|
|
76
|
+
attribute :conf_rank, Shale::Type::Integer
|
|
77
|
+
|
|
78
|
+
# @!attribute [rw] div_rank
|
|
79
|
+
# Returns division rank
|
|
80
|
+
# @api public
|
|
81
|
+
# @example
|
|
82
|
+
# stat.div_rank #=> 3
|
|
83
|
+
# @return [Integer] division rank
|
|
84
|
+
attribute :div_rank, Shale::Type::Integer
|
|
85
|
+
|
|
86
|
+
# @!attribute [rw] po_wins
|
|
87
|
+
# Returns playoff wins
|
|
88
|
+
# @api public
|
|
89
|
+
# @example
|
|
90
|
+
# stat.po_wins #=> 0
|
|
91
|
+
# @return [Integer] playoff wins
|
|
92
|
+
attribute :po_wins, Shale::Type::Integer
|
|
93
|
+
|
|
94
|
+
# @!attribute [rw] po_losses
|
|
95
|
+
# Returns playoff losses
|
|
96
|
+
# @api public
|
|
97
|
+
# @example
|
|
98
|
+
# stat.po_losses #=> 0
|
|
99
|
+
# @return [Integer] playoff losses
|
|
100
|
+
attribute :po_losses, Shale::Type::Integer
|
|
101
|
+
|
|
102
|
+
# @!attribute [rw] nba_finals_appearance
|
|
103
|
+
# Returns NBA Finals appearance
|
|
104
|
+
# @api public
|
|
105
|
+
# @example
|
|
106
|
+
# stat.nba_finals_appearance #=> "N/A"
|
|
107
|
+
# @return [String] Finals appearance
|
|
108
|
+
attribute :nba_finals_appearance, Shale::Type::String
|
|
109
|
+
|
|
110
|
+
# @!attribute [rw] fgm
|
|
111
|
+
# Returns field goals made per game
|
|
112
|
+
# @api public
|
|
113
|
+
# @example
|
|
114
|
+
# stat.fgm #=> 43.2
|
|
115
|
+
# @return [Float] field goals made
|
|
116
|
+
attribute :fgm, Shale::Type::Float
|
|
117
|
+
|
|
118
|
+
# @!attribute [rw] fga
|
|
119
|
+
# Returns field goals attempted per game
|
|
120
|
+
# @api public
|
|
121
|
+
# @example
|
|
122
|
+
# stat.fga #=> 91.5
|
|
123
|
+
# @return [Float] field goals attempted
|
|
124
|
+
attribute :fga, Shale::Type::Float
|
|
125
|
+
|
|
126
|
+
# @!attribute [rw] fg_pct
|
|
127
|
+
# Returns field goal percentage
|
|
128
|
+
# @api public
|
|
129
|
+
# @example
|
|
130
|
+
# stat.fg_pct #=> 0.472
|
|
131
|
+
# @return [Float] field goal percentage
|
|
132
|
+
attribute :fg_pct, Shale::Type::Float
|
|
133
|
+
|
|
134
|
+
# @!attribute [rw] fg3m
|
|
135
|
+
# Returns three-pointers made per game
|
|
136
|
+
# @api public
|
|
137
|
+
# @example
|
|
138
|
+
# stat.fg3m #=> 14.8
|
|
139
|
+
# @return [Float] three-pointers made
|
|
140
|
+
attribute :fg3m, Shale::Type::Float
|
|
141
|
+
|
|
142
|
+
# @!attribute [rw] fg3a
|
|
143
|
+
# Returns three-pointers attempted per game
|
|
144
|
+
# @api public
|
|
145
|
+
# @example
|
|
146
|
+
# stat.fg3a #=> 40.2
|
|
147
|
+
# @return [Float] three-pointers attempted
|
|
148
|
+
attribute :fg3a, Shale::Type::Float
|
|
149
|
+
|
|
150
|
+
# @!attribute [rw] fg3_pct
|
|
151
|
+
# Returns three-point percentage
|
|
152
|
+
# @api public
|
|
153
|
+
# @example
|
|
154
|
+
# stat.fg3_pct #=> 0.368
|
|
155
|
+
# @return [Float] three-point percentage
|
|
156
|
+
attribute :fg3_pct, Shale::Type::Float
|
|
157
|
+
|
|
158
|
+
# @!attribute [rw] ftm
|
|
159
|
+
# Returns free throws made per game
|
|
160
|
+
# @api public
|
|
161
|
+
# @example
|
|
162
|
+
# stat.ftm #=> 17.5
|
|
163
|
+
# @return [Float] free throws made
|
|
164
|
+
attribute :ftm, Shale::Type::Float
|
|
165
|
+
|
|
166
|
+
# @!attribute [rw] fta
|
|
167
|
+
# Returns free throws attempted per game
|
|
168
|
+
# @api public
|
|
169
|
+
# @example
|
|
170
|
+
# stat.fta #=> 22.1
|
|
171
|
+
# @return [Float] free throws attempted
|
|
172
|
+
attribute :fta, Shale::Type::Float
|
|
173
|
+
|
|
174
|
+
# @!attribute [rw] ft_pct
|
|
175
|
+
# Returns free throw percentage
|
|
176
|
+
# @api public
|
|
177
|
+
# @example
|
|
178
|
+
# stat.ft_pct #=> 0.792
|
|
179
|
+
# @return [Float] free throw percentage
|
|
180
|
+
attribute :ft_pct, Shale::Type::Float
|
|
181
|
+
|
|
182
|
+
# @!attribute [rw] oreb
|
|
183
|
+
# Returns offensive rebounds per game
|
|
184
|
+
# @api public
|
|
185
|
+
# @example
|
|
186
|
+
# stat.oreb #=> 10.5
|
|
187
|
+
# @return [Float] offensive rebounds
|
|
188
|
+
attribute :oreb, Shale::Type::Float
|
|
189
|
+
|
|
190
|
+
# @!attribute [rw] dreb
|
|
191
|
+
# Returns defensive rebounds per game
|
|
192
|
+
# @api public
|
|
193
|
+
# @example
|
|
194
|
+
# stat.dreb #=> 33.8
|
|
195
|
+
# @return [Float] defensive rebounds
|
|
196
|
+
attribute :dreb, Shale::Type::Float
|
|
197
|
+
|
|
198
|
+
# @!attribute [rw] reb
|
|
199
|
+
# Returns total rebounds per game
|
|
200
|
+
# @api public
|
|
201
|
+
# @example
|
|
202
|
+
# stat.reb #=> 44.3
|
|
203
|
+
# @return [Float] total rebounds
|
|
204
|
+
attribute :reb, Shale::Type::Float
|
|
205
|
+
|
|
206
|
+
# @!attribute [rw] ast
|
|
207
|
+
# Returns assists per game
|
|
208
|
+
# @api public
|
|
209
|
+
# @example
|
|
210
|
+
# stat.ast #=> 28.1
|
|
211
|
+
# @return [Float] assists
|
|
212
|
+
attribute :ast, Shale::Type::Float
|
|
213
|
+
|
|
214
|
+
# @!attribute [rw] pf
|
|
215
|
+
# Returns personal fouls per game
|
|
216
|
+
# @api public
|
|
217
|
+
# @example
|
|
218
|
+
# stat.pf #=> 19.5
|
|
219
|
+
# @return [Float] personal fouls
|
|
220
|
+
attribute :pf, Shale::Type::Float
|
|
221
|
+
|
|
222
|
+
# @!attribute [rw] stl
|
|
223
|
+
# Returns steals per game
|
|
224
|
+
# @api public
|
|
225
|
+
# @example
|
|
226
|
+
# stat.stl #=> 7.8
|
|
227
|
+
# @return [Float] steals
|
|
228
|
+
attribute :stl, Shale::Type::Float
|
|
229
|
+
|
|
230
|
+
# @!attribute [rw] tov
|
|
231
|
+
# Returns turnovers per game
|
|
232
|
+
# @api public
|
|
233
|
+
# @example
|
|
234
|
+
# stat.tov #=> 14.2
|
|
235
|
+
# @return [Float] turnovers
|
|
236
|
+
attribute :tov, Shale::Type::Float
|
|
237
|
+
|
|
238
|
+
# @!attribute [rw] blk
|
|
239
|
+
# Returns blocks per game
|
|
240
|
+
# @api public
|
|
241
|
+
# @example
|
|
242
|
+
# stat.blk #=> 5.2
|
|
243
|
+
# @return [Float] blocks
|
|
244
|
+
attribute :blk, Shale::Type::Float
|
|
245
|
+
|
|
246
|
+
# @!attribute [rw] pts
|
|
247
|
+
# Returns points per game
|
|
248
|
+
# @api public
|
|
249
|
+
# @example
|
|
250
|
+
# stat.pts #=> 118.7
|
|
251
|
+
# @return [Float] points
|
|
252
|
+
attribute :pts, Shale::Type::Float
|
|
253
|
+
|
|
254
|
+
# @!attribute [rw] pts_rank
|
|
255
|
+
# Returns points rank
|
|
256
|
+
# @api public
|
|
257
|
+
# @example
|
|
258
|
+
# stat.pts_rank #=> 5
|
|
259
|
+
# @return [Integer] points rank
|
|
260
|
+
attribute :pts_rank, Shale::Type::Integer
|
|
261
|
+
|
|
262
|
+
# Returns the team object
|
|
263
|
+
#
|
|
264
|
+
# @api public
|
|
265
|
+
# @example
|
|
266
|
+
# stat.team #=> #<NBA::Team>
|
|
267
|
+
# @return [Team, nil] the team object
|
|
268
|
+
def team
|
|
269
|
+
Teams.find(team_id)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
# Returns the full team name
|
|
273
|
+
#
|
|
274
|
+
# @api public
|
|
275
|
+
# @example
|
|
276
|
+
# stat.full_name #=> "Golden State Warriors"
|
|
277
|
+
# @return [String] the full name
|
|
278
|
+
def full_name
|
|
279
|
+
"#{team_city} #{team_name}".strip
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
end
|
data/lib/nba/teams.rb
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require_relative "collection"
|
|
2
|
+
require_relative "data"
|
|
3
|
+
require_relative "team"
|
|
4
|
+
require_relative "utils"
|
|
5
|
+
|
|
6
|
+
module NBA
|
|
7
|
+
# Provides methods to retrieve NBA teams
|
|
8
|
+
module Teams
|
|
9
|
+
# Retrieves all NBA teams
|
|
10
|
+
#
|
|
11
|
+
# @api public
|
|
12
|
+
# @example
|
|
13
|
+
# teams = NBA::Teams.all
|
|
14
|
+
# teams.each { |team| puts team.name }
|
|
15
|
+
# @return [Collection] a collection of all NBA teams
|
|
16
|
+
def self.all
|
|
17
|
+
Collection.new(Data::TEAMS.map { |data| Team.new(**data) })
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Finds a team by ID
|
|
21
|
+
#
|
|
22
|
+
# @api public
|
|
23
|
+
# @example
|
|
24
|
+
# warriors = NBA::Teams.find(NBA::Team::GSW)
|
|
25
|
+
# @param team_id [Integer] the team ID to find
|
|
26
|
+
# @return [Team, nil] the team with the given ID, or nil if not found
|
|
27
|
+
def self.find(team_id)
|
|
28
|
+
id = Utils.extract_id(team_id)
|
|
29
|
+
data = Data::TEAMS.find { |t| t.fetch(:id).eql?(id) }
|
|
30
|
+
Team.new(**data) if data
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
require "equalizer"
|
|
2
|
+
require "shale"
|
|
3
|
+
|
|
4
|
+
module NBA
|
|
5
|
+
# Represents an upcoming game
|
|
6
|
+
#
|
|
7
|
+
# @api public
|
|
8
|
+
class UpcomingGame < Shale::Mapper
|
|
9
|
+
include Equalizer.new(:game_id)
|
|
10
|
+
|
|
11
|
+
# @!attribute [rw] game_id
|
|
12
|
+
# Returns the game ID
|
|
13
|
+
# @api public
|
|
14
|
+
# @example
|
|
15
|
+
# game.game_id #=> "0022400001"
|
|
16
|
+
# @return [String] the game ID
|
|
17
|
+
attribute :game_id, Shale::Type::String
|
|
18
|
+
|
|
19
|
+
# @!attribute [rw] game_date
|
|
20
|
+
# Returns the game date
|
|
21
|
+
# @api public
|
|
22
|
+
# @example
|
|
23
|
+
# game.game_date #=> "2024-10-22T00:00:00"
|
|
24
|
+
# @return [String] the game date
|
|
25
|
+
attribute :game_date, Shale::Type::String
|
|
26
|
+
|
|
27
|
+
# @!attribute [rw] game_time
|
|
28
|
+
# Returns the game time
|
|
29
|
+
# @api public
|
|
30
|
+
# @example
|
|
31
|
+
# game.game_time #=> "7:30 PM"
|
|
32
|
+
# @return [String] the game time
|
|
33
|
+
attribute :game_time, Shale::Type::String
|
|
34
|
+
|
|
35
|
+
# @!attribute [rw] home_team_id
|
|
36
|
+
# Returns the home team ID
|
|
37
|
+
# @api public
|
|
38
|
+
# @example
|
|
39
|
+
# game.home_team_id #=> 1610612744
|
|
40
|
+
# @return [Integer] the home team ID
|
|
41
|
+
attribute :home_team_id, Shale::Type::Integer
|
|
42
|
+
|
|
43
|
+
# @!attribute [rw] visitor_team_id
|
|
44
|
+
# Returns the visitor team ID
|
|
45
|
+
# @api public
|
|
46
|
+
# @example
|
|
47
|
+
# game.visitor_team_id #=> 1610612747
|
|
48
|
+
# @return [Integer] the visitor team ID
|
|
49
|
+
attribute :visitor_team_id, Shale::Type::Integer
|
|
50
|
+
|
|
51
|
+
# @!attribute [rw] home_team_name
|
|
52
|
+
# Returns the home team full name
|
|
53
|
+
# @api public
|
|
54
|
+
# @example
|
|
55
|
+
# game.home_team_name #=> "Golden State Warriors"
|
|
56
|
+
# @return [String] the home team name
|
|
57
|
+
attribute :home_team_name, Shale::Type::String
|
|
58
|
+
|
|
59
|
+
# @!attribute [rw] visitor_team_name
|
|
60
|
+
# Returns the visitor team full name
|
|
61
|
+
# @api public
|
|
62
|
+
# @example
|
|
63
|
+
# game.visitor_team_name #=> "Los Angeles Lakers"
|
|
64
|
+
# @return [String] the visitor team name
|
|
65
|
+
attribute :visitor_team_name, Shale::Type::String
|
|
66
|
+
|
|
67
|
+
# @!attribute [rw] home_team_abbreviation
|
|
68
|
+
# Returns the home team abbreviation
|
|
69
|
+
# @api public
|
|
70
|
+
# @example
|
|
71
|
+
# game.home_team_abbreviation #=> "GSW"
|
|
72
|
+
# @return [String] the home team abbreviation
|
|
73
|
+
attribute :home_team_abbreviation, Shale::Type::String
|
|
74
|
+
|
|
75
|
+
# @!attribute [rw] visitor_team_abbreviation
|
|
76
|
+
# Returns the visitor team abbreviation
|
|
77
|
+
# @api public
|
|
78
|
+
# @example
|
|
79
|
+
# game.visitor_team_abbreviation #=> "LAL"
|
|
80
|
+
# @return [String] the visitor team abbreviation
|
|
81
|
+
attribute :visitor_team_abbreviation, Shale::Type::String
|
|
82
|
+
|
|
83
|
+
# @!attribute [rw] home_team_nickname
|
|
84
|
+
# Returns the home team nickname
|
|
85
|
+
# @api public
|
|
86
|
+
# @example
|
|
87
|
+
# game.home_team_nickname #=> "Warriors"
|
|
88
|
+
# @return [String] the home team nickname
|
|
89
|
+
attribute :home_team_nickname, Shale::Type::String
|
|
90
|
+
|
|
91
|
+
# @!attribute [rw] visitor_team_nickname
|
|
92
|
+
# Returns the visitor team nickname
|
|
93
|
+
# @api public
|
|
94
|
+
# @example
|
|
95
|
+
# game.visitor_team_nickname #=> "Lakers"
|
|
96
|
+
# @return [String] the visitor team nickname
|
|
97
|
+
attribute :visitor_team_nickname, Shale::Type::String
|
|
98
|
+
|
|
99
|
+
# Returns the home team object
|
|
100
|
+
#
|
|
101
|
+
# @api public
|
|
102
|
+
# @example
|
|
103
|
+
# game.home_team #=> #<NBA::Team>
|
|
104
|
+
# @return [Team, nil] the home team
|
|
105
|
+
def home_team = Teams.find(home_team_id)
|
|
106
|
+
|
|
107
|
+
# Returns the visitor team object
|
|
108
|
+
#
|
|
109
|
+
# @api public
|
|
110
|
+
# @example
|
|
111
|
+
# game.visitor_team #=> #<NBA::Team>
|
|
112
|
+
# @return [Team, nil] the visitor team
|
|
113
|
+
def visitor_team = Teams.find(visitor_team_id)
|
|
114
|
+
end
|
|
115
|
+
end
|
data/lib/nba/utils.rb
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
require "date"
|
|
2
|
+
require "uri"
|
|
3
|
+
|
|
4
|
+
module NBA
|
|
5
|
+
# Utility methods for the NBA gem
|
|
6
|
+
module Utils
|
|
7
|
+
# Returns the current NBA season year
|
|
8
|
+
#
|
|
9
|
+
# @api public
|
|
10
|
+
# @example
|
|
11
|
+
# NBA::Utils.current_season #=> 2024
|
|
12
|
+
# @return [Integer] the current season year
|
|
13
|
+
def self.current_season
|
|
14
|
+
today = Date.today
|
|
15
|
+
# NBA season typically runs from October to June
|
|
16
|
+
# If we're in January-June, we're in the same season (which started previous year)
|
|
17
|
+
# Otherwise (July-December), return current year
|
|
18
|
+
(today.month <= 6) ? today.year - 1 : today.year
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Formats a season year into the NBA API format (e.g., "2024-25")
|
|
22
|
+
#
|
|
23
|
+
# @api public
|
|
24
|
+
# @example
|
|
25
|
+
# NBA::Utils.format_season(2024) #=> "2024-25"
|
|
26
|
+
# @param year [Integer] the season start year
|
|
27
|
+
# @return [String] the formatted season string
|
|
28
|
+
def self.format_season(year)
|
|
29
|
+
"#{year}-#{(year + 1).to_s[-2..]}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Formats a season year into the NBA SeasonID format (e.g., "22024")
|
|
33
|
+
#
|
|
34
|
+
# @api public
|
|
35
|
+
# @example
|
|
36
|
+
# NBA::Utils.format_season_id(2024) #=> "22024"
|
|
37
|
+
# @param year [Integer] the season start year
|
|
38
|
+
# @return [String] the formatted season ID string
|
|
39
|
+
def self.format_season_id(year)
|
|
40
|
+
"2#{year}"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Builds a query string from a hash of parameters
|
|
44
|
+
#
|
|
45
|
+
# @api public
|
|
46
|
+
# @example
|
|
47
|
+
# NBA::Utils.build_query(season: 2024, team_id: 1) #=> "season=2024&team_id=1"
|
|
48
|
+
# @param params [Hash] the parameters to build into a query string
|
|
49
|
+
# @return [String] the query string
|
|
50
|
+
def self.build_query(**params)
|
|
51
|
+
URI.encode_www_form(params.compact)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Extracts an ID from an entity object or returns the value as-is
|
|
55
|
+
#
|
|
56
|
+
# @api public
|
|
57
|
+
# @example
|
|
58
|
+
# NBA::Utils.extract_id(player) #=> 2544
|
|
59
|
+
# NBA::Utils.extract_id(2544) #=> 2544
|
|
60
|
+
# @param entity [Player, Team, Game, Integer, String] the entity or ID
|
|
61
|
+
# @return [Integer, String] the extracted ID
|
|
62
|
+
def self.extract_id(entity)
|
|
63
|
+
entity.respond_to?(:id) ? entity.id : entity
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Parses a value as an integer, returning nil for invalid values
|
|
67
|
+
#
|
|
68
|
+
# @api public
|
|
69
|
+
# @example
|
|
70
|
+
# NBA::Utils.parse_integer("42") #=> 42
|
|
71
|
+
# NBA::Utils.parse_integer("N/A") #=> nil
|
|
72
|
+
# @param value [String, Integer, nil] the value to parse
|
|
73
|
+
# @return [Integer, nil] the parsed integer or nil
|
|
74
|
+
def self.parse_integer(value)
|
|
75
|
+
return if value.to_s.empty?
|
|
76
|
+
|
|
77
|
+
Integer(value)
|
|
78
|
+
rescue ArgumentError
|
|
79
|
+
nil
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Extracts a league ID from a League object or returns the value as-is
|
|
83
|
+
#
|
|
84
|
+
# @api public
|
|
85
|
+
# @example
|
|
86
|
+
# NBA::Utils.extract_league_id(league) #=> "00"
|
|
87
|
+
# NBA::Utils.extract_league_id("00") #=> "00"
|
|
88
|
+
# @param league [League, String] the league or ID
|
|
89
|
+
# @return [String] the extracted league ID
|
|
90
|
+
def self.extract_league_id(league)
|
|
91
|
+
league.respond_to?(:id) ? league.id : league
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
data/lib/nba/version.rb
CHANGED