mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-11 13:23:00 +00:00
add granular control over records display and troubleshooting odds ticker. Enabled Team Records for all sports
This commit is contained in:
@@ -38,7 +38,7 @@
|
|||||||
"hourly_forecast": 15,
|
"hourly_forecast": 15,
|
||||||
"daily_forecast": 15,
|
"daily_forecast": 15,
|
||||||
"stock_news": 20,
|
"stock_news": 20,
|
||||||
"odds_ticker": 25,
|
"odds_ticker": 45,
|
||||||
"nhl_live": 30,
|
"nhl_live": 30,
|
||||||
"nhl_recent": 20,
|
"nhl_recent": 20,
|
||||||
"nhl_upcoming": 20,
|
"nhl_upcoming": 20,
|
||||||
@@ -112,9 +112,8 @@
|
|||||||
"show_favorite_teams_only": true,
|
"show_favorite_teams_only": true,
|
||||||
"enabled_leagues": ["mlb"],
|
"enabled_leagues": ["mlb"],
|
||||||
"update_interval": 3600,
|
"update_interval": 3600,
|
||||||
"scroll_speed": 2,
|
"scroll_speed": 1,
|
||||||
"scroll_delay": 0.05,
|
"scroll_delay": 0.001
|
||||||
"display_duration": 30
|
|
||||||
},
|
},
|
||||||
"calendar": {
|
"calendar": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
@@ -126,15 +125,16 @@
|
|||||||
},
|
},
|
||||||
"nhl_scoreboard": {
|
"nhl_scoreboard": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"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,
|
||||||
"recent_update_interval": 3600,
|
"recent_update_interval": 3600,
|
||||||
"upcoming_update_interval": 3600,
|
"upcoming_update_interval": 3600,
|
||||||
"recent_game_hours": 48,
|
"recent_game_hours": 48,
|
||||||
"favorite_teams": ["TB", "DAL"],
|
"favorite_teams": ["TB"],
|
||||||
"logo_dir": "assets/sports/nhl_logos",
|
"logo_dir": "assets/sports/nhl_logos",
|
||||||
|
"show_records": true,
|
||||||
"display_modes": {
|
"display_modes": {
|
||||||
"nhl_live": true,
|
"nhl_live": true,
|
||||||
"nhl_recent": true,
|
"nhl_recent": true,
|
||||||
@@ -142,8 +142,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nba_scoreboard": {
|
"nba_scoreboard": {
|
||||||
"enabled": true,
|
"enabled": false,
|
||||||
"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,
|
||||||
@@ -152,8 +152,9 @@
|
|||||||
"recent_update_interval": 3600,
|
"recent_update_interval": 3600,
|
||||||
"upcoming_update_interval": 3600,
|
"upcoming_update_interval": 3600,
|
||||||
"recent_game_hours": 72,
|
"recent_game_hours": 72,
|
||||||
"favorite_teams": ["DAL", "ATL"],
|
"favorite_teams": ["DAL"],
|
||||||
"logo_dir": "assets/sports/nba_logos",
|
"logo_dir": "assets/sports/nba_logos",
|
||||||
|
"show_records": true,
|
||||||
"display_modes": {
|
"display_modes": {
|
||||||
"nba_live": true,
|
"nba_live": true,
|
||||||
"nba_recent": true,
|
"nba_recent": true,
|
||||||
@@ -172,6 +173,7 @@
|
|||||||
"future_fetch_days": 7,
|
"future_fetch_days": 7,
|
||||||
"favorite_teams": ["TB", "DAL"],
|
"favorite_teams": ["TB", "DAL"],
|
||||||
"logo_dir": "assets/sports/nfl_logos",
|
"logo_dir": "assets/sports/nfl_logos",
|
||||||
|
"show_records": true,
|
||||||
"display_modes": {
|
"display_modes": {
|
||||||
"nfl_live": true,
|
"nfl_live": true,
|
||||||
"nfl_recent": true,
|
"nfl_recent": true,
|
||||||
@@ -180,7 +182,7 @@
|
|||||||
},
|
},
|
||||||
"ncaa_fb_scoreboard": {
|
"ncaa_fb_scoreboard": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"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,
|
||||||
@@ -190,30 +192,16 @@
|
|||||||
"future_fetch_days": 7,
|
"future_fetch_days": 7,
|
||||||
"favorite_teams": ["UGA", "AUB"],
|
"favorite_teams": ["UGA", "AUB"],
|
||||||
"logo_dir": "assets/sports/ncaa_fbs_logos",
|
"logo_dir": "assets/sports/ncaa_fbs_logos",
|
||||||
|
"show_records": true,
|
||||||
"display_modes": {
|
"display_modes": {
|
||||||
"ncaa_fb_live": true,
|
"ncaa_fb_live": true,
|
||||||
"ncaa_fb_recent": true,
|
"ncaa_fb_recent": true,
|
||||||
"ncaa_fb_upcoming": true
|
"ncaa_fb_upcoming": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ncaam_basketball_scoreboard": {
|
|
||||||
"enabled": false,
|
|
||||||
"show_odds": false,
|
|
||||||
"test_mode": false,
|
|
||||||
"update_interval_seconds": 3600,
|
|
||||||
"live_update_interval": 30,
|
|
||||||
"recent_game_hours": 72,
|
|
||||||
"favorite_teams": ["UGA", "AUB"],
|
|
||||||
"logo_dir": "assets/sports/ncaa_fbs_logos",
|
|
||||||
"display_modes": {
|
|
||||||
"ncaam_basketball_live": true,
|
|
||||||
"ncaam_basketball_recent": true,
|
|
||||||
"ncaam_basketball_upcoming": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ncaa_baseball_scoreboard": {
|
"ncaa_baseball_scoreboard": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"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,
|
||||||
@@ -222,12 +210,29 @@
|
|||||||
"recent_game_hours": 72,
|
"recent_game_hours": 72,
|
||||||
"favorite_teams": ["UGA", "AUB"],
|
"favorite_teams": ["UGA", "AUB"],
|
||||||
"logo_dir": "assets/sports/ncaa_fbs_logos",
|
"logo_dir": "assets/sports/ncaa_fbs_logos",
|
||||||
|
"show_records": true,
|
||||||
"display_modes": {
|
"display_modes": {
|
||||||
"ncaa_baseball_live": true,
|
"ncaa_baseball_live": true,
|
||||||
"ncaa_baseball_recent": true,
|
"ncaa_baseball_recent": true,
|
||||||
"ncaa_baseball_upcoming": true
|
"ncaa_baseball_upcoming": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ncaam_basketball_scoreboard": {
|
||||||
|
"enabled": false,
|
||||||
|
"show_odds": true,
|
||||||
|
"test_mode": false,
|
||||||
|
"update_interval_seconds": 3600,
|
||||||
|
"live_update_interval": 30,
|
||||||
|
"recent_game_hours": 72,
|
||||||
|
"favorite_teams": ["UGA", "AUB"],
|
||||||
|
"logo_dir": "assets/sports/ncaa_fbs_logos",
|
||||||
|
"show_records": true,
|
||||||
|
"display_modes": {
|
||||||
|
"ncaam_basketball_live": true,
|
||||||
|
"ncaam_basketball_recent": true,
|
||||||
|
"ncaam_basketball_upcoming": true
|
||||||
|
}
|
||||||
|
},
|
||||||
"youtube": {
|
"youtube": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"update_interval": 3600
|
"update_interval": 3600
|
||||||
@@ -245,6 +250,7 @@
|
|||||||
"recent_game_hours": 48,
|
"recent_game_hours": 48,
|
||||||
"favorite_teams": ["TB", "TEX"],
|
"favorite_teams": ["TB", "TEX"],
|
||||||
"logo_dir": "assets/sports/mlb_logos",
|
"logo_dir": "assets/sports/mlb_logos",
|
||||||
|
"show_records": true,
|
||||||
"display_modes": {
|
"display_modes": {
|
||||||
"mlb_live": false,
|
"mlb_live": false,
|
||||||
"mlb_recent": true,
|
"mlb_recent": true,
|
||||||
@@ -280,6 +286,7 @@
|
|||||||
},
|
},
|
||||||
"soccer_scoreboard": {
|
"soccer_scoreboard": {
|
||||||
"enabled": false,
|
"enabled": 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,
|
||||||
@@ -287,9 +294,10 @@
|
|||||||
"upcoming_update_interval": 3600,
|
"upcoming_update_interval": 3600,
|
||||||
"recent_game_hours": 168,
|
"recent_game_hours": 168,
|
||||||
"upcoming_fetch_days": 7,
|
"upcoming_fetch_days": 7,
|
||||||
"favorite_teams": ["BAR"],
|
"favorite_teams": ["LIV"],
|
||||||
"leagues": ["eng.1", "esp.1", "ger.1", "ita.1", "fra.1", "uefa.champions", "usa.1"],
|
"leagues": ["eng.1", "esp.1", "ger.1", "ita.1", "fra.1", "uefa.champions", "usa.1"],
|
||||||
"logo_dir": "assets/sports/soccer_logos",
|
"logo_dir": "assets/sports/soccer_logos",
|
||||||
|
"show_records": true,
|
||||||
"display_modes": {
|
"display_modes": {
|
||||||
"soccer_live": true,
|
"soccer_live": true,
|
||||||
"soccer_recent": true,
|
"soccer_recent": true,
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ class BaseMLBManager:
|
|||||||
self.mlb_config = config.get('mlb', {})
|
self.mlb_config = config.get('mlb', {})
|
||||||
self.show_odds = self.mlb_config.get("show_odds", False)
|
self.show_odds = self.mlb_config.get("show_odds", False)
|
||||||
self.favorite_teams = self.mlb_config.get('favorite_teams', [])
|
self.favorite_teams = self.mlb_config.get('favorite_teams', [])
|
||||||
|
self.show_records = self.mlb_config.get('show_records', False)
|
||||||
self.cache_manager = CacheManager()
|
self.cache_manager = CacheManager()
|
||||||
self.odds_manager = OddsManager(self.cache_manager, self.config)
|
self.odds_manager = OddsManager(self.cache_manager, self.config)
|
||||||
self.logger = logging.getLogger(__name__)
|
self.logger = logging.getLogger(__name__)
|
||||||
@@ -315,7 +316,7 @@ class BaseMLBManager:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
# Draw records for upcoming and recent games
|
# Draw records for upcoming and recent games
|
||||||
if game_data['status'] in ['status_scheduled', 'status_final', 'final', 'completed']:
|
if self.show_records and game_data['status'] in ['status_scheduled', 'status_final', 'final', 'completed']:
|
||||||
try:
|
try:
|
||||||
record_font = ImageFont.truetype("assets/fonts/4x6-font.ttf", 6)
|
record_font = ImageFont.truetype("assets/fonts/4x6-font.ttf", 6)
|
||||||
except IOError:
|
except IOError:
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ class BaseNBAManager:
|
|||||||
self.show_odds = self.nba_config.get("show_odds", False)
|
self.show_odds = self.nba_config.get("show_odds", False)
|
||||||
self.test_mode = self.nba_config.get("test_mode", False)
|
self.test_mode = self.nba_config.get("test_mode", False)
|
||||||
self.logo_dir = self.nba_config.get("logo_dir", "assets/sports/nba_logos")
|
self.logo_dir = self.nba_config.get("logo_dir", "assets/sports/nba_logos")
|
||||||
|
self.show_records = self.nba_config.get('show_records', False)
|
||||||
self.update_interval = self.nba_config.get("update_interval_seconds", 300)
|
self.update_interval = self.nba_config.get("update_interval_seconds", 300)
|
||||||
self.last_update = 0
|
self.last_update = 0
|
||||||
self.current_game = None
|
self.current_game = None
|
||||||
@@ -424,6 +425,8 @@ class BaseNBAManager:
|
|||||||
|
|
||||||
home_team = next(c for c in competitors if c.get("homeAway") == "home")
|
home_team = next(c for c in competitors if c.get("homeAway") == "home")
|
||||||
away_team = next(c for c in competitors if c.get("homeAway") == "away")
|
away_team = next(c for c in competitors if c.get("homeAway") == "away")
|
||||||
|
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 ''
|
||||||
|
|
||||||
# Format game time and date for display
|
# Format game time and date for display
|
||||||
game_time = ""
|
game_time = ""
|
||||||
@@ -452,9 +455,11 @@ class BaseNBAManager:
|
|||||||
"is_within_window": is_within_window,
|
"is_within_window": is_within_window,
|
||||||
"home_abbr": home_team["team"]["abbreviation"],
|
"home_abbr": home_team["team"]["abbreviation"],
|
||||||
"home_score": home_team.get("score", "0"),
|
"home_score": home_team.get("score", "0"),
|
||||||
|
"home_record": home_record,
|
||||||
"home_logo_path": os.path.join(self.logo_dir, f"{home_team['team']['abbreviation']}.png"),
|
"home_logo_path": os.path.join(self.logo_dir, f"{home_team['team']['abbreviation']}.png"),
|
||||||
"away_abbr": away_team["team"]["abbreviation"],
|
"away_abbr": away_team["team"]["abbreviation"],
|
||||||
"away_score": away_team.get("score", "0"),
|
"away_score": away_team.get("score", "0"),
|
||||||
|
"away_record": away_record,
|
||||||
"away_logo_path": os.path.join(self.logo_dir, f"{away_team['team']['abbreviation']}.png"),
|
"away_logo_path": os.path.join(self.logo_dir, f"{away_team['team']['abbreviation']}.png"),
|
||||||
"game_time": game_time,
|
"game_time": game_time,
|
||||||
"game_date": game_date
|
"game_date": game_date
|
||||||
@@ -581,6 +586,30 @@ class BaseNBAManager:
|
|||||||
if 'odds' in game and game['odds']:
|
if 'odds' in game and game['odds']:
|
||||||
self._draw_dynamic_odds(draw, game['odds'], self.display_width, self.display_height)
|
self._draw_dynamic_odds(draw, game['odds'], self.display_width, self.display_height)
|
||||||
|
|
||||||
|
# Draw records if enabled
|
||||||
|
if self.show_records:
|
||||||
|
try:
|
||||||
|
record_font = ImageFont.truetype("assets/fonts/4x6-font.ttf", 6)
|
||||||
|
except IOError:
|
||||||
|
record_font = ImageFont.load_default()
|
||||||
|
|
||||||
|
away_record = game.get('away_record', '')
|
||||||
|
home_record = game.get('home_record', '')
|
||||||
|
|
||||||
|
record_bbox = draw.textbbox((0,0), "0-0", font=record_font)
|
||||||
|
record_height = record_bbox[3] - record_bbox[1]
|
||||||
|
record_y = self.display_height - record_height - 1
|
||||||
|
|
||||||
|
if away_record:
|
||||||
|
away_record_x = 2
|
||||||
|
self._draw_text_with_outline(draw, away_record, (away_record_x, record_y), record_font)
|
||||||
|
|
||||||
|
if home_record:
|
||||||
|
home_record_bbox = draw.textbbox((0,0), home_record, font=record_font)
|
||||||
|
home_record_width = home_record_bbox[2] - home_record_bbox[0]
|
||||||
|
home_record_x = self.display_width - home_record_width - 2
|
||||||
|
self._draw_text_with_outline(draw, home_record, (home_record_x, record_y), record_font)
|
||||||
|
|
||||||
# Display the image
|
# Display the image
|
||||||
self.display_manager.image.paste(main_img, (0, 0))
|
self.display_manager.image.paste(main_img, (0, 0))
|
||||||
self.display_manager.update_display()
|
self.display_manager.update_display()
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ class BaseNCAABaseballManager:
|
|||||||
self.display_manager = display_manager
|
self.display_manager = display_manager
|
||||||
self.ncaa_baseball_config = config.get('ncaa_baseball_scoreboard', {})
|
self.ncaa_baseball_config = config.get('ncaa_baseball_scoreboard', {})
|
||||||
self.show_odds = self.ncaa_baseball_config.get('show_odds', False)
|
self.show_odds = self.ncaa_baseball_config.get('show_odds', False)
|
||||||
|
self.show_records = self.ncaa_baseball_config.get('show_records', False)
|
||||||
self.favorite_teams = self.ncaa_baseball_config.get('favorite_teams', [])
|
self.favorite_teams = self.ncaa_baseball_config.get('favorite_teams', [])
|
||||||
self.cache_manager = CacheManager()
|
self.cache_manager = CacheManager()
|
||||||
self.odds_manager = OddsManager(self.cache_manager, self.config)
|
self.odds_manager = OddsManager(self.cache_manager, self.config)
|
||||||
@@ -276,6 +277,29 @@ class BaseNCAABaseballManager:
|
|||||||
score_y = height - score_font.getmetrics()[0] - 2 # Adjusted for font metrics
|
score_y = height - score_font.getmetrics()[0] - 2 # Adjusted for font metrics
|
||||||
self._draw_text_with_outline(draw, score_text, (score_x, score_y), score_font)
|
self._draw_text_with_outline(draw, score_text, (score_x, score_y), score_font)
|
||||||
|
|
||||||
|
if self.show_records and game_data['status'] in ['status_scheduled', 'status_final', 'final', 'completed']:
|
||||||
|
try:
|
||||||
|
record_font = ImageFont.truetype("assets/fonts/4x6-font.ttf", 6)
|
||||||
|
except IOError:
|
||||||
|
record_font = ImageFont.load_default()
|
||||||
|
|
||||||
|
away_record = game_data.get('away_record', '')
|
||||||
|
home_record = game_data.get('home_record', '')
|
||||||
|
|
||||||
|
record_bbox = draw.textbbox((0, 0), "0-0", font=record_font)
|
||||||
|
record_height = record_bbox[3] - record_bbox[1]
|
||||||
|
record_y = height - record_height - 1
|
||||||
|
|
||||||
|
if away_record:
|
||||||
|
away_record_x = 2
|
||||||
|
self._draw_text_with_outline(draw, away_record, (away_record_x, record_y), record_font)
|
||||||
|
|
||||||
|
if home_record:
|
||||||
|
home_record_bbox = draw.textbbox((0, 0), home_record, font=record_font)
|
||||||
|
home_record_width = home_record_bbox[2] - home_record_bbox[0]
|
||||||
|
home_record_x = width - home_record_width - 2
|
||||||
|
self._draw_text_with_outline(draw, home_record, (home_record_x, record_y), record_font)
|
||||||
|
|
||||||
# Draw betting odds if available and enabled
|
# Draw betting odds if available and enabled
|
||||||
if self.show_odds and 'odds' in game_data:
|
if self.show_odds and 'odds' in game_data:
|
||||||
odds_details = game_data['odds'].get('details', 'N/A')
|
odds_details = game_data['odds'].get('details', 'N/A')
|
||||||
@@ -393,6 +417,8 @@ class BaseNCAABaseballManager:
|
|||||||
|
|
||||||
home_abbr = home_team['team'].get('abbreviation', 'N/A')
|
home_abbr = home_team['team'].get('abbreviation', 'N/A')
|
||||||
away_abbr = away_team['team'].get('abbreviation', 'N/A')
|
away_abbr = away_team['team'].get('abbreviation', 'N/A')
|
||||||
|
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 ''
|
||||||
|
|
||||||
is_favorite_game = (home_abbr in self.favorite_teams or away_abbr in self.favorite_teams)
|
is_favorite_game = (home_abbr in self.favorite_teams or away_abbr in self.favorite_teams)
|
||||||
|
|
||||||
@@ -455,6 +481,8 @@ class BaseNCAABaseballManager:
|
|||||||
'home_team': home_abbr,
|
'home_team': home_abbr,
|
||||||
'away_score': away_team.get('score', '0'),
|
'away_score': away_team.get('score', '0'),
|
||||||
'home_score': home_team.get('score', '0'),
|
'home_score': home_team.get('score', '0'),
|
||||||
|
'away_record': away_record,
|
||||||
|
'home_record': home_record,
|
||||||
'status': status,
|
'status': status,
|
||||||
'status_state': status_state,
|
'status_state': status_state,
|
||||||
'inning': inning,
|
'inning': inning,
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ class BaseNCAAFBManager: # Renamed class
|
|||||||
self.test_mode = self.ncaa_fb_config.get("test_mode", False)
|
self.test_mode = self.ncaa_fb_config.get("test_mode", False)
|
||||||
self.logo_dir = self.ncaa_fb_config.get("logo_dir", "assets/sports/ncaa_fbs_logos") # Changed logo dir
|
self.logo_dir = self.ncaa_fb_config.get("logo_dir", "assets/sports/ncaa_fbs_logos") # Changed logo dir
|
||||||
self.update_interval = self.ncaa_fb_config.get("update_interval_seconds", 60)
|
self.update_interval = self.ncaa_fb_config.get("update_interval_seconds", 60)
|
||||||
|
self.show_records = self.ncaa_fb_config.get('show_records', False)
|
||||||
self.last_update = 0
|
self.last_update = 0
|
||||||
self.current_game = None
|
self.current_game = None
|
||||||
self.fonts = self._load_fonts()
|
self.fonts = self._load_fonts()
|
||||||
@@ -424,6 +425,8 @@ class BaseNCAAFBManager: # Renamed class
|
|||||||
|
|
||||||
home_abbr = home_team["team"]["abbreviation"]
|
home_abbr = home_team["team"]["abbreviation"]
|
||||||
away_abbr = away_team["team"]["abbreviation"]
|
away_abbr = away_team["team"]["abbreviation"]
|
||||||
|
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 ''
|
||||||
|
|
||||||
# Filter by favorite teams if the list is not empty
|
# Filter by favorite teams if the list is not empty
|
||||||
if self.favorite_teams and not (home_abbr in self.favorite_teams or away_abbr in self.favorite_teams):
|
if self.favorite_teams and not (home_abbr in self.favorite_teams or away_abbr in self.favorite_teams):
|
||||||
@@ -497,10 +500,12 @@ class BaseNCAAFBManager: # Renamed class
|
|||||||
"is_halftime": status["type"]["state"] == "halftime", # Added halftime check
|
"is_halftime": status["type"]["state"] == "halftime", # Added halftime check
|
||||||
"home_abbr": home_abbr,
|
"home_abbr": home_abbr,
|
||||||
"home_score": home_team.get("score", "0"),
|
"home_score": home_team.get("score", "0"),
|
||||||
|
"home_record": home_record,
|
||||||
"home_logo_path": os.path.join(self.logo_dir, f"{home_abbr}.png"),
|
"home_logo_path": os.path.join(self.logo_dir, f"{home_abbr}.png"),
|
||||||
"home_timeouts": home_timeouts,
|
"home_timeouts": home_timeouts,
|
||||||
"away_abbr": away_abbr,
|
"away_abbr": away_abbr,
|
||||||
"away_score": away_team.get("score", "0"),
|
"away_score": away_team.get("score", "0"),
|
||||||
|
"away_record": away_record,
|
||||||
"away_logo_path": os.path.join(self.logo_dir, f"{away_abbr}.png"),
|
"away_logo_path": os.path.join(self.logo_dir, f"{away_abbr}.png"),
|
||||||
"away_timeouts": away_timeouts,
|
"away_timeouts": away_timeouts,
|
||||||
"game_time": game_time,
|
"game_time": game_time,
|
||||||
@@ -1019,6 +1024,30 @@ class NCAAFBRecentManager(BaseNCAAFBManager): # Renamed class
|
|||||||
if 'odds' in game and game['odds']:
|
if 'odds' in game and game['odds']:
|
||||||
self._draw_dynamic_odds(draw_overlay, game['odds'], self.display_width, self.display_height)
|
self._draw_dynamic_odds(draw_overlay, game['odds'], self.display_width, self.display_height)
|
||||||
|
|
||||||
|
# Draw records if enabled
|
||||||
|
if self.show_records:
|
||||||
|
try:
|
||||||
|
record_font = ImageFont.truetype("assets/fonts/4x6-font.ttf", 6)
|
||||||
|
except IOError:
|
||||||
|
record_font = ImageFont.load_default()
|
||||||
|
|
||||||
|
away_record = game.get('away_record', '')
|
||||||
|
home_record = game.get('home_record', '')
|
||||||
|
|
||||||
|
record_bbox = draw_overlay.textbbox((0,0), "0-0", font=record_font)
|
||||||
|
record_height = record_bbox[3] - record_bbox[1]
|
||||||
|
record_y = self.display_height - record_height - 1
|
||||||
|
|
||||||
|
if away_record:
|
||||||
|
away_record_x = 2
|
||||||
|
self._draw_text_with_outline(draw_overlay, away_record, (away_record_x, record_y), record_font)
|
||||||
|
|
||||||
|
if home_record:
|
||||||
|
home_record_bbox = draw_overlay.textbbox((0,0), home_record, font=record_font)
|
||||||
|
home_record_width = home_record_bbox[2] - home_record_bbox[0]
|
||||||
|
home_record_x = self.display_width - home_record_width - 2
|
||||||
|
self._draw_text_with_outline(draw_overlay, home_record, (home_record_x, record_y), record_font)
|
||||||
|
|
||||||
# Composite and display
|
# Composite and display
|
||||||
main_img = Image.alpha_composite(main_img, overlay)
|
main_img = Image.alpha_composite(main_img, overlay)
|
||||||
main_img = main_img.convert('RGB')
|
main_img = main_img.convert('RGB')
|
||||||
@@ -1213,6 +1242,30 @@ class NCAAFBUpcomingManager(BaseNCAAFBManager): # Renamed class
|
|||||||
if 'odds' in game and game['odds']:
|
if 'odds' in game and game['odds']:
|
||||||
self._draw_dynamic_odds(draw_overlay, game['odds'], self.display_width, self.display_height)
|
self._draw_dynamic_odds(draw_overlay, game['odds'], self.display_width, self.display_height)
|
||||||
|
|
||||||
|
# Draw records if enabled
|
||||||
|
if self.show_records:
|
||||||
|
try:
|
||||||
|
record_font = ImageFont.truetype("assets/fonts/4x6-font.ttf", 6)
|
||||||
|
except IOError:
|
||||||
|
record_font = ImageFont.load_default()
|
||||||
|
|
||||||
|
away_record = game.get('away_record', '')
|
||||||
|
home_record = game.get('home_record', '')
|
||||||
|
|
||||||
|
record_bbox = draw_overlay.textbbox((0,0), "0-0", font=record_font)
|
||||||
|
record_height = record_bbox[3] - record_bbox[1]
|
||||||
|
record_y = self.display_height - record_height - 1
|
||||||
|
|
||||||
|
if away_record:
|
||||||
|
away_record_x = 2
|
||||||
|
self._draw_text_with_outline(draw_overlay, away_record, (away_record_x, record_y), record_font)
|
||||||
|
|
||||||
|
if home_record:
|
||||||
|
home_record_bbox = draw_overlay.textbbox((0,0), home_record, font=record_font)
|
||||||
|
home_record_width = home_record_bbox[2] - home_record_bbox[0]
|
||||||
|
home_record_x = self.display_width - home_record_width - 2
|
||||||
|
self._draw_text_with_outline(draw_overlay, home_record, (home_record_x, record_y), record_font)
|
||||||
|
|
||||||
# Composite and display
|
# Composite and display
|
||||||
main_img = Image.alpha_composite(main_img, overlay)
|
main_img = Image.alpha_composite(main_img, overlay)
|
||||||
main_img = main_img.convert('RGB')
|
main_img = main_img.convert('RGB')
|
||||||
|
|||||||
@@ -44,8 +44,9 @@ class BaseNCAAMBasketballManager:
|
|||||||
self.is_enabled = self.ncaam_basketball_config.get("enabled", False)
|
self.is_enabled = self.ncaam_basketball_config.get("enabled", False)
|
||||||
self.show_odds = self.ncaam_basketball_config.get("show_odds", False)
|
self.show_odds = self.ncaam_basketball_config.get("show_odds", False)
|
||||||
self.test_mode = self.ncaam_basketball_config.get("test_mode", False)
|
self.test_mode = self.ncaam_basketball_config.get("test_mode", False)
|
||||||
self.logo_dir = self.ncaam_basketball_config.get("logo_dir", "assets/sports/ncaam_logos")
|
self.logo_dir = self.ncaam_basketball_config.get("logo_dir", "assets/sports/ncaa_fbs_logos")
|
||||||
self.update_interval = self.ncaam_basketball_config.get("update_interval_seconds", 300)
|
self.update_interval = self.ncaam_basketball_config.get("update_interval_seconds", 60)
|
||||||
|
self.show_records = self.ncaam_basketball_config.get('show_records', False)
|
||||||
self.last_update = 0
|
self.last_update = 0
|
||||||
self.current_game = None
|
self.current_game = None
|
||||||
self.fonts = self._load_fonts()
|
self.fonts = self._load_fonts()
|
||||||
@@ -421,6 +422,8 @@ class BaseNCAAMBasketballManager:
|
|||||||
|
|
||||||
home_team = next(c for c in competitors if c.get("homeAway") == "home")
|
home_team = next(c for c in competitors if c.get("homeAway") == "home")
|
||||||
away_team = next(c for c in competitors if c.get("homeAway") == "away")
|
away_team = next(c for c in competitors if c.get("homeAway") == "away")
|
||||||
|
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 ''
|
||||||
|
|
||||||
# Format game time and date for display
|
# Format game time and date for display
|
||||||
game_time = ""
|
game_time = ""
|
||||||
@@ -450,9 +453,11 @@ class BaseNCAAMBasketballManager:
|
|||||||
"is_within_window": is_within_window,
|
"is_within_window": is_within_window,
|
||||||
"home_abbr": home_team["team"]["abbreviation"],
|
"home_abbr": home_team["team"]["abbreviation"],
|
||||||
"home_score": home_team.get("score", "0"),
|
"home_score": home_team.get("score", "0"),
|
||||||
|
"home_record": home_record,
|
||||||
"home_logo_path": os.path.join(self.logo_dir, f"{home_team['team']['abbreviation']}.png"),
|
"home_logo_path": os.path.join(self.logo_dir, f"{home_team['team']['abbreviation']}.png"),
|
||||||
"away_abbr": away_team["team"]["abbreviation"],
|
"away_abbr": away_team["team"]["abbreviation"],
|
||||||
"away_score": away_team.get("score", "0"),
|
"away_score": away_team.get("score", "0"),
|
||||||
|
"away_record": away_record,
|
||||||
"away_logo_path": os.path.join(self.logo_dir, f"{away_team['team']['abbreviation']}.png"),
|
"away_logo_path": os.path.join(self.logo_dir, f"{away_team['team']['abbreviation']}.png"),
|
||||||
"game_time": game_time,
|
"game_time": game_time,
|
||||||
"game_date": game_date,
|
"game_date": game_date,
|
||||||
@@ -589,23 +594,32 @@ class BaseNCAAMBasketballManager:
|
|||||||
self._draw_text_with_outline(draw, clock, (clock_x, clock_y), self.fonts['time'])
|
self._draw_text_with_outline(draw, clock, (clock_x, clock_y), self.fonts['time'])
|
||||||
|
|
||||||
# Display odds if available
|
# Display odds if available
|
||||||
if 'odds' in game:
|
if 'odds' in game and game['odds']:
|
||||||
odds = game['odds']
|
self._draw_dynamic_odds(draw, game['odds'], self.display_width, self.display_height)
|
||||||
spread = odds.get('spread', {}).get('point', None)
|
|
||||||
if spread is not None:
|
# Draw records if enabled
|
||||||
# Format spread text
|
if self.show_records:
|
||||||
spread_text = f"{spread:+.1f}" if spread > 0 else f"{spread:.1f}"
|
try:
|
||||||
|
record_font = ImageFont.truetype("assets/fonts/4x6-font.ttf", 6)
|
||||||
# Choose color and position based on which team has the spread
|
except IOError:
|
||||||
if odds.get('spread', {}).get('team') == game['home_abbr']:
|
record_font = ImageFont.load_default()
|
||||||
text_color = (255, 100, 100) # Reddish
|
|
||||||
spread_x = self.display_width - draw.textlength(spread_text, font=self.fonts['status']) - 2
|
away_record = game.get('away_record', '')
|
||||||
else:
|
home_record = game.get('home_record', '')
|
||||||
text_color = (100, 255, 100) # Greenish
|
|
||||||
spread_x = 2
|
record_bbox = draw.textbbox((0,0), "0-0", font=record_font)
|
||||||
|
record_height = record_bbox[3] - record_bbox[1]
|
||||||
spread_y = self.display_height - 8
|
record_y = self.display_height - record_height - 1
|
||||||
self._draw_text_with_outline(draw, spread_text, (spread_x, spread_y), self.fonts['status'], fill=text_color)
|
|
||||||
|
if away_record:
|
||||||
|
away_record_x = 2
|
||||||
|
self._draw_text_with_outline(draw, away_record, (away_record_x, record_y), record_font)
|
||||||
|
|
||||||
|
if home_record:
|
||||||
|
home_record_bbox = draw.textbbox((0,0), home_record, font=record_font)
|
||||||
|
home_record_width = home_record_bbox[2] - home_record_bbox[0]
|
||||||
|
home_record_x = self.display_width - home_record_width - 2
|
||||||
|
self._draw_text_with_outline(draw, home_record, (home_record_x, record_y), record_font)
|
||||||
|
|
||||||
# Display the image
|
# Display the image
|
||||||
self.display_manager.image.paste(main_img, (0, 0))
|
self.display_manager.image.paste(main_img, (0, 0))
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ class BaseNFLManager: # Renamed class
|
|||||||
self.test_mode = self.nfl_config.get("test_mode", False)
|
self.test_mode = self.nfl_config.get("test_mode", False)
|
||||||
self.logo_dir = self.nfl_config.get("logo_dir", "assets/sports/nfl_logos") # Changed logo dir
|
self.logo_dir = self.nfl_config.get("logo_dir", "assets/sports/nfl_logos") # Changed logo dir
|
||||||
self.update_interval = self.nfl_config.get("update_interval_seconds", 60)
|
self.update_interval = self.nfl_config.get("update_interval_seconds", 60)
|
||||||
|
self.show_records = self.nfl_config.get('show_records', False)
|
||||||
self.last_update = 0
|
self.last_update = 0
|
||||||
self.current_game = None
|
self.current_game = None
|
||||||
self.fonts = self._load_fonts()
|
self.fonts = self._load_fonts()
|
||||||
@@ -424,6 +425,8 @@ class BaseNFLManager: # Renamed class
|
|||||||
|
|
||||||
home_abbr = home_team["team"]["abbreviation"]
|
home_abbr = home_team["team"]["abbreviation"]
|
||||||
away_abbr = away_team["team"]["abbreviation"]
|
away_abbr = away_team["team"]["abbreviation"]
|
||||||
|
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 ''
|
||||||
|
|
||||||
# Filter by favorite teams if the list is not empty
|
# Filter by favorite teams if the list is not empty
|
||||||
if self.favorite_teams and not (home_abbr in self.favorite_teams or away_abbr in self.favorite_teams):
|
if self.favorite_teams and not (home_abbr in self.favorite_teams or away_abbr in self.favorite_teams):
|
||||||
@@ -498,10 +501,12 @@ class BaseNFLManager: # Renamed class
|
|||||||
"is_halftime": status["type"]["state"] == "halftime", # Added halftime check
|
"is_halftime": status["type"]["state"] == "halftime", # Added halftime check
|
||||||
"home_abbr": home_abbr,
|
"home_abbr": home_abbr,
|
||||||
"home_score": home_team.get("score", "0"),
|
"home_score": home_team.get("score", "0"),
|
||||||
|
"home_record": home_record,
|
||||||
"home_logo_path": os.path.join(self.logo_dir, f"{home_abbr}.png"),
|
"home_logo_path": os.path.join(self.logo_dir, f"{home_abbr}.png"),
|
||||||
"home_timeouts": home_timeouts,
|
"home_timeouts": home_timeouts,
|
||||||
"away_abbr": away_abbr,
|
"away_abbr": away_abbr,
|
||||||
"away_score": away_team.get("score", "0"),
|
"away_score": away_team.get("score", "0"),
|
||||||
|
"away_record": away_record,
|
||||||
"away_logo_path": os.path.join(self.logo_dir, f"{away_abbr}.png"),
|
"away_logo_path": os.path.join(self.logo_dir, f"{away_abbr}.png"),
|
||||||
"away_timeouts": away_timeouts,
|
"away_timeouts": away_timeouts,
|
||||||
"game_time": game_time,
|
"game_time": game_time,
|
||||||
@@ -1008,6 +1013,30 @@ class NFLRecentManager(BaseNFLManager): # Renamed class
|
|||||||
if 'odds' in game and game['odds']:
|
if 'odds' in game and game['odds']:
|
||||||
self._draw_dynamic_odds(draw_overlay, game['odds'], self.display_width, self.display_height)
|
self._draw_dynamic_odds(draw_overlay, game['odds'], self.display_width, self.display_height)
|
||||||
|
|
||||||
|
# Draw records if enabled
|
||||||
|
if self.show_records:
|
||||||
|
try:
|
||||||
|
record_font = ImageFont.truetype("assets/fonts/4x6-font.ttf", 6)
|
||||||
|
except IOError:
|
||||||
|
record_font = ImageFont.load_default()
|
||||||
|
|
||||||
|
away_record = game.get('away_record', '')
|
||||||
|
home_record = game.get('home_record', '')
|
||||||
|
|
||||||
|
record_bbox = draw_overlay.textbbox((0,0), "0-0", font=record_font)
|
||||||
|
record_height = record_bbox[3] - record_bbox[1]
|
||||||
|
record_y = self.display_height - record_height - 1
|
||||||
|
|
||||||
|
if away_record:
|
||||||
|
away_record_x = 2
|
||||||
|
self._draw_text_with_outline(draw_overlay, away_record, (away_record_x, record_y), record_font)
|
||||||
|
|
||||||
|
if home_record:
|
||||||
|
home_record_bbox = draw_overlay.textbbox((0,0), home_record, font=record_font)
|
||||||
|
home_record_width = home_record_bbox[2] - home_record_bbox[0]
|
||||||
|
home_record_x = self.display_width - home_record_width - 2
|
||||||
|
self._draw_text_with_outline(draw_overlay, home_record, (home_record_x, record_y), record_font)
|
||||||
|
|
||||||
# Composite and display
|
# Composite and display
|
||||||
main_img = Image.alpha_composite(main_img, overlay)
|
main_img = Image.alpha_composite(main_img, overlay)
|
||||||
main_img = main_img.convert('RGB')
|
main_img = main_img.convert('RGB')
|
||||||
@@ -1205,6 +1234,30 @@ class NFLUpcomingManager(BaseNFLManager): # Renamed class
|
|||||||
if 'odds' in game and game['odds']:
|
if 'odds' in game and game['odds']:
|
||||||
self._draw_dynamic_odds(draw_overlay, game['odds'], self.display_width, self.display_height)
|
self._draw_dynamic_odds(draw_overlay, game['odds'], self.display_width, self.display_height)
|
||||||
|
|
||||||
|
# Draw records if enabled
|
||||||
|
if self.show_records:
|
||||||
|
try:
|
||||||
|
record_font = ImageFont.truetype("assets/fonts/4x6-font.ttf", 6)
|
||||||
|
except IOError:
|
||||||
|
record_font = ImageFont.load_default()
|
||||||
|
|
||||||
|
away_record = game.get('away_record', '')
|
||||||
|
home_record = game.get('home_record', '')
|
||||||
|
|
||||||
|
record_bbox = draw_overlay.textbbox((0,0), "0-0", font=record_font)
|
||||||
|
record_height = record_bbox[3] - record_bbox[1]
|
||||||
|
record_y = self.display_height - record_height - 1
|
||||||
|
|
||||||
|
if away_record:
|
||||||
|
away_record_x = 2
|
||||||
|
self._draw_text_with_outline(draw_overlay, away_record, (away_record_x, record_y), record_font)
|
||||||
|
|
||||||
|
if home_record:
|
||||||
|
home_record_bbox = draw_overlay.textbbox((0,0), home_record, font=record_font)
|
||||||
|
home_record_width = home_record_bbox[2] - home_record_bbox[0]
|
||||||
|
home_record_x = self.display_width - home_record_width - 2
|
||||||
|
self._draw_text_with_outline(draw_overlay, home_record, (home_record_x, record_y), record_font)
|
||||||
|
|
||||||
# Composite and display
|
# Composite and display
|
||||||
main_img = Image.alpha_composite(main_img, overlay)
|
main_img = Image.alpha_composite(main_img, overlay)
|
||||||
main_img = main_img.convert('RGB')
|
main_img = main_img.convert('RGB')
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ class BaseNHLManager:
|
|||||||
self.test_mode = self.nhl_config.get("test_mode", False) # Use test_mode from config
|
self.test_mode = self.nhl_config.get("test_mode", False) # Use test_mode from config
|
||||||
self.logo_dir = self.nhl_config.get("logo_dir", "assets/sports/nhl_logos")
|
self.logo_dir = self.nhl_config.get("logo_dir", "assets/sports/nhl_logos")
|
||||||
self.update_interval = self.nhl_config.get("update_interval_seconds", 60)
|
self.update_interval = self.nhl_config.get("update_interval_seconds", 60)
|
||||||
|
self.show_records = self.nhl_config.get('show_records', False)
|
||||||
self.last_update = 0
|
self.last_update = 0
|
||||||
self.current_game = None
|
self.current_game = None
|
||||||
self.fonts = self._load_fonts()
|
self.fonts = self._load_fonts()
|
||||||
@@ -364,6 +365,8 @@ class BaseNHLManager:
|
|||||||
|
|
||||||
home_team = next(c for c in competitors if c.get("homeAway") == "home")
|
home_team = next(c for c in competitors if c.get("homeAway") == "home")
|
||||||
away_team = next(c for c in competitors if c.get("homeAway") == "away")
|
away_team = next(c for c in competitors if c.get("homeAway") == "away")
|
||||||
|
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 ''
|
||||||
|
|
||||||
# Format game time and date for display
|
# Format game time and date for display
|
||||||
game_time = ""
|
game_time = ""
|
||||||
@@ -400,9 +403,11 @@ class BaseNHLManager:
|
|||||||
"is_within_window": is_within_window,
|
"is_within_window": is_within_window,
|
||||||
"home_abbr": home_team["team"]["abbreviation"],
|
"home_abbr": home_team["team"]["abbreviation"],
|
||||||
"home_score": home_team.get("score", "0"),
|
"home_score": home_team.get("score", "0"),
|
||||||
|
"home_record": home_record,
|
||||||
"home_logo_path": os.path.join(self.logo_dir, f"{home_team['team']['abbreviation']}.png"),
|
"home_logo_path": os.path.join(self.logo_dir, f"{home_team['team']['abbreviation']}.png"),
|
||||||
"away_abbr": away_team["team"]["abbreviation"],
|
"away_abbr": away_team["team"]["abbreviation"],
|
||||||
"away_score": away_team.get("score", "0"),
|
"away_score": away_team.get("score", "0"),
|
||||||
|
"away_record": away_record,
|
||||||
"away_logo_path": os.path.join(self.logo_dir, f"{away_team['team']['abbreviation']}.png"),
|
"away_logo_path": os.path.join(self.logo_dir, f"{away_team['team']['abbreviation']}.png"),
|
||||||
"game_time": game_time,
|
"game_time": game_time,
|
||||||
"game_date": game_date,
|
"game_date": game_date,
|
||||||
@@ -551,6 +556,30 @@ class BaseNHLManager:
|
|||||||
spread_y = self.display_height - 8
|
spread_y = self.display_height - 8
|
||||||
self._draw_text_with_outline(draw, spread_text, (spread_x, spread_y), self.fonts['status'], fill=text_color)
|
self._draw_text_with_outline(draw, spread_text, (spread_x, spread_y), self.fonts['status'], fill=text_color)
|
||||||
|
|
||||||
|
# Draw records if enabled
|
||||||
|
if self.show_records:
|
||||||
|
try:
|
||||||
|
record_font = ImageFont.truetype("assets/fonts/4x6-font.ttf", 6)
|
||||||
|
except IOError:
|
||||||
|
record_font = ImageFont.load_default()
|
||||||
|
|
||||||
|
away_record = game.get('away_record', '')
|
||||||
|
home_record = game.get('home_record', '')
|
||||||
|
|
||||||
|
record_bbox = draw.textbbox((0,0), "0-0", font=record_font)
|
||||||
|
record_height = record_bbox[3] - record_bbox[1]
|
||||||
|
record_y = self.display_height - record_height - 1
|
||||||
|
|
||||||
|
if away_record:
|
||||||
|
away_record_x = 2
|
||||||
|
self._draw_text_with_outline(draw, away_record, (away_record_x, record_y), record_font)
|
||||||
|
|
||||||
|
if home_record:
|
||||||
|
home_record_bbox = draw.textbbox((0,0), home_record, font=record_font)
|
||||||
|
home_record_width = home_record_bbox[2] - home_record_bbox[0]
|
||||||
|
home_record_x = self.display_width - home_record_width - 2
|
||||||
|
self._draw_text_with_outline(draw, home_record, (home_record_x, record_y), record_font)
|
||||||
|
|
||||||
# Display the image
|
# Display the image
|
||||||
self.display_manager.image.paste(main_img, (0, 0))
|
self.display_manager.image.paste(main_img, (0, 0))
|
||||||
self.display_manager.update_display()
|
self.display_manager.update_display()
|
||||||
|
|||||||
@@ -102,14 +102,30 @@ class OddsTickerManager:
|
|||||||
# This is a simplified implementation; a more robust solution would cache team data
|
# This is a simplified implementation; a more robust solution would cache team data
|
||||||
try:
|
try:
|
||||||
sport = 'baseball' if league == 'mlb' else 'football' if league in ['nfl', 'college-football'] else 'basketball'
|
sport = 'baseball' if league == 'mlb' else 'football' if league in ['nfl', 'college-football'] else 'basketball'
|
||||||
url = f"https://site.api.espn.com/apis/site/v2/sports/{sport}/{league}/teams/{team_abbr}"
|
|
||||||
|
# Use a more specific endpoint for college sports
|
||||||
|
if league == 'college-football':
|
||||||
|
url = f"https://site.api.espn.com/apis/site/v2/sports/football/college-football/teams/{team_abbr}"
|
||||||
|
else:
|
||||||
|
url = f"https://site.api.espn.com/apis/site/v2/sports/{sport}/{league}/teams/{team_abbr}"
|
||||||
|
|
||||||
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()
|
||||||
record = data.get('team', {}).get('record', {}).get('summary', 'N/A')
|
|
||||||
return record
|
# Different path for college sports records
|
||||||
|
if league == 'college-football':
|
||||||
|
record_items = data.get('team', {}).get('record', {}).get('items', [])
|
||||||
|
if record_items:
|
||||||
|
return record_items[0].get('summary', 'N/A')
|
||||||
|
else:
|
||||||
|
return 'N/A'
|
||||||
|
else:
|
||||||
|
record = data.get('team', {}).get('record', {}).get('summary', 'N/A')
|
||||||
|
return record
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error fetching record for {team_abbr}: {e}")
|
logger.error(f"Error fetching record for {team_abbr} in league {league}: {e}")
|
||||||
return "N/A"
|
return "N/A"
|
||||||
|
|
||||||
def _get_team_logo(self, team_abbr: str, logo_dir: str) -> Optional[Image.Image]:
|
def _get_team_logo(self, team_abbr: str, logo_dir: str) -> Optional[Image.Image]:
|
||||||
@@ -219,6 +235,10 @@ class OddsTickerManager:
|
|||||||
home_abbr = home_team['team']['abbreviation']
|
home_abbr = home_team['team']['abbreviation']
|
||||||
away_abbr = away_team['team']['abbreviation']
|
away_abbr = away_team['team']['abbreviation']
|
||||||
|
|
||||||
|
# Get records directly from the scoreboard feed
|
||||||
|
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 ''
|
||||||
|
|
||||||
# Check if this game involves favorite teams BEFORE fetching odds
|
# Check if this game involves favorite teams BEFORE fetching odds
|
||||||
if self.show_favorite_teams_only:
|
if self.show_favorite_teams_only:
|
||||||
favorite_teams = league_config.get('favorite_teams', [])
|
favorite_teams = league_config.get('favorite_teams', [])
|
||||||
@@ -253,10 +273,6 @@ class OddsTickerManager:
|
|||||||
logger.debug(f"Game {game_id} has no valid odds data, setting odds to None")
|
logger.debug(f"Game {game_id} has no valid odds data, setting odds to None")
|
||||||
odds_data = None
|
odds_data = None
|
||||||
|
|
||||||
# Fetch team records
|
|
||||||
home_record = self._fetch_team_record(home_abbr, league)
|
|
||||||
away_record = self._fetch_team_record(away_abbr, league)
|
|
||||||
|
|
||||||
game_data = {
|
game_data = {
|
||||||
'id': game_id,
|
'id': game_id,
|
||||||
'league': league_config['league'],
|
'league': league_config['league'],
|
||||||
@@ -385,29 +401,34 @@ class OddsTickerManager:
|
|||||||
|
|
||||||
# "vs." text
|
# "vs." text
|
||||||
vs_text = "vs."
|
vs_text = "vs."
|
||||||
vs_width = temp_draw.textlength(vs_text, font=vs_font)
|
vs_width = int(temp_draw.textlength(vs_text, font=vs_font))
|
||||||
|
|
||||||
# Team and record text
|
# Team and record text
|
||||||
away_team_text = f"{game.get('away_team', 'N/A')} ({game.get('away_record', '')})"
|
away_team_text = f"{game.get('away_team', 'N/A')} ({game.get('away_record', '') or 'N/A'})"
|
||||||
home_team_text = f"{game.get('home_team', 'N/A')} ({game.get('home_record', '')})"
|
home_team_text = f"{game.get('home_team', 'N/A')} ({game.get('home_record', '') or 'N/A'})"
|
||||||
away_team_width = temp_draw.textlength(away_team_text, font=team_font)
|
away_team_width = int(temp_draw.textlength(away_team_text, font=team_font))
|
||||||
home_team_width = temp_draw.textlength(home_team_text, font=team_font)
|
home_team_width = int(temp_draw.textlength(home_team_text, font=team_font))
|
||||||
team_info_width = max(away_team_width, home_team_width)
|
team_info_width = max(away_team_width, home_team_width)
|
||||||
|
|
||||||
# Odds text
|
# Odds text
|
||||||
odds = game.get('odds') or {}
|
odds = game.get('odds') or {}
|
||||||
home_team_odds = odds.get('home_team_odds', {})
|
home_team_odds = odds.get('home_team_odds', {})
|
||||||
away_team_odds = odds.get('away_team_odds', {})
|
away_team_odds = odds.get('away_team_odds', {})
|
||||||
home_spread = home_team_odds.get('spread_odds')
|
|
||||||
away_spread = away_team_odds.get('spread_odds')
|
# Determine the favorite and get the spread
|
||||||
|
home_spread = home_team_odds.get('point_spread')
|
||||||
|
away_spread = away_team_odds.get('point_spread')
|
||||||
|
|
||||||
|
# Check for valid spread values before comparing
|
||||||
|
home_favored = isinstance(home_spread, (int, float)) and home_spread < 0
|
||||||
|
away_favored = isinstance(away_spread, (int, float)) and away_spread < 0
|
||||||
|
|
||||||
over_under = odds.get('over_under')
|
over_under = odds.get('over_under')
|
||||||
|
|
||||||
home_favored = home_spread is not None and home_spread < 0
|
|
||||||
away_favored = away_spread is not None and away_spread < 0
|
|
||||||
|
|
||||||
away_odds_text = ""
|
away_odds_text = ""
|
||||||
home_odds_text = ""
|
home_odds_text = ""
|
||||||
|
|
||||||
|
# Simplified odds placement logic
|
||||||
if home_favored:
|
if home_favored:
|
||||||
home_odds_text = f"{home_spread}"
|
home_odds_text = f"{home_spread}"
|
||||||
if over_under:
|
if over_under:
|
||||||
@@ -416,11 +437,11 @@ class OddsTickerManager:
|
|||||||
away_odds_text = f"{away_spread}"
|
away_odds_text = f"{away_spread}"
|
||||||
if over_under:
|
if over_under:
|
||||||
home_odds_text = f"O/U {over_under}"
|
home_odds_text = f"O/U {over_under}"
|
||||||
elif over_under: # No clear favorite, put O/U on home line
|
elif over_under:
|
||||||
home_odds_text = f"O/U {over_under}"
|
home_odds_text = f"O/U {over_under}"
|
||||||
|
|
||||||
away_odds_width = temp_draw.textlength(away_odds_text, font=odds_font)
|
away_odds_width = int(temp_draw.textlength(away_odds_text, font=odds_font))
|
||||||
home_odds_width = temp_draw.textlength(home_odds_text, font=odds_font)
|
home_odds_width = int(temp_draw.textlength(home_odds_text, font=odds_font))
|
||||||
odds_width = max(away_odds_width, home_odds_width)
|
odds_width = max(away_odds_width, home_odds_width)
|
||||||
|
|
||||||
# --- Calculate total width ---
|
# --- Calculate total width ---
|
||||||
@@ -463,8 +484,12 @@ class OddsTickerManager:
|
|||||||
odds_font_height = odds_font.size if hasattr(odds_font, 'size') else 6
|
odds_font_height = odds_font.size if hasattr(odds_font, 'size') else 6
|
||||||
odds_y_away = 2
|
odds_y_away = 2
|
||||||
odds_y_home = height - odds_font_height - 2
|
odds_y_home = height - odds_font_height - 2
|
||||||
draw.text((current_x, odds_y_away), away_odds_text, font=odds_font, fill=(255, 255, 0)) # Yellow for odds
|
|
||||||
draw.text((current_x, odds_y_home), home_odds_text, font=odds_font, fill=(0, 255, 0)) # Green for favorite
|
# Use a consistent color for all odds text
|
||||||
|
odds_color = (255, 255, 0) # Yellow
|
||||||
|
|
||||||
|
draw.text((current_x, odds_y_away), away_odds_text, font=odds_font, fill=odds_color)
|
||||||
|
draw.text((current_x, odds_y_home), home_odds_text, font=odds_font, fill=odds_color)
|
||||||
|
|
||||||
return image
|
return image
|
||||||
|
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ class BaseSoccerManager:
|
|||||||
self.test_mode = self.soccer_config.get("test_mode", False)
|
self.test_mode = self.soccer_config.get("test_mode", False)
|
||||||
self.logo_dir = self.soccer_config.get("logo_dir", "assets/sports/soccer_logos") # Soccer logos
|
self.logo_dir = self.soccer_config.get("logo_dir", "assets/sports/soccer_logos") # Soccer logos
|
||||||
self.update_interval = self.soccer_config.get("update_interval_seconds", 60) # General fallback
|
self.update_interval = self.soccer_config.get("update_interval_seconds", 60) # General fallback
|
||||||
|
self.show_records = self.soccer_config.get('show_records', False)
|
||||||
self.last_update = 0
|
self.last_update = 0
|
||||||
self.current_game = None
|
self.current_game = None
|
||||||
self.fonts = self._load_fonts()
|
self.fonts = self._load_fonts()
|
||||||
@@ -552,6 +553,8 @@ class BaseSoccerManager:
|
|||||||
|
|
||||||
home_team = next(c for c in competitors if c.get("homeAway") == "home")
|
home_team = next(c for c in competitors if c.get("homeAway") == "home")
|
||||||
away_team = next(c for c in competitors if c.get("homeAway") == "away")
|
away_team = next(c for c in competitors if c.get("homeAway") == "away")
|
||||||
|
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 ''
|
||||||
|
|
||||||
game_time = ""
|
game_time = ""
|
||||||
game_date = ""
|
game_date = ""
|
||||||
@@ -589,9 +592,11 @@ class BaseSoccerManager:
|
|||||||
"is_within_window": is_within_window,
|
"is_within_window": is_within_window,
|
||||||
"home_abbr": home_team["team"]["abbreviation"],
|
"home_abbr": home_team["team"]["abbreviation"],
|
||||||
"home_score": home_team.get("score", "0"),
|
"home_score": home_team.get("score", "0"),
|
||||||
|
"home_record": home_record,
|
||||||
"home_logo": self._load_and_resize_logo(home_team["team"]["abbreviation"]),
|
"home_logo": self._load_and_resize_logo(home_team["team"]["abbreviation"]),
|
||||||
"away_abbr": away_team["team"]["abbreviation"],
|
"away_abbr": away_team["team"]["abbreviation"],
|
||||||
"away_score": away_team.get("score", "0"),
|
"away_score": away_team.get("score", "0"),
|
||||||
|
"away_record": away_record,
|
||||||
"away_logo": self._load_and_resize_logo(away_team["team"]["abbreviation"]),
|
"away_logo": self._load_and_resize_logo(away_team["team"]["abbreviation"]),
|
||||||
"game_time": game_time, # Formatted local time (e.g., 2:30pm)
|
"game_time": game_time, # Formatted local time (e.g., 2:30pm)
|
||||||
"game_date": game_date, # Formatted local date (e.g., 7/21)
|
"game_date": game_date, # Formatted local date (e.g., 7/21)
|
||||||
@@ -732,6 +737,30 @@ class BaseSoccerManager:
|
|||||||
spread_y = self.display_height - 8
|
spread_y = self.display_height - 8
|
||||||
self._draw_text_with_outline(draw, spread_text, (spread_x, spread_y), self.fonts['status'], fill=text_color)
|
self._draw_text_with_outline(draw, spread_text, (spread_x, spread_y), self.fonts['status'], fill=text_color)
|
||||||
|
|
||||||
|
# Draw records if enabled
|
||||||
|
if self.show_records:
|
||||||
|
try:
|
||||||
|
record_font = ImageFont.truetype("assets/fonts/4x6-font.ttf", 6)
|
||||||
|
except IOError:
|
||||||
|
record_font = ImageFont.load_default()
|
||||||
|
|
||||||
|
away_record = game.get('away_record', '')
|
||||||
|
home_record = game.get('home_record', '')
|
||||||
|
|
||||||
|
record_bbox = draw.textbbox((0,0), "0-0", font=record_font)
|
||||||
|
record_height = record_bbox[3] - record_bbox[1]
|
||||||
|
record_y = self.display_height - record_height - 1
|
||||||
|
|
||||||
|
if away_record:
|
||||||
|
away_record_x = 2
|
||||||
|
self._draw_text_with_outline(draw, away_record, (away_record_x, record_y), record_font)
|
||||||
|
|
||||||
|
if home_record:
|
||||||
|
home_record_bbox = draw.textbbox((0,0), home_record, font=record_font)
|
||||||
|
home_record_width = home_record_bbox[2] - home_record_bbox[0]
|
||||||
|
home_record_x = self.display_width - home_record_width - 2
|
||||||
|
self._draw_text_with_outline(draw, home_record, (home_record_x, record_y), record_font)
|
||||||
|
|
||||||
# --- Display Image ---
|
# --- Display Image ---
|
||||||
self.display_manager.image.paste(main_img, (0, 0))
|
self.display_manager.image.paste(main_img, (0, 0))
|
||||||
self.display_manager.update_display()
|
self.display_manager.update_display()
|
||||||
|
|||||||
Reference in New Issue
Block a user