mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-29 20:13:00 +00:00
Fix odds and more (#81)
* fix(odds): Resolve incorrect sport and league parameters in _fetch_odds calls - Fixed SportsCore._fetch_data() to call _fetch_odds(game) instead of _fetch_odds(game, sport_key, sport_key) - Updated _fetch_odds method signature to accept only game parameter - Added _fetch_odds_with_params helper method for sport-specific implementations - Updated sport-specific managers to use correct sport and league parameters: - NFL: football/nfl - NCAA Football: football/college-football - NCAA Hockey: hockey/mens-college-hockey - Ensures odds are fetched with correct ESPN API endpoints Fixes #79 * Fix odds and other things * update hockey * fix rankings * update imports * Fix Logo Cache * Add show_favorite_team_only attribute --------- Co-authored-by: ChuckBuilds <33324927+ChuckBuilds@users.noreply.github.com> Co-authored-by: Alex Resnick <adr8282@gmail.com>
This commit is contained in:
@@ -14,39 +14,13 @@ import requests
|
||||
class Football(SportsCore):
|
||||
"""Base class for football sports with common functionality."""
|
||||
|
||||
# Football sport configuration (moved from sport_configs.py)
|
||||
SPORT_CONFIG = {
|
||||
'update_cadence': 'weekly',
|
||||
'season_length': 17, # NFL default
|
||||
'games_per_week': 1,
|
||||
'api_endpoints': ['scoreboard', 'standings'],
|
||||
'sport_specific_fields': ['down', 'distance', 'possession', 'timeouts', 'is_redzone'],
|
||||
'update_interval_seconds': 60,
|
||||
'logo_dir': 'assets/sports/nfl_logos',
|
||||
'show_records': True,
|
||||
'show_ranking': True,
|
||||
'show_odds': True,
|
||||
'data_source_type': 'espn',
|
||||
'api_base_url': 'https://site.api.espn.com/apis/site/v2/sports/football'
|
||||
}
|
||||
|
||||
def __init__(self, config: Dict[str, Any], display_manager: DisplayManager, cache_manager: CacheManager, logger: logging.Logger, sport_key: str):
|
||||
super().__init__(config, display_manager, cache_manager, logger, sport_key)
|
||||
|
||||
# Initialize football-specific architecture components
|
||||
self.sport_config = self.get_sport_config()
|
||||
self.api_extractor = ESPNFootballExtractor(logger)
|
||||
self.data_source = ESPNDataSource(logger)
|
||||
|
||||
def get_sport_config(self) -> Dict[str, Any]:
|
||||
"""Get football sport configuration."""
|
||||
return self.SPORT_CONFIG.copy()
|
||||
|
||||
def _fetch_game_odds(self, _: Dict) -> None:
|
||||
pass
|
||||
|
||||
def _fetch_odds(self, game: Dict, league: str) -> None:
|
||||
super()._fetch_odds(game, "football", league)
|
||||
self.sport = "football"
|
||||
|
||||
def _extract_game_details(self, game_event: Dict) -> Optional[Dict]:
|
||||
"""Extract relevant game details from ESPN NCAA FB API response."""
|
||||
@@ -122,13 +96,6 @@ class Football(SportsCore):
|
||||
elif status["type"]["state"] == "pre":
|
||||
period_text = details.get("game_time", "") # Show time for upcoming
|
||||
|
||||
# Timeouts (assuming max 3 per half, not carried over well in standard API)
|
||||
# API often provides 'timeouts' directly under team, but reset logic is tricky
|
||||
# We might need to simplify this or just use a fixed display if API is unreliable
|
||||
# For upcoming games, we'll show based on number of games, not time window
|
||||
# For recent games, we'll show based on number of games, not time window
|
||||
is_within_window = True # Always include games, let the managers filter by count
|
||||
|
||||
details.update({
|
||||
"period": period,
|
||||
"period_text": period_text, # Formatted quarter/status
|
||||
@@ -155,17 +122,6 @@ class Football(SportsCore):
|
||||
logging.error(f"Error extracting game details: {e} from event: {game_event.get('id')}", exc_info=True)
|
||||
return None
|
||||
|
||||
def _fetch_todays_games(self, league: str) -> Optional[Dict]:
|
||||
"""Fetch only today's games for live updates (not entire season)."""
|
||||
return super()._fetch_todays_games("football", league)
|
||||
|
||||
def _get_weeks_data(self, league: str) -> Optional[Dict]:
|
||||
"""
|
||||
Get partial data for immediate display while background fetch is in progress.
|
||||
This fetches current/recent games only for quick response.
|
||||
"""
|
||||
return super()._get_weeks_data("football", league)
|
||||
|
||||
class FootballLive(Football):
|
||||
def __init__(self, config: Dict[str, Any], display_manager: DisplayManager, cache_manager: CacheManager, logger: logging.Logger, sport_key: str):
|
||||
super().__init__(config, display_manager, cache_manager, logger, sport_key)
|
||||
@@ -250,21 +206,19 @@ class FootballLive(Football):
|
||||
data = self._fetch_data()
|
||||
new_live_games = []
|
||||
if data and "events" in data:
|
||||
for event in data["events"]:
|
||||
details = self._extract_game_details(event)
|
||||
for game in data["events"]:
|
||||
details = self._extract_game_details(game)
|
||||
if details and (details["is_live"] or details["is_halftime"]):
|
||||
# If show_favorite_teams_only is true, only add if it's a favorite.
|
||||
# Otherwise, add all games.
|
||||
if self.mode_config.get("show_favorite_teams_only", False):
|
||||
if self.show_favorite_teams_only:
|
||||
if details["home_abbr"] in self.favorite_teams or details["away_abbr"] in self.favorite_teams:
|
||||
if self.show_odds:
|
||||
self._fetch_game_odds(details)
|
||||
new_live_games.append(details)
|
||||
else:
|
||||
if self.show_odds:
|
||||
self._fetch_game_odds(details)
|
||||
new_live_games.append(details)
|
||||
|
||||
for game in new_live_games:
|
||||
if self.show_odds:
|
||||
self._fetch_odds(game)
|
||||
# Log changes or periodically
|
||||
current_time_for_log = time.time() # Use a consistent time for logging comparison
|
||||
should_log = (
|
||||
@@ -276,12 +230,12 @@ class FootballLive(Football):
|
||||
|
||||
if should_log:
|
||||
if new_live_games:
|
||||
filter_text = "favorite teams" if self.mode_config.get("show_favorite_teams_only", False) else "all teams"
|
||||
filter_text = "favorite teams" if self.show_favorite_teams_only else "all teams"
|
||||
self.logger.info(f"Found {len(new_live_games)} live/halftime games for {filter_text}.")
|
||||
for game_info in new_live_games: # Renamed game to game_info
|
||||
self.logger.info(f" - {game_info['away_abbr']}@{game_info['home_abbr']} ({game_info.get('status_text', 'N/A')})")
|
||||
else:
|
||||
filter_text = "favorite teams" if self.mode_config.get("show_favorite_teams_only", False) else "criteria"
|
||||
filter_text = "favorite teams" if self.show_favorite_teams_only else "criteria"
|
||||
self.logger.info(f"No live/halftime games found for {filter_text}.")
|
||||
self.last_log_time = current_time_for_log
|
||||
|
||||
@@ -504,8 +458,7 @@ class FootballLive(Football):
|
||||
if away_abbr:
|
||||
if self.show_ranking and self.show_records:
|
||||
# When both rankings and records are enabled, rankings replace records completely
|
||||
rankings = self._fetch_team_rankings()
|
||||
away_rank = rankings.get(away_abbr, 0)
|
||||
away_rank = self._team_rankings_cache.get(away_abbr, 0)
|
||||
if away_rank > 0:
|
||||
away_text = f"#{away_rank}"
|
||||
else:
|
||||
@@ -513,8 +466,7 @@ class FootballLive(Football):
|
||||
away_text = ''
|
||||
elif self.show_ranking:
|
||||
# Show ranking only if available
|
||||
rankings = self._fetch_team_rankings()
|
||||
away_rank = rankings.get(away_abbr, 0)
|
||||
away_rank = self._team_rankings_cache.get(away_abbr, 0)
|
||||
if away_rank > 0:
|
||||
away_text = f"#{away_rank}"
|
||||
else:
|
||||
@@ -534,8 +486,7 @@ class FootballLive(Football):
|
||||
if home_abbr:
|
||||
if self.show_ranking and self.show_records:
|
||||
# When both rankings and records are enabled, rankings replace records completely
|
||||
rankings = self._fetch_team_rankings()
|
||||
home_rank = rankings.get(home_abbr, 0)
|
||||
home_rank = self._team_rankings_cache.get(home_abbr, 0)
|
||||
if home_rank > 0:
|
||||
home_text = f"#{home_rank}"
|
||||
else:
|
||||
@@ -543,8 +494,7 @@ class FootballLive(Football):
|
||||
home_text = ''
|
||||
elif self.show_ranking:
|
||||
# Show ranking only if available
|
||||
rankings = self._fetch_team_rankings()
|
||||
home_rank = rankings.get(home_abbr, 0)
|
||||
home_rank = self._team_rankings_cache.get(home_abbr, 0)
|
||||
if home_rank > 0:
|
||||
home_text = f"#{home_rank}"
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user