mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 21:03:01 +00:00
make team logos larger on ticker and enable NFL & NCAA FB displays. Limit data pulls based on future fetch days and games per favorite
This commit is contained in:
@@ -168,8 +168,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nfl_scoreboard": {
|
"nfl_scoreboard": {
|
||||||
"enabled": false,
|
"enabled": true,
|
||||||
"show_odds": false,
|
"show_odds": true,
|
||||||
"test_mode": false,
|
"test_mode": false,
|
||||||
"update_interval_seconds": 3600,
|
"update_interval_seconds": 3600,
|
||||||
"live_update_interval": 30,
|
"live_update_interval": 30,
|
||||||
@@ -187,7 +187,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ncaa_fb_scoreboard": {
|
"ncaa_fb_scoreboard": {
|
||||||
"enabled": false,
|
"enabled": true,
|
||||||
"show_odds": true,
|
"show_odds": true,
|
||||||
"test_mode": false,
|
"test_mode": false,
|
||||||
"update_interval_seconds": 3600,
|
"update_interval_seconds": 3600,
|
||||||
|
|||||||
@@ -213,72 +213,59 @@ class OddsTickerManager:
|
|||||||
def _fetch_league_games(self, league_config: Dict[str, Any], now: datetime) -> List[Dict[str, Any]]:
|
def _fetch_league_games(self, league_config: Dict[str, Any], now: datetime) -> List[Dict[str, Any]]:
|
||||||
"""Fetch upcoming games for a specific league."""
|
"""Fetch upcoming games for a specific league."""
|
||||||
games = []
|
games = []
|
||||||
|
|
||||||
# Get dates for API request (yesterday, today, tomorrow - same as MLB manager)
|
|
||||||
yesterday = now - timedelta(days=1)
|
yesterday = now - timedelta(days=1)
|
||||||
# Use user-configurable future_fetch_days
|
|
||||||
future_window = now + timedelta(days=self.future_fetch_days)
|
future_window = now + timedelta(days=self.future_fetch_days)
|
||||||
# Build a list of dates from yesterday to future_window
|
|
||||||
num_days = (future_window - yesterday).days + 1
|
num_days = (future_window - yesterday).days + 1
|
||||||
dates = [(yesterday + timedelta(days=i)).strftime("%Y%m%d") for i in range(num_days)]
|
dates = [(yesterday + timedelta(days=i)).strftime("%Y%m%d") for i in range(num_days)]
|
||||||
|
|
||||||
|
# Optimization: If showing favorite teams only, track games found per team
|
||||||
|
favorite_teams = league_config.get('favorite_teams', []) if self.show_favorite_teams_only else []
|
||||||
|
team_games_found = {team: 0 for team in favorite_teams}
|
||||||
|
max_games = self.games_per_favorite_team if self.show_favorite_teams_only else None
|
||||||
|
all_games = []
|
||||||
|
|
||||||
for date in dates:
|
for date in dates:
|
||||||
|
if self.show_favorite_teams_only and all(team_games_found[t] >= max_games for t in favorite_teams):
|
||||||
|
break # All favorite teams have enough games, stop searching
|
||||||
try:
|
try:
|
||||||
# ESPN API endpoint for games with date parameter
|
|
||||||
sport = league_config['sport']
|
sport = league_config['sport']
|
||||||
league = league_config['league']
|
league = league_config['league']
|
||||||
url = f"https://site.api.espn.com/apis/site/v2/sports/{sport}/{league}/scoreboard?dates={date}"
|
url = f"https://site.api.espn.com/apis/site/v2/sports/{sport}/{league}/scoreboard?dates={date}"
|
||||||
|
|
||||||
logger.debug(f"Fetching {league} games from ESPN API for date: {date}")
|
logger.debug(f"Fetching {league} games from ESPN API for date: {date}")
|
||||||
response = requests.get(url, timeout=10)
|
response = requests.get(url, timeout=10)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
|
|
||||||
data = response.json()
|
data = response.json()
|
||||||
|
|
||||||
for event in data.get('events', []):
|
for event in data.get('events', []):
|
||||||
game_id = event['id']
|
game_id = event['id']
|
||||||
status = event['status']['type']['name'].lower()
|
status = event['status']['type']['name'].lower()
|
||||||
logger.debug(f"Event {game_id}: status={status}")
|
|
||||||
|
|
||||||
# Only include upcoming games (handle both 'scheduled' and 'status_scheduled')
|
|
||||||
if status in ['scheduled', 'pre-game', 'status_scheduled']:
|
if status in ['scheduled', 'pre-game', 'status_scheduled']:
|
||||||
game_time = datetime.fromisoformat(event['date'].replace('Z', '+00:00'))
|
game_time = datetime.fromisoformat(event['date'].replace('Z', '+00:00'))
|
||||||
|
|
||||||
# Only include games in the next 3 days (same as MLB manager)
|
|
||||||
if now <= game_time <= future_window:
|
if now <= game_time <= future_window:
|
||||||
# Get team information
|
|
||||||
competitors = event['competitions'][0]['competitors']
|
competitors = event['competitions'][0]['competitors']
|
||||||
home_team = next(c for c in competitors if c['homeAway'] == 'home')
|
home_team = next(c for c in competitors if c['homeAway'] == 'home')
|
||||||
away_team = next(c for c in competitors if c['homeAway'] == 'away')
|
away_team = next(c for c in competitors if c['homeAway'] == 'away')
|
||||||
|
|
||||||
home_abbr = home_team['team']['abbreviation']
|
home_abbr = home_team['team']['abbreviation']
|
||||||
away_abbr = away_team['team']['abbreviation']
|
away_abbr = away_team['team']['abbreviation']
|
||||||
|
# Only process favorite teams if enabled
|
||||||
# Get records directly from the scoreboard feed
|
if self.show_favorite_teams_only:
|
||||||
|
# Skip if both teams have already met their quota
|
||||||
|
for team in [home_abbr, away_abbr]:
|
||||||
|
if team in team_games_found and team_games_found[team] >= max_games:
|
||||||
|
continue
|
||||||
|
# Only add if at least one team still needs games
|
||||||
|
if not ((home_abbr in team_games_found and team_games_found[home_abbr] < max_games) or (away_abbr in team_games_found and team_games_found[away_abbr] < max_games)):
|
||||||
|
continue
|
||||||
|
# Build game dict (existing logic)
|
||||||
home_record = home_team.get('records', [{}])[0].get('summary', '') if home_team.get('records') else ''
|
home_record = home_team.get('records', [{}])[0].get('summary', '') if home_team.get('records') else ''
|
||||||
away_record = away_team.get('records', [{}])[0].get('summary', '') if away_team.get('records') else ''
|
away_record = away_team.get('records', [{}])[0].get('summary', '') if away_team.get('records') else ''
|
||||||
|
|
||||||
# Check if this game involves favorite teams BEFORE fetching odds
|
|
||||||
if self.show_favorite_teams_only:
|
|
||||||
favorite_teams = league_config.get('favorite_teams', [])
|
|
||||||
if home_abbr not in favorite_teams and away_abbr not in favorite_teams:
|
|
||||||
logger.debug(f"Skipping game {home_abbr} vs {away_abbr} - no favorite teams involved")
|
|
||||||
continue
|
|
||||||
|
|
||||||
logger.debug(f"Found upcoming game: {away_abbr} @ {home_abbr} on {game_time}")
|
|
||||||
|
|
||||||
# Fetch odds for this game (only if it involves favorite teams)
|
|
||||||
odds_data = self.odds_manager.get_odds(
|
odds_data = self.odds_manager.get_odds(
|
||||||
sport=sport,
|
sport=sport,
|
||||||
league=league,
|
league=league,
|
||||||
event_id=game_id,
|
event_id=game_id,
|
||||||
update_interval_seconds=7200 # Cache for 2 hours instead of 1 hour
|
update_interval_seconds=7200
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check if odds data has actual values (similar to MLB manager)
|
|
||||||
has_odds = False
|
has_odds = False
|
||||||
if odds_data and not odds_data.get('no_odds'):
|
if odds_data and not odds_data.get('no_odds'):
|
||||||
# Check if the odds data has any non-null values
|
|
||||||
if odds_data.get('spread') is not None:
|
if odds_data.get('spread') is not None:
|
||||||
has_odds = True
|
has_odds = True
|
||||||
if odds_data.get('home_team_odds', {}).get('spread_odds') is not None:
|
if odds_data.get('home_team_odds', {}).get('spread_odds') is not None:
|
||||||
@@ -287,34 +274,24 @@ class OddsTickerManager:
|
|||||||
has_odds = True
|
has_odds = True
|
||||||
if odds_data.get('over_under') is not None:
|
if odds_data.get('over_under') is not None:
|
||||||
has_odds = True
|
has_odds = True
|
||||||
|
game = {
|
||||||
if not has_odds:
|
|
||||||
logger.debug(f"Game {game_id} has no valid odds data, setting odds to None")
|
|
||||||
odds_data = None
|
|
||||||
|
|
||||||
game_data = {
|
|
||||||
'id': game_id,
|
'id': game_id,
|
||||||
'league': league_config['league'],
|
|
||||||
'league_key': league_config['sport'],
|
|
||||||
'home_team': home_abbr,
|
'home_team': home_abbr,
|
||||||
'away_team': away_abbr,
|
'away_team': away_abbr,
|
||||||
'start_time': game_time,
|
'start_time': game_time,
|
||||||
'odds': odds_data,
|
|
||||||
'logo_dir': league_config['logo_dir'],
|
|
||||||
'home_record': home_record,
|
'home_record': home_record,
|
||||||
'away_record': away_record
|
'away_record': away_record,
|
||||||
|
'odds': odds_data if has_odds else None
|
||||||
}
|
}
|
||||||
|
all_games.append(game)
|
||||||
games.append(game_data)
|
# If favorite teams only, increment counters
|
||||||
else:
|
if self.show_favorite_teams_only:
|
||||||
logger.debug(f"Game {game_id} is outside 3-day window: {game_time}")
|
for team in [home_abbr, away_abbr]:
|
||||||
else:
|
if team in team_games_found and team_games_found[team] < max_games:
|
||||||
logger.debug(f"Game {game_id} has status '{status}', skipping")
|
team_games_found[team] += 1
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error fetching {league_config['league']} games for date {date}: {e}")
|
logger.error(f"Error fetching games for {league_config.get('league', 'unknown')} on {date}: {e}", exc_info=True)
|
||||||
|
return all_games
|
||||||
return games
|
|
||||||
|
|
||||||
def _format_odds_text(self, game: Dict[str, Any]) -> str:
|
def _format_odds_text(self, game: Dict[str, Any]) -> str:
|
||||||
"""Format the odds text for display."""
|
"""Format the odds text for display."""
|
||||||
@@ -393,9 +370,9 @@ class OddsTickerManager:
|
|||||||
height = self.display_manager.matrix.height
|
height = self.display_manager.matrix.height
|
||||||
|
|
||||||
# Make logos use most of the display height, with a small margin
|
# Make logos use most of the display height, with a small margin
|
||||||
logo_margin = 2
|
logo_margin = 0
|
||||||
logo_size = height - 2 * logo_margin
|
logo_size = int(height * 1.2)
|
||||||
logo_padding = 5
|
logo_padding = 2
|
||||||
vs_padding = 8
|
vs_padding = 8
|
||||||
section_padding = 12
|
section_padding = 12
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user