diff --git a/config/config.json b/config/config.json index f2d0bfd7..5161b5e9 100644 --- a/config/config.json +++ b/config/config.json @@ -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", diff --git a/src/milb_manager.py b/src/milb_manager.py index 117122dd..a6fbdccc 100644 --- a/src/milb_manager.py +++ b/src/milb_manager.py @@ -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) \ No newline at end of file + self.logger.error(f"[MiLB] Error displaying upcoming game: {e}", exc_info=True) \ No newline at end of file diff --git a/src/mlb_manager.py b/src/mlb_manager.py index 9ef6439d..d5ea28a5 100644 --- a/src/mlb_manager.py +++ b/src/mlb_manager.py @@ -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 diff --git a/src/nba_managers.py b/src/nba_managers.py index ef6cc14b..aae9d546 100644 --- a/src/nba_managers.py +++ b/src/nba_managers.py @@ -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] diff --git a/src/ncaa_baseball_managers.py b/src/ncaa_baseball_managers.py index df7594a6..96c41723 100644 --- a/src/ncaa_baseball_managers.py +++ b/src/ncaa_baseball_managers.py @@ -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 diff --git a/src/ncaa_fb_managers.py b/src/ncaa_fb_managers.py index ade55b02..23a7c107 100644 --- a/src/ncaa_fb_managers.py +++ b/src/ncaa_fb_managers.py @@ -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)) diff --git a/src/ncaam_basketball_managers.py b/src/ncaam_basketball_managers.py index db7ad8b2..c19f4c0e 100644 --- a/src/ncaam_basketball_managers.py +++ b/src/ncaam_basketball_managers.py @@ -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))) diff --git a/src/nfl_managers.py b/src/nfl_managers.py index 65924b74..9cd2b742 100644 --- a/src/nfl_managers.py +++ b/src/nfl_managers.py @@ -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 diff --git a/src/nhl_managers.py b/src/nhl_managers.py index 85489092..8db80d71 100644 --- a/src/nhl_managers.py +++ b/src/nhl_managers.py @@ -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: diff --git a/src/soccer_managers.py b/src/soccer_managers.py index ac1ae093..9cbb4197 100644 --- a/src/soccer_managers.py +++ b/src/soccer_managers.py @@ -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: