massive refactor on game filtering logic and odds calls for all sports displays

This commit is contained in:
Chuck
2025-07-22 11:06:54 -05:00
parent e238577f36
commit a580d87876
10 changed files with 303 additions and 206 deletions

View File

@@ -33,42 +33,42 @@
},
"display_durations": {
"clock": 15,
"weather": 15,
"weather": 30,
"stocks": 30,
"hourly_forecast": 15,
"daily_forecast": 15,
"hourly_forecast": 30,
"daily_forecast": 30,
"stock_news": 20,
"odds_ticker": 60,
"nhl_live": 30,
"nhl_recent": 20,
"nhl_upcoming": 20,
"nhl_recent": 30,
"nhl_upcoming": 30,
"nba_live": 30,
"nba_recent": 20,
"nba_upcoming": 20,
"nba_recent": 30,
"nba_upcoming": 30,
"nfl_live": 30,
"nfl_recent": 15,
"nfl_upcoming": 15,
"nfl_recent": 30,
"nfl_upcoming": 30,
"ncaa_fb_live": 30,
"ncaa_fb_recent": 15,
"ncaa_fb_upcoming": 15,
"ncaa_fb_recent": 30,
"ncaa_fb_upcoming": 30,
"ncaa_baseball_live": 30,
"ncaa_baseball_recent": 15,
"ncaa_baseball_upcoming": 15,
"ncaa_baseball_recent": 30,
"ncaa_baseball_upcoming": 30,
"calendar": 30,
"youtube": 20,
"youtube": 30,
"mlb_live": 30,
"mlb_recent": 20,
"mlb_upcoming": 20,
"mlb_recent": 30,
"mlb_upcoming": 30,
"milb_live": 30,
"milb_recent": 20,
"milb_upcoming": 20,
"milb_recent": 30,
"milb_upcoming": 30,
"text_display": 10,
"soccer_live": 30,
"soccer_recent": 20,
"soccer_upcoming": 20,
"ncaam_basketball_live": 20,
"ncaam_basketball_recent": 15,
"ncaam_basketball_upcoming": 15,
"soccer_recent": 30,
"soccer_upcoming": 30,
"ncaam_basketball_live": 30,
"ncaam_basketball_recent": 30,
"ncaam_basketball_upcoming": 30,
"music": 30
}
},
@@ -137,6 +137,7 @@
"live_update_interval": 30,
"recent_update_interval": 3600,
"upcoming_update_interval": 3600,
"show_favorite_teams_only": true,
"favorite_teams": ["TB"],
"logo_dir": "assets/sports/nhl_logos",
"show_records": true,
@@ -157,6 +158,7 @@
"recent_update_interval": 3600,
"upcoming_update_interval": 3600,
"recent_game_hours": 72,
"show_favorite_teams_only": true,
"favorite_teams": ["DAL"],
"logo_dir": "assets/sports/nba_logos",
"show_records": true,
@@ -176,6 +178,7 @@
"odds_update_interval": 3600,
"recent_games_to_show": 0,
"upcoming_games_to_show": 2,
"show_favorite_teams_only": true,
"favorite_teams": ["TB", "DAL"],
"logo_dir": "assets/sports/nfl_logos",
"show_records": true,
@@ -196,6 +199,7 @@
"season_cache_duration_seconds": 86400,
"recent_games_to_show": 0,
"upcoming_games_to_show": 2,
"show_favorite_teams_only": true,
"favorite_teams": ["UGA", "AUB"],
"logo_dir": "assets/sports/ncaa_fbs_logos",
"show_records": true,
@@ -214,6 +218,7 @@
"recent_update_interval": 3600,
"upcoming_update_interval": 3600,
"recent_game_hours": 72,
"show_favorite_teams_only": true,
"favorite_teams": ["UGA", "AUB"],
"logo_dir": "assets/sports/ncaa_fbs_logos",
"show_records": true,
@@ -230,6 +235,7 @@
"update_interval_seconds": 3600,
"live_update_interval": 30,
"recent_game_hours": 72,
"show_favorite_teams_only": true,
"favorite_teams": ["UGA", "AUB"],
"logo_dir": "assets/sports/ncaa_fbs_logos",
"show_records": true,
@@ -255,6 +261,7 @@
"upcoming_update_interval": 3600,
"recent_games_to_show": 1,
"upcoming_games_to_show": 1,
"show_favorite_teams_only": true,
"favorite_teams": ["TB", "TEX"],
"logo_dir": "assets/sports/mlb_logos",
"show_records": true,
@@ -302,6 +309,7 @@
"recent_update_interval": 3600,
"upcoming_update_interval": 3600,
"recent_game_hours": 168,
"show_favorite_teams_only": true,
"favorite_teams": ["LIV"],
"leagues": ["eng.1", "esp.1", "ger.1", "ita.1", "fra.1", "uefa.champions", "usa.1"],
"logo_dir": "assets/sports/soccer_logos",

View File

@@ -948,6 +948,8 @@ class MiLBRecentManager(BaseMiLBManager):
self.last_warning_time = 0
self.warning_cooldown = 300 # Only show warning every 5 minutes
logger.info(f"Initialized MiLBRecentManager with {len(self.favorite_teams)} favorite teams")
self.last_log_time = 0
self.log_interval = 300 # 5 minutes
def update(self):
"""Update recent games data."""
@@ -1002,14 +1004,13 @@ class MiLBRecentManager(BaseMiLBManager):
self.logger.info(f"[MiLB] Game Time: {game_time.isoformat()}")
self.logger.info(f"[MiLB] Is final: {is_final}")
self.logger.info(f"[MiLB] Status: {game['status']}, Status State: {game['status_state']}")
# Only add favorite team games that are final
if is_final:
self.logger.info(f"[MiLB] Adding game {game_id} to recent games list.")
new_recent_games.append(game)
logger.info(f"[MiLB] Added favorite team game to recent list: {game['away_team']} @ {game['home_team']}")
else:
logger.info(f"[MiLB] Skipping non-final game: {game['away_team']} @ {game['home_team']} (Status: {game['status_state']})")
self.logger.info(f"[MiLB] Skipping game {game_id} - not final.")
# Log summary of all games found
logger.info(f"[MiLB] All games found ({len(all_games_log)}): {all_games_log}")
@@ -1091,7 +1092,7 @@ class MiLBUpcomingManager(BaseMiLBManager):
"""Manager for upcoming MiLB games."""
def __init__(self, config: Dict[str, Any], display_manager):
super().__init__(config, display_manager)
self.logger.info("Initialized MiLB Upcoming Manager")
self.logger = logging.getLogger(__name__)
self.upcoming_games = []
self.current_game = None
self.current_game_index = 0
@@ -1102,75 +1103,76 @@ class MiLBUpcomingManager(BaseMiLBManager):
self.warning_cooldown = 300 # Only show warning every 5 minutes
self.last_game_switch = 0 # Track when we last switched games
self.game_display_duration = 10 # Display each game for 10 seconds
logger.info(f"Initialized MiLBUpcomingManager with {len(self.favorite_teams)} favorite teams")
self.logger.info(f"Initialized MiLBUpcomingManager with {len(self.favorite_teams)} favorite teams")
def update(self):
"""Update upcoming games data."""
current_time = time.time()
if current_time - self.last_update >= self.update_interval:
self.last_update = current_time
else:
self.logger.debug(f"[MiLB] show_favorite_teams_only: {self.milb_config.get('show_favorite_teams_only', False)}")
self.logger.debug(f"[MiLB] favorite_teams: {self.favorite_teams}")
if self.last_update != 0 and (current_time - self.last_update < self.update_interval):
return
try:
# Fetch data from MiLB API
games = self._fetch_milb_api_data()
if games:
# Process games
new_upcoming_games = []
if not games:
self.logger.warning("[MiLB] No games returned from API for upcoming games update.")
return
# --- Optimization: Filter for favorite teams before processing ---
if self.milb_config.get("show_favorite_teams_only", False) and self.favorite_teams:
games = {
game_id: game for game_id, game in games.items()
if game['home_team'] in self.favorite_teams or game['away_team'] in self.favorite_teams
}
self.logger.info(f"[MiLB Upcoming] Filtered to {len(games)} games for favorite teams.")
# Process games
new_upcoming_games = []
self.logger.info(f"[MiLB] Processing {len(games)} games for upcoming games...")
for game_id, game in games.items():
self.logger.debug(f"[MiLB] Processing game {game_id} for upcoming games...")
logger.info(f"[MiLB] Processing {len(games)} games for upcoming games...")
game_time = datetime.fromisoformat(game['start_time'].replace('Z', '+00:00'))
if game_time.tzinfo is None:
game_time = game_time.replace(tzinfo=timezone.utc)
for game_id, game in games.items():
# Only fetch odds for games that will be displayed
if self.milb_config.get("show_favorite_teams_only", False):
if not self.favorite_teams:
continue
if game['home_team'] not in self.favorite_teams and game['away_team'] not in self.favorite_teams:
continue
# Convert game time to UTC datetime
game_time_str = game['start_time'].replace('Z', '+00:00')
game_time = datetime.fromisoformat(game_time_str)
if game_time.tzinfo is None:
game_time = game_time.replace(tzinfo=timezone.utc)
# For upcoming games, we'll consider any game that:
# 1. Is not final (not 'post' or 'final' state)
# 2. Has a future start time
is_upcoming = (
game['status_state'] not in ['post', 'final', 'completed'] and
game_time > datetime.now(timezone.utc)
)
if is_upcoming:
if self.show_odds:
self._fetch_odds(game)
new_upcoming_games.append(game)
logger.info(f"[MiLB] Added favorite team game to upcoming list: {game['away_team']} @ {game['home_team']}")
is_upcoming = (
game['status_state'] not in ['post', 'final', 'completed'] and
game_time > datetime.now(timezone.utc)
)
# Sort by game time (soonest first) and limit to upcoming_games_to_show
new_upcoming_games.sort(key=lambda x: x['start_time'])
new_upcoming_games = new_upcoming_games[:self.upcoming_games_to_show]
if is_upcoming:
new_upcoming_games.append(game)
if new_upcoming_games:
logger.info(f"[MiLB] Found {len(new_upcoming_games)} upcoming games for favorite teams")
self.upcoming_games = new_upcoming_games
if not self.current_game:
self.current_game = self.upcoming_games[0]
else:
logger.info("[MiLB] No upcoming games found for favorite teams")
self.upcoming_games = []
self.current_game = None
# Sort by game time (soonest first) and limit to upcoming_games_to_show
new_upcoming_games.sort(key=lambda x: x['start_time'])
new_upcoming_games = new_upcoming_games[:self.upcoming_games_to_show]
self.last_update = current_time
if new_upcoming_games:
self.logger.info(f"[MiLB] Found {len(new_upcoming_games)} upcoming games for favorite teams")
self.upcoming_games = new_upcoming_games
if not self.current_game:
self.current_game = self.upcoming_games[0]
else:
self.logger.info("[MiLB] No upcoming games found for favorite teams")
self.upcoming_games = []
self.current_game = None
self.last_update = current_time
except Exception as e:
logger.error(f"[MiLB] Error updating upcoming games: {e}", exc_info=True)
self.logger.error(f"[MiLB] Error updating upcoming games: {e}", exc_info=True)
def display(self, force_clear: bool = False):
"""Display upcoming games."""
if not self.upcoming_games:
current_time = time.time()
if current_time - self.last_warning_time > self.warning_cooldown:
logger.info("[MiLB] No upcoming games to display")
self.logger.info("[MiLB] No upcoming games to display")
self.last_warning_time = current_time
return # Skip display update entirely
@@ -1186,10 +1188,11 @@ class MiLBUpcomingManager(BaseMiLBManager):
force_clear = True # Force clear when switching games
# Create and display the game image
game_image = self._create_game_display(self.current_game)
self.display_manager.image = game_image
self.display_manager.draw = ImageDraw.Draw(self.display_manager.image)
self.display_manager.update_display()
if self.current_game:
game_image = self._create_game_display(self.current_game)
self.display_manager.image = game_image
self.display_manager.draw = ImageDraw.Draw(self.display_manager.image)
self.display_manager.update_display()
except Exception as e:
logger.error(f"[MiLB] Error displaying upcoming game: {e}", exc_info=True)
self.logger.error(f"[MiLB] Error displaying upcoming game: {e}", exc_info=True)

View File

@@ -55,9 +55,21 @@ class BaseMLBManager:
def _fetch_odds(self, game: Dict) -> None:
"""Fetch odds for a game and attach it to the game dictionary."""
# Check if odds should be shown for this sport
if not self.show_odds:
return
# Check if we should only fetch for favorite teams
is_favorites_only = self.mlb_config.get("show_favorite_teams_only", False)
if is_favorites_only:
home_team = game.get('home_team')
away_team = game.get('away_team')
if not (home_team in self.favorite_teams or away_team in self.favorite_teams):
self.logger.debug(f"Skipping odds fetch for non-favorite game in favorites-only mode: {away_team}@{home_team}")
return
self.logger.debug(f"Proceeding with odds fetch for game: {game.get('id', 'N/A')}")
# Skip if odds are already attached to this game
if 'odds' in game and game['odds']:
return
@@ -777,7 +789,15 @@ class MLBLiveManager(BaseMLBManager):
new_live_games.append(game)
except (ValueError, TypeError):
self.logger.warning(f"Invalid score format for game {game['away_team']} @ {game['home_team']}")
else:
# Not in favorites-only mode, so add the game
try:
game['home_score'] = int(game['home_score'])
game['away_score'] = int(game['away_score'])
new_live_games.append(game)
except (ValueError, TypeError):
self.logger.warning(f"Invalid score format for game {game['away_team']} @ {game['home_team']}")
# Only log if there's a change in games or enough time has passed
should_log = (
current_time - self.last_log_time >= self.log_interval or

View File

@@ -368,13 +368,21 @@ class BaseNBAManager:
def _fetch_odds(self, game: Dict) -> None:
"""Fetch odds for a specific game if conditions are met."""
self.logger.debug(f"Checking odds for game: {game.get('id', 'N/A')}")
# Check if odds should be shown for this sport
if not self.show_odds:
self.logger.debug("Odds display is disabled for NBA.")
return
# Check if we should only fetch for favorite teams
is_favorites_only = self.nba_config.get("show_favorite_teams_only", False)
if is_favorites_only:
home_abbr = game.get('home_abbr')
away_abbr = game.get('away_abbr')
if not (home_abbr in self.favorite_teams or away_abbr in self.favorite_teams):
self.logger.debug(f"Skipping odds fetch for non-favorite game in favorites-only mode: {away_abbr}@{home_abbr}")
return
self.logger.debug(f"Proceeding with odds fetch for game: {game.get('id', 'N/A')}")
# Fetch odds using OddsManager (ESPN API)
try:
# Determine update interval based on game state
@@ -748,14 +756,7 @@ class NBALiveManager(BaseNBAManager):
for event in data["events"]:
details = self._extract_game_details(event)
if details and details["is_live"]:
# Only fetch odds for games that will be displayed
if self.nba_config.get("show_favorite_teams_only", False):
if not self.favorite_teams:
continue
if details["home_abbr"] not in self.favorite_teams and details["away_abbr"] not in self.favorite_teams:
continue
if self.show_odds:
self._fetch_odds(details)
self._fetch_odds(details)
new_live_games.append(details)
# Update game list and current game
@@ -806,13 +807,11 @@ class NBARecentManager(BaseNBAManager):
for event in events:
game = self._extract_game_details(event)
if game and game['is_final'] and game['is_within_window']:
# Fetch odds if enabled
if self.show_odds:
self._fetch_odds(game)
self._fetch_odds(game)
new_recent_games.append(game)
# Filter for favorite teams
if self.favorite_teams:
# Filter for favorite teams only if the config is set
if self.nba_config.get("show_favorite_teams_only", False):
team_games = [game for game in new_recent_games
if game['home_abbr'] in self.favorite_teams or
game['away_abbr'] in self.favorite_teams]
@@ -874,13 +873,11 @@ class NBAUpcomingManager(BaseNBAManager):
for event in events:
game = self._extract_game_details(event)
if game and game['is_upcoming']:
# Fetch odds if enabled
if self.show_odds:
self._fetch_odds(game)
self._fetch_odds(game)
self.upcoming_games.append(game)
# Filter for favorite teams
if self.favorite_teams:
# Filter for favorite teams only if the config is set
if self.nba_config.get("show_favorite_teams_only", False):
team_games = [game for game in self.upcoming_games
if game['home_abbr'] in self.favorite_teams or
game['away_abbr'] in self.favorite_teams]

View File

@@ -59,8 +59,20 @@ class BaseNCAABaseballManager:
def _fetch_odds(self, game: Dict) -> None:
"""Fetch odds for a game and attach it to the game dictionary."""
# Check if odds should be shown for this sport
if not self.show_odds:
return
# Check if we should only fetch for favorite teams
is_favorites_only = self.ncaa_baseball_config.get("show_favorite_teams_only", False)
if is_favorites_only:
home_team = game.get('home_team')
away_team = game.get('away_team')
if not (home_team in self.favorite_teams or away_team in self.favorite_teams):
self.logger.debug(f"Skipping odds fetch for non-favorite game in favorites-only mode: {away_team}@{home_team}")
return
self.logger.debug(f"Proceeding with odds fetch for game: {game.get('id', 'N/A')}")
try:
odds_data = self.odds_manager.get_odds(
@@ -579,14 +591,13 @@ class NCAABaseballLiveManager(BaseNCAABaseballManager):
new_live_games = []
for game in games.values():
if game['status_state'] == 'in':
if not self.favorite_teams or (game['home_team'] in self.favorite_teams or game['away_team'] in self.favorite_teams):
try:
game['home_score'] = int(game['home_score'])
game['away_score'] = int(game['away_score'])
self._fetch_odds(game)
new_live_games.append(game)
except (ValueError, TypeError):
self.logger.warning(f"[NCAABaseball] Invalid score format for game {game['away_team']} @ {game['home_team']}")
self._fetch_odds(game)
try:
game['home_score'] = int(game['home_score'])
game['away_score'] = int(game['away_score'])
new_live_games.append(game)
except (ValueError, TypeError):
self.logger.warning(f"[NCAABaseball] Invalid score format for game {game['away_team']} @ {game['home_team']}")
should_log = (
current_time - self.last_log_time >= self.log_interval or
@@ -867,9 +878,15 @@ class NCAABaseballRecentManager(BaseNCAABaseballManager):
new_recent_games.append(game)
logger.info(f"[NCAABaseball] Added favorite team game to recent list: {game['away_team']} @ {game['home_team']}")
if new_recent_games:
logger.info(f"[NCAABaseball] Found {len(new_recent_games)} recent games for favorite teams: {self.favorite_teams}")
self.recent_games = sorted(new_recent_games, key=lambda g: g.get('start_time'), reverse=True)
# Filter for favorite teams only if the config is set
if self.ncaa_baseball_config.get("show_favorite_teams_only", False):
team_games = [game for game in new_recent_games if game['home_team'] in self.favorite_teams or game['away_team'] in self.favorite_teams]
else:
team_games = new_recent_games
if team_games:
logger.info(f"[NCAABaseball] Found {len(team_games)} recent games for favorite teams: {self.favorite_teams}")
self.recent_games = sorted(team_games, key=lambda g: g.get('start_time'), reverse=True)
if not self.current_game or self.current_game.get('id') not in [g.get('id') for g in self.recent_games]:
self.current_game_index = 0
self.current_game = self.recent_games[0] if self.recent_games else None
@@ -960,9 +977,15 @@ class NCAABaseballUpcomingManager(BaseNCAABaseballManager):
new_upcoming_games.append(game)
logger.info(f"[NCAABaseball] Added favorite team game to upcoming list: {game['away_team']} @ {game['home_team']}")
if new_upcoming_games:
logger.info(f"[NCAABaseball] Found {len(new_upcoming_games)} upcoming games for favorite teams")
self.upcoming_games = sorted(new_upcoming_games, key=lambda g: g.get('start_time'))
# Filter for favorite teams only if the config is set
if self.ncaa_baseball_config.get("show_favorite_teams_only", False):
team_games = [game for game in new_upcoming_games if game['home_team'] in self.favorite_teams or game['away_team'] in self.favorite_teams]
else:
team_games = new_upcoming_games
if team_games:
logger.info(f"[NCAABaseball] Found {len(team_games)} upcoming games for favorite teams")
self.upcoming_games = sorted(team_games, key=lambda g: g.get('start_time'))
if not self.current_game or self.current_game.get('id') not in [g.get('id') for g in self.upcoming_games]:
self.current_game_index = 0
self.current_game = self.upcoming_games[0] if self.upcoming_games else None

View File

@@ -120,13 +120,21 @@ class BaseNCAAFBManager: # Renamed class
def _fetch_odds(self, game: Dict) -> None:
"""Fetch odds for a specific game if conditions are met."""
self.logger.debug(f"Checking odds for game: {game.get('id', 'N/A')}")
# Check if odds should be shown for this sport
if not self.show_odds:
self.logger.debug("Odds display is disabled for NCAAFB.")
return
# Check if we should only fetch for favorite teams
is_favorites_only = self.ncaa_fb_config.get("show_favorite_teams_only", False)
if is_favorites_only:
home_abbr = game.get('home_abbr')
away_abbr = game.get('away_abbr')
if not (home_abbr in self.favorite_teams or away_abbr in self.favorite_teams):
self.logger.debug(f"Skipping odds fetch for non-favorite game in favorites-only mode: {away_abbr}@{home_abbr}")
return
self.logger.debug(f"Proceeding with odds fetch for game: {game.get('id', 'N/A')}")
# Fetch odds using OddsManager (ESPN API)
try:
# Determine update interval based on game state
@@ -715,12 +723,15 @@ class NCAAFBLiveManager(BaseNCAAFBManager): # Renamed class
if data and "events" in data:
for event in data["events"]:
details = self._extract_game_details(event)
if details and (details["is_live"] or details["is_halftime"]): # Include halftime as 'live' display
if not self.favorite_teams or (
details["home_abbr"] in self.favorite_teams or
details["away_abbr"] in self.favorite_teams
):
# Fetch odds if enabled
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.ncaa_fb_config.get("show_favorite_teams_only", False):
if details["home_abbr"] in self.favorite_teams or details["away_abbr"] in self.favorite_teams:
if self.show_odds:
self._fetch_odds(details)
new_live_games.append(details)
else:
if self.show_odds:
self._fetch_odds(details)
new_live_games.append(details)
@@ -1212,15 +1223,13 @@ class NCAAFBUpcomingManager(BaseNCAAFBManager): # Renamed class
# Summary logging instead of verbose debug
self.logger.info(f"[NCAAFB Upcoming] Found {len(processed_games)} total upcoming games")
# Filter for favorite teams
if self.favorite_teams:
# Filter for favorite teams only if the config is set
if self.ncaa_fb_config.get("show_favorite_teams_only", False):
team_games = [game for game in processed_games
if game['home_abbr'] in self.favorite_teams or
game['away_abbr'] in self.favorite_teams]
self.logger.info(f"[NCAAFB Upcoming] Found {favorite_games_found} favorite team games out of {len(processed_games)} total upcoming games")
else:
team_games = processed_games # Show all upcoming if no favorites
self.logger.info(f"[NCAAFB Upcoming] Found {len(processed_games)} total upcoming games (no favorite teams configured)")
# Sort by game time, earliest first
team_games.sort(key=lambda g: g.get('start_time_utc') or datetime.max.replace(tzinfo=timezone.utc))

View File

@@ -72,8 +72,20 @@ class BaseNCAAMBasketballManager:
def _fetch_odds(self, game: Dict) -> None:
"""Fetch odds for a game and attach it to the game dictionary."""
# Check if odds should be shown for this sport
if not self.show_odds:
return
# Check if we should only fetch for favorite teams
is_favorites_only = self.ncaam_basketball_config.get("show_favorite_teams_only", False)
if is_favorites_only:
home_abbr = game.get('home_abbr')
away_abbr = game.get('away_abbr')
if not (home_abbr in self.favorite_teams or away_abbr in self.favorite_teams):
self.logger.debug(f"Skipping odds fetch for non-favorite game in favorites-only mode: {away_abbr}@{home_abbr}")
return
self.logger.debug(f"Proceeding with odds fetch for game: {game.get('id', 'N/A')}")
try:
odds_data = self.odds_manager.get_odds(
@@ -732,17 +744,13 @@ class NCAAMBasketballLiveManager(BaseNCAAMBasketballManager):
for event in data["events"]:
details = self._extract_game_details(event)
if details and details["is_live"]: # is_live includes 'in' and 'halftime'
if not self.favorite_teams or (
self._fetch_odds(details)
new_live_games.append(details)
if self.favorite_teams and (
details["home_abbr"] in self.favorite_teams or
details["away_abbr"] in self.favorite_teams
):
self._fetch_odds(details)
new_live_games.append(details)
if self.favorite_teams and (
details["home_abbr"] in self.favorite_teams or
details["away_abbr"] in self.favorite_teams
):
has_favorite_team = True
has_favorite_team = True
# Update favorite team game status
self.has_favorite_team_game = has_favorite_team
@@ -873,11 +881,13 @@ class NCAAMBasketballRecentManager(BaseNCAAMBasketballManager):
self._fetch_odds(game)
new_recent_games.append(game)
# Filter for favorite teams
new_team_games = [game for game in new_recent_games
if not self.favorite_teams or # Show all if no favorites
game['home_abbr'] in self.favorite_teams or
# Filter for favorite teams only if the config is set
if self.ncaam_basketball_config.get("show_favorite_teams_only", False):
new_team_games = [game for game in new_recent_games
if game['home_abbr'] in self.favorite_teams or
game['away_abbr'] in self.favorite_teams]
else:
new_team_games = new_recent_games
# Sort by game time (most recent first)
new_team_games.sort(key=lambda g: g.get('start_time_utc', datetime.min.replace(tzinfo=timezone.utc)), reverse=True)
@@ -1005,11 +1015,13 @@ class NCAAMBasketballUpcomingManager(BaseNCAAMBasketballManager):
new_upcoming_games.append(game)
self.logger.debug(f"Processing upcoming game: {game['away_abbr']} vs {game['home_abbr']}")
# Filter for favorite teams
team_games = [game for game in new_upcoming_games
if not self.favorite_teams or # Show all if no favorites
game['home_abbr'] in self.favorite_teams or
# Filter for favorite teams only if the config is set
if self.ncaam_basketball_config.get("show_favorite_teams_only", False):
team_games = [game for game in new_upcoming_games
if game['home_abbr'] in self.favorite_teams or
game['away_abbr'] in self.favorite_teams]
else:
team_games = new_upcoming_games
# Sort by game time (soonest first)
team_games.sort(key=lambda g: g.get('start_time_utc', datetime.max.replace(tzinfo=timezone.utc)))

View File

@@ -101,13 +101,21 @@ class BaseNFLManager: # Renamed class
def _fetch_odds(self, game: Dict) -> None:
"""Fetch odds for a specific game if conditions are met."""
self.logger.debug(f"Checking odds for game: {game.get('id', 'N/A')}")
# Check if odds should be shown for this sport
if not self.show_odds:
self.logger.debug("Odds display is disabled for NFL.")
return
# Check if we should only fetch for favorite teams
is_favorites_only = self.nfl_config.get("show_favorite_teams_only", False)
if is_favorites_only:
home_abbr = game.get('home_abbr')
away_abbr = game.get('away_abbr')
if not (home_abbr in self.favorite_teams or away_abbr in self.favorite_teams):
self.logger.debug(f"Skipping odds fetch for non-favorite game in favorites-only mode: {away_abbr}@{home_abbr}")
return
self.logger.debug(f"Proceeding with odds fetch for game: {game.get('id', 'N/A')}")
# Fetch odds using OddsManager (ESPN API)
try:
# Determine update interval based on game state
@@ -646,8 +654,7 @@ class NFLLiveManager(BaseNFLManager): # Renamed class
details["away_abbr"] in self.favorite_teams
):
# Fetch odds if enabled
if self.show_odds:
self._fetch_odds(details)
self._fetch_odds(details)
new_live_games.append(details)
# Log changes or periodically
@@ -905,12 +912,11 @@ class NFLRecentManager(BaseNFLManager): # Renamed class
# Filter criteria: must be final
if game and game['is_final']:
# Fetch odds if enabled
if self.show_odds:
self._fetch_odds(game)
self._fetch_odds(game)
processed_games.append(game)
# This check is now partially redundant if show_favorite_teams_only is true, but acts as the main filter otherwise
if self.favorite_teams:
# Filter for favorite teams only if the config is set
if self.nfl_config.get("show_favorite_teams_only", False):
team_games = [game for game in processed_games
if game['home_abbr'] in self.favorite_teams or
game['away_abbr'] in self.favorite_teams]
@@ -1130,23 +1136,14 @@ class NFLUpcomingManager(BaseNFLManager): # Renamed class
continue
if game['home_abbr'] not in self.favorite_teams and game['away_abbr'] not in self.favorite_teams:
continue
if self.show_odds:
self._fetch_odds(game)
self._fetch_odds(game)
processed_games.append(game)
# Debug logging to see what games we have
self.logger.debug(f"[NFL Upcoming] Processed {len(processed_games)} upcoming games")
for game in processed_games:
self.logger.debug(f"[NFL Upcoming] Game: {game['away_abbr']}@{game['home_abbr']} - Upcoming: {game['is_upcoming']}")
# This check is now partially redundant if show_favorite_teams_only is true, but acts as the main filter otherwise
if self.favorite_teams:
if self.nfl_config.get("show_favorite_teams_only", False):
team_games = [game for game in processed_games
if game['home_abbr'] in self.favorite_teams or
game['away_abbr'] in self.favorite_teams]
self.logger.debug(f"[NFL Upcoming] After favorite team filtering: {len(team_games)} games")
for game in team_games:
self.logger.debug(f"[NFL Upcoming] Favorite game: {game['away_abbr']}@{game['home_abbr']}")
else:
team_games = processed_games # Show all upcoming if no favorites

View File

@@ -121,8 +121,20 @@ class BaseNHLManager:
def _fetch_odds(self, game: Dict) -> None:
"""Fetch odds for a game and attach it to the game dictionary."""
# Check if odds should be shown for this sport
if not self.show_odds:
return
# Check if we should only fetch for favorite teams
is_favorites_only = self.nhl_config.get("show_favorite_teams_only", False)
if is_favorites_only:
home_abbr = game.get('home_abbr')
away_abbr = game.get('away_abbr')
if not (home_abbr in self.favorite_teams or away_abbr in self.favorite_teams):
self.logger.debug(f"Skipping odds fetch for non-favorite game in favorites-only mode: {away_abbr}@{home_abbr}")
return
self.logger.debug(f"Proceeding with odds fetch for game: {game.get('id', 'N/A')}")
try:
odds_data = self.odds_manager.get_odds(
@@ -677,12 +689,8 @@ class NHLLiveManager(BaseNHLManager):
for event in data["events"]:
details = self._extract_game_details(event)
if details and details["is_live"]:
if not self.favorite_teams or (
details["home_abbr"] in self.favorite_teams or
details["away_abbr"] in self.favorite_teams
):
self._fetch_odds(details)
new_live_games.append(details)
self._fetch_odds(details)
new_live_games.append(details)
# Only log if there's a change in games or enough time has passed
should_log = (
@@ -782,15 +790,17 @@ class NHLRecentManager(BaseNHLManager):
game = self._extract_game_details(event)
if game:
# Fetch odds if enabled
if self.show_odds:
self._fetch_odds(game)
self._fetch_odds(game)
self.recent_games.append(game)
self.logger.debug(f"Processing game: {game['away_abbr']} vs {game['home_abbr']} - Final: {game['is_final']}, Within window: {game['is_within_window']}")
# Filter for favorite teams
team_games = [game for game in self.recent_games
# Filter for favorite teams only if the config is set
if self.nhl_config.get("show_favorite_teams_only", False):
team_games = [game for game in self.recent_games
if game['home_abbr'] in self.favorite_teams or
game['away_abbr'] in self.favorite_teams]
else:
team_games = self.recent_games
self.logger.info(f"[NHL] Found {len(team_games)} recent games for favorite teams")
if not team_games:
@@ -878,15 +888,17 @@ class NHLUpcomingManager(BaseNHLManager):
if game['home_abbr'] not in self.favorite_teams and game['away_abbr'] not in self.favorite_teams:
continue
if not game['is_final'] and game['is_within_window']:
if self.show_odds:
self._fetch_odds(game)
self._fetch_odds(game)
new_upcoming_games.append(game)
self.logger.debug(f"[NHL] Added to upcoming games: {game['away_abbr']} vs {game['home_abbr']}")
# Filter for favorite teams
new_team_games = [game for game in new_upcoming_games
# Filter for favorite teams only if the config is set
if self.nhl_config.get("show_favorite_teams_only", False):
new_team_games = [game for game in new_upcoming_games
if game['home_abbr'] in self.favorite_teams or
game['away_abbr'] in self.favorite_teams]
else:
new_team_games = new_upcoming_games
# Log all upcoming games found *before* filtering by favorite teams
if new_upcoming_games:

View File

@@ -153,8 +153,20 @@ class BaseSoccerManager:
def _fetch_odds(self, game: Dict) -> None:
"""Fetch odds for a game and attach it to the game dictionary."""
# Check if odds should be shown for this sport
if not self.show_odds:
return
# Check if we should only fetch for favorite teams
is_favorites_only = self.soccer_config.get("show_favorite_teams_only", False)
if is_favorites_only:
home_abbr = game.get('home_abbr')
away_abbr = game.get('away_abbr')
if not (home_abbr in self.favorite_teams or away_abbr in self.favorite_teams):
self.logger.debug(f"Skipping odds fetch for non-favorite game in favorites-only mode: {away_abbr}@{home_abbr}")
return
self.logger.debug(f"Proceeding with odds fetch for game: {game.get('id', 'N/A')}")
try:
odds_data = self.odds_manager.get_odds(
@@ -856,12 +868,8 @@ class SoccerLiveManager(BaseSoccerManager):
details = self._extract_game_details(event)
# Ensure it's live and involves a favorite team (if specified)
if details and details["is_live"]:
if not self.favorite_teams or (
details["home_abbr"] in self.favorite_teams or
details["away_abbr"] in self.favorite_teams
):
self._fetch_odds(details)
new_live_games.append(details)
self._fetch_odds(details)
new_live_games.append(details)
# Logging
should_log = (current_time - self.last_log_time >= self.log_interval or
@@ -987,22 +995,26 @@ class SoccerRecentManager(BaseSoccerManager):
for event in data['events']:
game = self._extract_game_details(event)
if game and game['is_final'] and game['start_time_utc'] and game['start_time_utc'] >= cutoff_time:
# Check favorite teams if list is provided
if not self.favorite_teams or (game['home_abbr'] in self.favorite_teams or game['away_abbr'] in self.favorite_teams):
self._fetch_odds(game)
new_recent_games.append(game)
self._fetch_odds(game)
new_recent_games.append(game)
# Filter for favorite teams only if the config is set
if self.soccer_config.get("show_favorite_teams_only", False):
team_games = [game for game in new_recent_games if game['home_abbr'] in self.favorite_teams or game['away_abbr'] in self.favorite_teams]
else:
team_games = new_recent_games
# Sort games by start time, most recent first
new_recent_games.sort(key=lambda x: x['start_time_utc'], reverse=True)
team_games.sort(key=lambda x: x['start_time_utc'], reverse=True)
# Update only if the list content changes
new_ids = {g['id'] for g in new_recent_games}
new_ids = {g['id'] for g in team_games}
current_ids = {g['id'] for g in self.games_list}
if new_ids != current_ids:
self.logger.info(f"[Soccer] Found {len(new_recent_games)} recent games matching criteria.")
self.recent_games = new_recent_games # Keep raw filtered list
self.games_list = new_recent_games # Use the same list for display rotation
self.logger.info(f"[Soccer] Found {len(team_games)} recent games matching criteria.")
self.recent_games = team_games
self.games_list = team_games
# Reset display index if needed
if not self.current_game or self.current_game['id'] not in new_ids:
@@ -1090,34 +1102,38 @@ class SoccerUpcomingManager(BaseSoccerManager):
# Must be upcoming, have a start time, and be within the window
if game and game['is_upcoming'] and game['start_time_utc'] and \
game['start_time_utc'] >= now_utc and game['start_time_utc'] <= cutoff_time:
# Check favorite teams if list is provided
if not self.favorite_teams or (game['home_abbr'] in self.favorite_teams or game['away_abbr'] in self.favorite_teams):
self._fetch_odds(game)
new_upcoming_games.append(game)
self._fetch_odds(game)
new_upcoming_games.append(game)
# Filter for favorite teams only if the config is set
if self.soccer_config.get("show_favorite_teams_only", False):
team_games = [game for game in new_upcoming_games if game['home_abbr'] in self.favorite_teams or game['away_abbr'] in self.favorite_teams]
else:
team_games = new_upcoming_games
# Sort games by start time, soonest first
new_upcoming_games.sort(key=lambda x: x['start_time_utc'])
team_games.sort(key=lambda x: x['start_time_utc'])
# Update only if the list content changes
new_ids = {g['id'] for g in new_upcoming_games}
new_ids = {g['id'] for g in team_games}
current_ids = {g['id'] for g in self.upcoming_games}
if new_ids != current_ids:
# Logging
should_log = (current_time - self.last_log_time >= self.log_interval or
len(new_upcoming_games) != len(self.upcoming_games) or
len(team_games) != len(self.upcoming_games) or
not self.upcoming_games)
if should_log:
if new_upcoming_games:
self.logger.info(f"[Soccer] Found {len(new_upcoming_games)} upcoming games matching criteria.")
if team_games:
self.logger.info(f"[Soccer] Found {len(team_games)} upcoming games matching criteria.")
# Log first few games for brevity
for game in new_upcoming_games[:3]:
for game in team_games[:3]:
self.logger.info(f"[Soccer] Upcoming game: {game['away_abbr']} vs {game['home_abbr']} ({game['game_date']} {game['game_time']}) - {game['league']}")
else:
self.logger.info("[Soccer] No upcoming games found matching criteria.")
self.last_log_time = current_time
self.upcoming_games = new_upcoming_games
self.upcoming_games = team_games
# Reset display index if needed
if not self.current_game or self.current_game['id'] not in new_ids: