broadcast logo test py

This commit is contained in:
Chuck
2025-07-22 17:56:52 -05:00
parent 1a92389334
commit 2c0596baf6
4 changed files with 429 additions and 15 deletions

View File

@@ -1,7 +1,7 @@
{
"web_display_autostart": true,
"schedule": {
"enabled": false,
"enabled": true,
"start_time": "07:00",
"end_time": "23:00"
},
@@ -74,18 +74,18 @@
"use_short_date_format": true
},
"clock": {
"enabled": false,
"enabled": true,
"format": "%I:%M %p",
"update_interval": 1
},
"weather": {
"enabled": false,
"enabled": true,
"update_interval": 1800,
"units": "imperial",
"display_format": "{temp}°F\n{condition}"
},
"stocks": {
"enabled": false,
"enabled": true,
"update_interval": 600,
"symbols": [
"ASTS", "SCHD", "INTC", "NVDA", "T", "VOO", "SMCI"
@@ -93,7 +93,7 @@
"display_format": "{symbol}: ${price} ({change}%)"
},
"crypto": {
"enabled": false,
"enabled": true,
"update_interval": 600,
"symbols": [
"BTC-USD", "ETH-USD"
@@ -101,7 +101,7 @@
"display_format": "{symbol}: ${price} ({change}%)"
},
"stock_news": {
"enabled": false,
"enabled": true,
"update_interval": 3600,
"scroll_speed": 1,
"scroll_delay": 0.01,
@@ -285,6 +285,7 @@
"favorite_teams": ["TAM"],
"logo_dir": "assets/sports/milb_logos",
"show_records": true,
"upcoming_fetch_days": 7,
"display_modes": {
"milb_live": false,
"milb_recent": true,

View File

@@ -31,6 +31,8 @@ class OddsTickerManager:
"ESPN3": "espn3",
"ESPNU": "espnu",
"ESPNEWS": "espn",
"ESPN+": "espn",
"ESPN Plus": "espn",
"FOX": "fox",
"FS1": "fs1",
"FS2": "fs2",
@@ -44,7 +46,12 @@ class OddsTickerManager:
"SECN": "espn-sec-us",
"TBS": "tbs",
"TNT": "tnt",
"truTV": "tru"
"truTV": "tru",
"Peacock": "nbc",
"Paramount+": "cbs",
"Hulu": "espn",
"Disney+": "espn",
"Apple TV+": "nbc"
}
def __init__(self, config: Dict[str, Any], display_manager: DisplayManager):
@@ -368,7 +375,19 @@ class OddsTickerManager:
broadcasts = event.get('competitions', [{}])[0].get('broadcasts', [])
if broadcasts:
broadcast_info = [b.get('media', {}).get('shortName', '') for b in broadcasts if b.get('media', {}).get('shortName')]
logger.debug(f"Found broadcast channels for game {game_id}: {broadcast_info}")
logger.info(f"Found broadcast channels for game {game_id}: {broadcast_info}")
logger.debug(f"Raw broadcasts data for game {game_id}: {broadcasts}")
# Log the first broadcast structure for debugging
if broadcasts:
logger.debug(f"First broadcast structure: {broadcasts[0]}")
if 'media' in broadcasts[0]:
logger.debug(f"Media structure: {broadcasts[0]['media']}")
else:
logger.debug(f"No broadcasts data found for game {game_id}")
# Log the competitions structure to see what's available
competitions = event.get('competitions', [])
if competitions:
logger.debug(f"Competitions structure for game {game_id}: {competitions[0].keys()}")
# Only process favorite teams if enabled
if self.show_favorite_teams_only:
@@ -527,34 +546,43 @@ class OddsTickerManager:
home_logo = self._get_team_logo(game['home_team'], game['logo_dir'])
away_logo = self._get_team_logo(game['away_team'], game['logo_dir'])
broadcast_logo = None
# Enhanced broadcast logo debugging
if self.show_channel_logos:
broadcast_names = game.get('broadcast_info', []) # This is now a list
logger.debug(f"Game {game.get('id')}: Raw broadcast info from API: {broadcast_names}")
logger.info(f"Game {game.get('id')}: Raw broadcast info from API: {broadcast_names}")
logger.info(f"Game {game.get('id')}: show_channel_logos setting: {self.show_channel_logos}")
if broadcast_names:
logo_name = None
# Sort keys by length, descending, to match more specific names first (e.g., "ESPNEWS" before "ESPN")
sorted_keys = sorted(self.BROADCAST_LOGO_MAP.keys(), key=len, reverse=True)
logger.debug(f"Game {game.get('id')}: Available broadcast logo keys: {sorted_keys}")
for b_name in broadcast_names:
logger.debug(f"Game {game.get('id')}: Checking broadcast name: '{b_name}'")
for key in sorted_keys:
if key in b_name:
logo_name = self.BROADCAST_LOGO_MAP[key]
logger.info(f"Game {game.get('id')}: Matched '{key}' to logo '{logo_name}' for broadcast '{b_name}'")
break # Found the best match for this b_name
if logo_name:
break # Found a logo, stop searching through broadcast list
logger.debug(f"Game {game.get('id')}: Mapped logo name: '{logo_name}' from broadcast names: {broadcast_names}")
logger.info(f"Game {game.get('id')}: Final mapped logo name: '{logo_name}' from broadcast names: {broadcast_names}")
if logo_name:
broadcast_logo = self._get_team_logo(logo_name, 'assets/broadcast_logos')
if broadcast_logo:
logger.debug(f"Game {game.get('id')}: Successfully loaded broadcast logo for '{logo_name}'")
logger.info(f"Game {game.get('id')}: Successfully loaded broadcast logo for '{logo_name}' - Size: {broadcast_logo.size}")
else:
logger.warning(f"Game {game.get('id')}: Failed to load broadcast logo for '{logo_name}'")
# Check if the file exists
logo_path = os.path.join('assets', 'broadcast_logos', f"{logo_name}.png")
logger.warning(f"Game {game.get('id')}: Logo file exists: {os.path.exists(logo_path)}")
else:
logger.warning(f"Game {game.get('id')}: No mapping found for broadcast names {broadcast_names} in BROADCAST_LOGO_MAP")
else:
logger.debug(f"Game {game.get('id')}: No broadcast info available.")
logger.info(f"Game {game.get('id')}: No broadcast info available.")
if home_logo:
home_logo = home_logo.resize((logo_size, logo_size), Image.Resampling.LANCZOS)
@@ -569,7 +597,8 @@ class OddsTickerManager:
b_logo_w = int(broadcast_logo.width * ratio)
broadcast_logo = broadcast_logo.resize((b_logo_w, b_logo_h), Image.Resampling.LANCZOS)
broadcast_logo_col_width = b_logo_w
logger.info(f"Game {game.get('id')}: Resized broadcast logo to {broadcast_logo.size}, column width: {broadcast_logo_col_width}")
# Format date and time into 3 parts
game_time = game['start_time']
timezone_str = self.config.get('timezone', 'UTC')
@@ -659,7 +688,9 @@ class OddsTickerManager:
# Add width for the broadcast logo if it exists
if broadcast_logo:
total_width += broadcast_logo_col_width
total_width += broadcast_logo_col_width + h_padding # Add padding after broadcast logo
logger.info(f"Game {game.get('id')}: Total width calculation - logo_size: {logo_size}, vs_width: {vs_width}, team_info_width: {team_info_width}, odds_width: {odds_width}, datetime_col_width: {datetime_col_width}, broadcast_logo_col_width: {broadcast_logo_col_width}, total_width: {total_width}")
# --- Create final image ---
image = Image.new('RGB', (int(total_width), height), color=(0, 0, 0))
@@ -726,8 +757,12 @@ class OddsTickerManager:
if broadcast_logo:
# Position the broadcast logo in its own column
logo_y = (height - broadcast_logo.height) // 2
logger.debug(f"Pasting broadcast logo at ({int(current_x)}, {logo_y})")
logger.info(f"Game {game.get('id')}: Pasting broadcast logo at ({int(current_x)}, {logo_y})")
logger.info(f"Game {game.get('id')}: Broadcast logo size: {broadcast_logo.size}, image total width: {image.width}")
image.paste(broadcast_logo, (int(current_x), logo_y), broadcast_logo if broadcast_logo.mode == 'RGBA' else None)
logger.info(f"Game {game.get('id')}: Successfully pasted broadcast logo")
else:
logger.info(f"Game {game.get('id')}: No broadcast logo to paste")
return image

155
test_broadcast_logos.py Normal file
View File

@@ -0,0 +1,155 @@
#!/usr/bin/env python3
"""
Test script to debug broadcast logo display in odds ticker
"""
import os
import sys
import logging
from PIL import Image
# Add the src directory to the path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
from odds_ticker_manager import OddsTickerManager
from display_manager import DisplayManager
from config_manager import ConfigManager
# Set up logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
def test_broadcast_logo_loading():
"""Test broadcast logo loading functionality"""
# Load config
config_manager = ConfigManager()
config = config_manager.get_config()
# Create a mock display manager
class MockDisplayManager:
def __init__(self):
self.matrix = type('Matrix', (), {'width': 64, 'height': 32})()
self.image = None
self.draw = None
def update_display(self):
pass
display_manager = MockDisplayManager()
# Create odds ticker manager
odds_ticker = OddsTickerManager(config, display_manager)
# Test broadcast logo mapping
print("Testing broadcast logo mapping...")
test_broadcast_names = [
["ESPN"],
["FOX"],
["CBS"],
["NBC"],
["ESPN2"],
["FS1"],
["ESPNEWS"],
["ABC"],
["TBS"],
["TNT"],
["Unknown Channel"],
[]
]
for broadcast_names in test_broadcast_names:
print(f"\nTesting broadcast names: {broadcast_names}")
# Simulate the logo mapping logic
logo_name = None
sorted_keys = sorted(odds_ticker.BROADCAST_LOGO_MAP.keys(), key=len, reverse=True)
for b_name in broadcast_names:
for key in sorted_keys:
if key in b_name:
logo_name = odds_ticker.BROADCAST_LOGO_MAP[key]
break
if logo_name:
break
print(f"Mapped logo name: '{logo_name}'")
if logo_name:
# Test loading the actual logo
logo_path = os.path.join('assets', 'broadcast_logos', f"{logo_name}.png")
print(f"Logo path: {logo_path}")
print(f"File exists: {os.path.exists(logo_path)}")
if os.path.exists(logo_path):
try:
logo = Image.open(logo_path)
print(f"Successfully loaded logo: {logo.size} pixels")
except Exception as e:
print(f"Error loading logo: {e}")
else:
print("Logo file not found!")
def test_game_with_broadcast_info():
"""Test creating a game display with broadcast info"""
# Load config
config_manager = ConfigManager()
config = config_manager.get_config()
# Create a mock display manager
class MockDisplayManager:
def __init__(self):
self.matrix = type('Matrix', (), {'width': 64, 'height': 32})()
self.image = None
self.draw = None
def update_display(self):
pass
display_manager = MockDisplayManager()
# Create odds ticker manager
odds_ticker = OddsTickerManager(config, display_manager)
# Create a test game with broadcast info
test_game = {
'id': 'test_game_1',
'home_team': 'TB',
'away_team': 'BOS',
'home_team_name': 'Tampa Bay Rays',
'away_team_name': 'Boston Red Sox',
'start_time': '2024-01-15T19:00:00Z',
'home_record': '95-67',
'away_record': '78-84',
'broadcast_info': ['ESPN'],
'logo_dir': 'assets/sports/mlb_logos'
}
print(f"\nTesting game display with broadcast info: {test_game['broadcast_info']}")
try:
# Create the game display
game_image = odds_ticker._create_game_display(test_game)
print(f"Successfully created game image: {game_image.size} pixels")
# Save the image for inspection
output_path = 'test_broadcast_logo_output.png'
game_image.save(output_path)
print(f"Saved test image to: {output_path}")
except Exception as e:
print(f"Error creating game display: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
print("=== Testing Broadcast Logo Functionality ===\n")
# Test 1: Logo loading
test_broadcast_logo_loading()
# Test 2: Game display with broadcast info
test_game_with_broadcast_info()
print("\n=== Test Complete ===")

223
test_broadcast_logos_rpi.py Normal file
View File

@@ -0,0 +1,223 @@
#!/usr/bin/env python3
"""
Diagnostic script for broadcast logo display on Raspberry Pi
Run this on the Pi to test broadcast logo functionality
"""
import os
import sys
import logging
from PIL import Image
# Add the src directory to the path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
from odds_ticker_manager import OddsTickerManager
from display_manager import DisplayManager
from config_manager import ConfigManager
# Set up logging to see what's happening
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def test_broadcast_logo_files():
"""Test if broadcast logo files exist and can be loaded"""
print("=== Testing Broadcast Logo Files ===")
broadcast_logos_dir = "assets/broadcast_logos"
if not os.path.exists(broadcast_logos_dir):
print(f"ERROR: Broadcast logos directory not found: {broadcast_logos_dir}")
return False
print(f"Found broadcast logos directory: {broadcast_logos_dir}")
# Test a few key logos
test_logos = ["espn", "fox", "cbs", "nbc", "tbs", "tnt"]
for logo_name in test_logos:
logo_path = os.path.join(broadcast_logos_dir, f"{logo_name}.png")
if os.path.exists(logo_path):
try:
logo = Image.open(logo_path)
print(f"{logo_name}.png - Size: {logo.size}")
except Exception as e:
print(f"{logo_name}.png - Error loading: {e}")
else:
print(f"{logo_name}.png - File not found")
return True
def test_broadcast_logo_mapping():
"""Test the broadcast logo mapping logic"""
print("\n=== Testing Broadcast Logo Mapping ===")
# Load config
config_manager = ConfigManager()
config = config_manager.get_config()
# Create a mock display manager
class MockDisplayManager:
def __init__(self):
self.matrix = type('Matrix', (), {'width': 64, 'height': 32})()
self.image = None
self.draw = None
def update_display(self):
pass
display_manager = MockDisplayManager()
# Create odds ticker manager
odds_ticker = OddsTickerManager(config, display_manager)
# Test various broadcast names that might appear in the API
test_cases = [
["ESPN"],
["FOX"],
["CBS"],
["NBC"],
["ESPN2"],
["FS1"],
["ESPNEWS"],
["ESPN+"],
["ESPN Plus"],
["Peacock"],
["Paramount+"],
["ABC"],
["TBS"],
["TNT"],
["Unknown Channel"],
[]
]
for broadcast_names in test_cases:
print(f"\nTesting broadcast names: {broadcast_names}")
# Simulate the logo mapping logic
logo_name = None
sorted_keys = sorted(odds_ticker.BROADCAST_LOGO_MAP.keys(), key=len, reverse=True)
for b_name in broadcast_names:
for key in sorted_keys:
if key in b_name:
logo_name = odds_ticker.BROADCAST_LOGO_MAP[key]
break
if logo_name:
break
print(f" Mapped logo name: '{logo_name}'")
if logo_name:
# Test loading the actual logo
logo_path = os.path.join('assets', 'broadcast_logos', f"{logo_name}.png")
print(f" Logo path: {logo_path}")
print(f" File exists: {os.path.exists(logo_path)}")
if os.path.exists(logo_path):
try:
logo = Image.open(logo_path)
print(f" ✓ Successfully loaded logo: {logo.size} pixels")
except Exception as e:
print(f" ✗ Error loading logo: {e}")
else:
print(" ✗ Logo file not found!")
def test_game_display_with_broadcast():
"""Test creating a game display with broadcast info"""
print("\n=== Testing Game Display with Broadcast Info ===")
# Load config
config_manager = ConfigManager()
config = config_manager.get_config()
# Create a mock display manager
class MockDisplayManager:
def __init__(self):
self.matrix = type('Matrix', (), {'width': 64, 'height': 32})()
self.image = None
self.draw = None
def update_display(self):
pass
display_manager = MockDisplayManager()
# Create odds ticker manager
odds_ticker = OddsTickerManager(config, display_manager)
# Test cases with different broadcast info
test_games = [
{
'id': 'test_game_1',
'home_team': 'TB',
'away_team': 'BOS',
'home_team_name': 'Tampa Bay Rays',
'away_team_name': 'Boston Red Sox',
'start_time': '2024-01-15T19:00:00Z',
'home_record': '95-67',
'away_record': '78-84',
'broadcast_info': ['ESPN'],
'logo_dir': 'assets/sports/mlb_logos'
},
{
'id': 'test_game_2',
'home_team': 'NY',
'away_team': 'LA',
'home_team_name': 'New York Yankees',
'away_team_name': 'Los Angeles Dodgers',
'start_time': '2024-01-15T20:00:00Z',
'home_record': '82-80',
'away_record': '100-62',
'broadcast_info': ['FOX'],
'logo_dir': 'assets/sports/mlb_logos'
},
{
'id': 'test_game_3',
'home_team': 'CHI',
'away_team': 'MIA',
'home_team_name': 'Chicago Cubs',
'away_team_name': 'Miami Marlins',
'start_time': '2024-01-15T21:00:00Z',
'home_record': '83-79',
'away_record': '84-78',
'broadcast_info': [], # No broadcast info
'logo_dir': 'assets/sports/mlb_logos'
}
]
for i, test_game in enumerate(test_games):
print(f"\n--- Test Game {i+1}: {test_game['away_team']} @ {test_game['home_team']} ---")
print(f"Broadcast info: {test_game['broadcast_info']}")
try:
# Create the game display
game_image = odds_ticker._create_game_display(test_game)
print(f"✓ Successfully created game image: {game_image.size} pixels")
# Save the image for inspection
output_path = f'test_broadcast_logo_output_{i+1}.png'
game_image.save(output_path)
print(f"✓ Saved test image to: {output_path}")
except Exception as e:
print(f"✗ Error creating game display: {e}")
import traceback
traceback.print_exc()
if __name__ == "__main__":
print("=== Broadcast Logo Diagnostic Script ===\n")
# Test 1: Check if broadcast logo files exist
test_broadcast_logo_files()
# Test 2: Test broadcast logo mapping
test_broadcast_logo_mapping()
# Test 3: Test game display with broadcast info
test_game_display_with_broadcast()
print("\n=== Diagnostic Complete ===")
print("Check the generated PNG files to see if broadcast logos are being included.")