From 457f9f9eb551894e94e35b17823a1610d0bcc521 Mon Sep 17 00:00:00 2001 From: Chuck <33324927+ChuckBuilds@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:45:34 -0400 Subject: [PATCH] better error handling and correct image call for top 25 --- src/leaderboard_manager.py | 8 +- test/README_broadcast_logo_analyzer.md | 103 ++++++ test/analyze_broadcast_logos.py | 418 +++++++++++++++++++++++++ test/broadcast_logo_analysis.json | 326 +++++++++++++++++++ 4 files changed, 853 insertions(+), 2 deletions(-) create mode 100644 test/README_broadcast_logo_analyzer.md create mode 100644 test/analyze_broadcast_logos.py create mode 100644 test/broadcast_logo_analysis.json diff --git a/src/leaderboard_manager.py b/src/leaderboard_manager.py index 4011afb9..c3ea8221 100644 --- a/src/leaderboard_manager.py +++ b/src/leaderboard_manager.py @@ -469,7 +469,9 @@ class LeaderboardManager: draw.text((x, y), text, font=self.fonts['medium'], fill=(255, 255, 255)) - self.display_manager.set_image(image) + self.display_manager.image = image + self.display_manager.draw = ImageDraw.Draw(self.display_manager.image) + self.display_manager.update_display() except Exception as e: logger.error(f"Error displaying fallback message: {e}") @@ -582,7 +584,9 @@ class LeaderboardManager: )) # Display the visible portion - self.display_manager.set_image(visible_image) + self.display_manager.image = visible_image + self.display_manager.draw = ImageDraw.Draw(self.display_manager.image) + self.display_manager.update_display() except Exception as e: logger.error(f"Error in leaderboard display: {e}") diff --git a/test/README_broadcast_logo_analyzer.md b/test/README_broadcast_logo_analyzer.md new file mode 100644 index 00000000..d23f74c0 --- /dev/null +++ b/test/README_broadcast_logo_analyzer.md @@ -0,0 +1,103 @@ +# Broadcast Logo Analyzer + +This script analyzes broadcast channel logos to ensure we have proper logos for every game and identifies missing or problematic logos that might show as white boxes. + +## Important Notes + +**This script must be run on the Raspberry Pi** where the LEDMatrix project is located, as it needs to access the actual logo files in the `assets/broadcast_logos/` directory. + +## Usage + +### On Raspberry Pi (Recommended) + +```bash +# SSH into your Raspberry Pi +ssh pi@your-pi-ip + +# Navigate to the LEDMatrix project directory +cd /path/to/LEDMatrix + +# Run the analyzer +python test/analyze_broadcast_logos.py +``` + +### Local Testing (Optional) + +If you want to test the script logic locally, you can: + +1. Copy some logo files from your Pi to your local machine +2. Place them in `assets/broadcast_logos/` directory +3. Run the script locally + +## What the Script Does + +1. **Checks Logo Mappings**: Verifies all broadcast channel names in `BROADCAST_LOGO_MAP` have corresponding logo files +2. **Validates File Existence**: Ensures all referenced logo files actually exist +3. **Analyzes Logo Quality**: + - Checks dimensions (too small/large) + - Analyzes transparency handling + - Detects potential white box issues + - Measures content density +4. **Identifies Issues**: + - Missing logos + - Problematic logos (corrupted, too transparent, etc.) + - Orphaned logo files (exist but not mapped) +5. **Generates Report**: Creates both console output and JSON report + +## Output + +The script generates: +- **Console Report**: Detailed analysis with recommendations +- **JSON Report**: `test/broadcast_logo_analysis.json` with structured data + +## Common Issues Found + +- **White Boxes**: Usually caused by: + - Missing logo files + - Corrupted image files + - Images that are mostly transparent + - Images with very low content density +- **Missing Logos**: Broadcast channels that don't have corresponding logo files +- **Orphaned Logos**: Logo files that exist but aren't mapped to any broadcast channel + +## Recommendations + +The script provides specific recommendations for each issue found, such as: +- Adding missing logo files +- Fixing problematic logos +- Optimizing logo dimensions +- Ensuring proper transparency handling + +## Example Output + +``` +BROADCAST LOGO ANALYSIS REPORT +================================================================================ + +SUMMARY: + Total broadcast mappings: 44 + Existing logos: 40 + Missing logos: 2 + Problematic logos: 2 + Orphaned logos: 1 + +MISSING LOGOS (2): +-------------------------------------------------- + New Channel -> newchannel.png + Expected: /path/to/LEDMatrix/assets/broadcast_logos/newchannel.png + +PROBLEMATIC LOGOS (2): +-------------------------------------------------- + ESPN -> espn + Issue: Very low content density: 2.1% + Recommendation: Logo may appear as a white box - check content +``` + +## Troubleshooting + +If you see errors about missing dependencies: +```bash +pip install Pillow +``` + +If the script can't find the broadcast logos directory, ensure you're running it from the LEDMatrix project root directory. diff --git a/test/analyze_broadcast_logos.py b/test/analyze_broadcast_logos.py new file mode 100644 index 00000000..36fdf65c --- /dev/null +++ b/test/analyze_broadcast_logos.py @@ -0,0 +1,418 @@ +#!/usr/bin/env python3 +""" +Broadcast Logo Analyzer + +This script analyzes broadcast channel logos to ensure we have proper logos +for every game and identifies missing or problematic logos that might show +as white boxes. + +IMPORTANT: This script must be run on the Raspberry Pi where the LEDMatrix +project is located, as it needs to access the actual logo files in the +assets/broadcast_logos/ directory. + +Usage (on Raspberry Pi): + python test/analyze_broadcast_logos.py + +Features: +- Checks all broadcast logos referenced in BROADCAST_LOGO_MAP +- Validates logo file existence and integrity +- Analyzes logo dimensions and transparency +- Identifies potential white box issues +- Provides recommendations for missing logos +- Generates a detailed report +""" + +import os +import sys +import json +from pathlib import Path +from typing import Dict, List, Set, Tuple, Optional +from PIL import Image, ImageStat +import logging + +# Add the project root to the path so we can import from src +project_root = Path(__file__).parent.parent +sys.path.insert(0, str(project_root)) + +# Define the broadcast logo map directly (copied from odds_ticker_manager.py) +BROADCAST_LOGO_MAP = { + "ACC Network": "accn", + "ACCN": "accn", + "ABC": "abc", + "BTN": "btn", + "CBS": "cbs", + "CBSSN": "cbssn", + "CBS Sports Network": "cbssn", + "ESPN": "espn", + "ESPN2": "espn2", + "ESPN3": "espn3", + "ESPNU": "espnu", + "ESPNEWS": "espn", + "ESPN+": "espn", + "ESPN Plus": "espn", + "FOX": "fox", + "FS1": "fs1", + "FS2": "fs2", + "MLBN": "mlbn", + "MLB Network": "mlbn", + "MLB.TV": "mlbn", + "NBC": "nbc", + "NFLN": "nfln", + "NFL Network": "nfln", + "PAC12": "pac12n", + "Pac-12 Network": "pac12n", + "SECN": "espn-sec-us", + "TBS": "tbs", + "TNT": "tnt", + "truTV": "tru", + "Peacock": "nbc", + "Paramount+": "cbs", + "Hulu": "espn", + "Disney+": "espn", + "Apple TV+": "nbc", + # Regional sports networks + "MASN": "cbs", + "MASN2": "cbs", + "MAS+": "cbs", + "SportsNet": "nbc", + "FanDuel SN": "fox", + "FanDuel SN DET": "fox", + "FanDuel SN FL": "fox", + "SportsNet PIT": "nbc", + "Padres.TV": "espn", + "CLEGuardians.TV": "espn" +} + +# Set up logging +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(levelname)s - %(message)s' +) +logger = logging.getLogger(__name__) + +class BroadcastLogoAnalyzer: + """Analyzes broadcast channel logos for completeness and quality.""" + + def __init__(self, project_root: Path): + self.project_root = project_root + self.broadcast_logos_dir = project_root / "assets" / "broadcast_logos" + self.results = { + 'total_mappings': len(BROADCAST_LOGO_MAP), + 'existing_logos': [], + 'missing_logos': [], + 'problematic_logos': [], + 'recommendations': [] + } + + def analyze_all_logos(self) -> Dict: + """Perform comprehensive analysis of all broadcast logos.""" + logger.info("Starting broadcast logo analysis...") + + # Get all logo files that exist + existing_files = self._get_existing_logo_files() + logger.info(f"Found {len(existing_files)} existing logo files") + + # Check each mapping in BROADCAST_LOGO_MAP + for broadcast_name, logo_filename in BROADCAST_LOGO_MAP.items(): + self._analyze_logo_mapping(broadcast_name, logo_filename, existing_files) + + # Check for orphaned logo files (files that exist but aren't mapped) + self._check_orphaned_logos(existing_files) + + # Generate recommendations + self._generate_recommendations() + + return self.results + + def _get_existing_logo_files(self) -> Set[str]: + """Get all existing logo files in the broadcast_logos directory.""" + existing_files = set() + + if not self.broadcast_logos_dir.exists(): + logger.warning(f"Broadcast logos directory does not exist: {self.broadcast_logos_dir}") + return existing_files + + for file_path in self.broadcast_logos_dir.iterdir(): + if file_path.is_file() and file_path.suffix.lower() in ['.png', '.jpg', '.jpeg']: + existing_files.add(file_path.stem) # filename without extension + + return existing_files + + def _analyze_logo_mapping(self, broadcast_name: str, logo_filename: str, existing_files: Set[str]): + """Analyze a single logo mapping.""" + logo_path = self.broadcast_logos_dir / f"{logo_filename}.png" + + if logo_filename not in existing_files: + self.results['missing_logos'].append({ + 'broadcast_name': broadcast_name, + 'logo_filename': logo_filename, + 'expected_path': str(logo_path) + }) + logger.warning(f"Missing logo: {broadcast_name} -> {logo_filename}.png") + return + + # Logo exists, analyze its quality + try: + analysis = self._analyze_logo_quality(logo_path, broadcast_name, logo_filename) + if analysis['is_problematic']: + self.results['problematic_logos'].append(analysis) + else: + self.results['existing_logos'].append(analysis) + except Exception as e: + logger.error(f"Error analyzing logo {logo_path}: {e}") + self.results['problematic_logos'].append({ + 'broadcast_name': broadcast_name, + 'logo_filename': logo_filename, + 'path': str(logo_path), + 'error': str(e), + 'is_problematic': True + }) + + def _analyze_logo_quality(self, logo_path: Path, broadcast_name: str, logo_filename: str) -> Dict: + """Analyze the quality of a logo file.""" + try: + with Image.open(logo_path) as img: + # Basic image info + width, height = img.size + mode = img.mode + + # Convert to RGBA for analysis if needed + if mode != 'RGBA': + img_rgba = img.convert('RGBA') + else: + img_rgba = img + + # Analyze for potential white box issues + analysis = { + 'broadcast_name': broadcast_name, + 'logo_filename': logo_filename, + 'path': str(logo_path), + 'dimensions': (width, height), + 'mode': mode, + 'file_size': logo_path.stat().st_size, + 'is_problematic': False, + 'issues': [], + 'recommendations': [] + } + + # Check for white box issues + self._check_white_box_issues(img_rgba, analysis) + + # Check dimensions + self._check_dimensions(width, height, analysis) + + # Check transparency + self._check_transparency(img_rgba, analysis) + + # Check if image is mostly empty/white + self._check_content_density(img_rgba, analysis) + + return analysis + + except Exception as e: + raise Exception(f"Failed to analyze image: {e}") + + def _check_white_box_issues(self, img: Image.Image, analysis: Dict): + """Check for potential white box issues.""" + # Get image statistics + stat = ImageStat.Stat(img) + + # Check if image is mostly white + if img.mode == 'RGBA': + # For RGBA, check RGB channels + r_mean, g_mean, b_mean = stat.mean[:3] + if r_mean > 240 and g_mean > 240 and b_mean > 240: + analysis['issues'].append("Image appears to be mostly white") + analysis['is_problematic'] = True + + # Check for completely transparent images + if img.mode == 'RGBA': + alpha_channel = img.split()[3] + alpha_stat = ImageStat.Stat(alpha_channel) + if alpha_stat.mean[0] < 10: # Very low alpha + analysis['issues'].append("Image is mostly transparent") + analysis['is_problematic'] = True + + def _check_dimensions(self, width: int, height: int, analysis: Dict): + """Check if dimensions are reasonable.""" + if width < 16 or height < 16: + analysis['issues'].append(f"Very small dimensions: {width}x{height}") + analysis['is_problematic'] = True + analysis['recommendations'].append("Consider using a higher resolution logo") + + if width > 512 or height > 512: + analysis['issues'].append(f"Very large dimensions: {width}x{height}") + analysis['recommendations'].append("Consider optimizing logo size for better performance") + + # Check aspect ratio + aspect_ratio = width / height + if aspect_ratio > 4 or aspect_ratio < 0.25: + analysis['issues'].append(f"Extreme aspect ratio: {aspect_ratio:.2f}") + analysis['recommendations'].append("Consider using a more square logo") + + def _check_transparency(self, img: Image.Image, analysis: Dict): + """Check transparency handling.""" + if img.mode == 'RGBA': + # Check if there's any transparency + alpha_channel = img.split()[3] + alpha_data = list(alpha_channel.getdata()) + min_alpha = min(alpha_data) + max_alpha = max(alpha_data) + + if min_alpha < 255: + analysis['recommendations'].append("Logo has transparency - ensure proper background handling") + + if max_alpha < 128: + analysis['issues'].append("Logo is very transparent") + analysis['is_problematic'] = True + + def _check_content_density(self, img: Image.Image, analysis: Dict): + """Check if the image has sufficient content.""" + # Convert to grayscale for analysis + gray = img.convert('L') + + # Count non-white pixels (assuming white background) + pixels = list(gray.getdata()) + non_white_pixels = sum(1 for p in pixels if p < 240) + total_pixels = len(pixels) + content_ratio = non_white_pixels / total_pixels + + if content_ratio < 0.05: # Less than 5% content + analysis['issues'].append(f"Very low content density: {content_ratio:.1%}") + analysis['is_problematic'] = True + analysis['recommendations'].append("Logo may appear as a white box - check content") + + def _check_orphaned_logos(self, existing_files: Set[str]): + """Check for logo files that exist but aren't mapped.""" + mapped_filenames = set(BROADCAST_LOGO_MAP.values()) + orphaned_files = existing_files - mapped_filenames + + if orphaned_files: + self.results['orphaned_logos'] = list(orphaned_files) + logger.info(f"Found {len(orphaned_files)} orphaned logo files: {orphaned_files}") + + def _generate_recommendations(self): + """Generate overall recommendations.""" + recommendations = [] + + if self.results['missing_logos']: + recommendations.append(f"Add {len(self.results['missing_logos'])} missing logo files") + + if self.results['problematic_logos']: + recommendations.append(f"Fix {len(self.results['problematic_logos'])} problematic logos") + + if 'orphaned_logos' in self.results: + recommendations.append(f"Consider mapping {len(self.results['orphaned_logos'])} orphaned logo files") + + # General recommendations + recommendations.extend([ + "Ensure all logos are PNG format with transparency support", + "Use consistent dimensions (preferably 64x64 or 128x128 pixels)", + "Test logos on the actual LED matrix display", + "Consider creating fallback logos for missing channels" + ]) + + self.results['recommendations'] = recommendations + + def print_report(self): + """Print a detailed analysis report.""" + print("\n" + "="*80) + print("BROADCAST LOGO ANALYSIS REPORT") + print("="*80) + + print(f"\nSUMMARY:") + print(f" Total broadcast mappings: {self.results['total_mappings']}") + print(f" Existing logos: {len(self.results['existing_logos'])}") + print(f" Missing logos: {len(self.results['missing_logos'])}") + print(f" Problematic logos: {len(self.results['problematic_logos'])}") + + if 'orphaned_logos' in self.results: + print(f" Orphaned logos: {len(self.results['orphaned_logos'])}") + + # Missing logos + if self.results['missing_logos']: + print(f"\nMISSING LOGOS ({len(self.results['missing_logos'])}):") + print("-" * 50) + for missing in self.results['missing_logos']: + print(f" {missing['broadcast_name']} -> {missing['logo_filename']}.png") + print(f" Expected: {missing['expected_path']}") + + # Problematic logos + if self.results['problematic_logos']: + print(f"\nPROBLEMATIC LOGOS ({len(self.results['problematic_logos'])}):") + print("-" * 50) + for problematic in self.results['problematic_logos']: + print(f" {problematic['broadcast_name']} -> {problematic['logo_filename']}") + if 'error' in problematic: + print(f" Error: {problematic['error']}") + if 'issues' in problematic: + for issue in problematic['issues']: + print(f" Issue: {issue}") + if 'recommendations' in problematic: + for rec in problematic['recommendations']: + print(f" Recommendation: {rec}") + + # Orphaned logos + if 'orphaned_logos' in self.results and self.results['orphaned_logos']: + print(f"\nORPHANED LOGOS ({len(self.results['orphaned_logos'])}):") + print("-" * 50) + for orphaned in self.results['orphaned_logos']: + print(f" {orphaned}.png (not mapped in BROADCAST_LOGO_MAP)") + + # Recommendations + if self.results['recommendations']: + print(f"\nRECOMMENDATIONS:") + print("-" * 50) + for i, rec in enumerate(self.results['recommendations'], 1): + print(f" {i}. {rec}") + + print("\n" + "="*80) + + def save_report(self, output_file: str = "broadcast_logo_analysis.json"): + """Save the analysis results to a JSON file.""" + output_path = self.project_root / "test" / output_file + with open(output_path, 'w') as f: + json.dump(self.results, f, indent=2) + logger.info(f"Analysis report saved to: {output_path}") + +def main(): + """Main function to run the broadcast logo analysis.""" + print("Broadcast Logo Analyzer") + print("=" * 50) + + # Check if we're in the right directory structure + if not (project_root / "assets" / "broadcast_logos").exists(): + print("ERROR: This script must be run from the LEDMatrix project root directory") + print(f"Expected directory structure: {project_root}/assets/broadcast_logos/") + print("Please run this script on the Raspberry Pi where the LEDMatrix project is located.") + print("\nTo test the script logic locally, you can copy some logo files to the expected location.") + return 1 + + # Initialize analyzer + analyzer = BroadcastLogoAnalyzer(project_root) + + # Run analysis + try: + results = analyzer.analyze_all_logos() + + # Print report + analyzer.print_report() + + # Save report + analyzer.save_report() + + # Return exit code based on issues found + total_issues = len(results['missing_logos']) + len(results['problematic_logos']) + if total_issues > 0: + print(f"\n⚠️ Found {total_issues} issues that need attention!") + return 1 + else: + print(f"\n✅ All broadcast logos are in good condition!") + return 0 + + except Exception as e: + logger.error(f"Analysis failed: {e}") + return 1 + +if __name__ == "__main__": + exit(main()) diff --git a/test/broadcast_logo_analysis.json b/test/broadcast_logo_analysis.json new file mode 100644 index 00000000..fab9ffb8 --- /dev/null +++ b/test/broadcast_logo_analysis.json @@ -0,0 +1,326 @@ +{ + "total_mappings": 44, + "existing_logos": [], + "missing_logos": [], + "problematic_logos": [ + { + "broadcast_name": "ACC Network", + "logo_filename": "accn", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\accn.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "ACCN", + "logo_filename": "accn", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\accn.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "ABC", + "logo_filename": "abc", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\abc.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "BTN", + "logo_filename": "btn", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\btn.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "CBS", + "logo_filename": "cbs", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\cbs.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "CBSSN", + "logo_filename": "cbssn", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\cbssn.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "CBS Sports Network", + "logo_filename": "cbssn", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\cbssn.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "ESPN", + "logo_filename": "espn", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "ESPN2", + "logo_filename": "espn2", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn2.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "ESPN3", + "logo_filename": "espn3", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn3.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "ESPNU", + "logo_filename": "espnu", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espnu.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "ESPNEWS", + "logo_filename": "espn", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "ESPN+", + "logo_filename": "espn", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "ESPN Plus", + "logo_filename": "espn", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "FOX", + "logo_filename": "fox", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\fox.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "FS1", + "logo_filename": "fs1", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\fs1.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "FS2", + "logo_filename": "fs2", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\fs2.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "MLBN", + "logo_filename": "mlbn", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\mlbn.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "MLB Network", + "logo_filename": "mlbn", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\mlbn.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "MLB.TV", + "logo_filename": "mlbn", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\mlbn.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "NBC", + "logo_filename": "nbc", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\nbc.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "NFLN", + "logo_filename": "nfln", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\nfln.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "NFL Network", + "logo_filename": "nfln", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\nfln.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "PAC12", + "logo_filename": "pac12n", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\pac12n.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "Pac-12 Network", + "logo_filename": "pac12n", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\pac12n.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "SECN", + "logo_filename": "espn-sec-us", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn-sec-us.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "TBS", + "logo_filename": "tbs", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\tbs.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "TNT", + "logo_filename": "tnt", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\tnt.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "truTV", + "logo_filename": "tru", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\tru.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "Peacock", + "logo_filename": "nbc", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\nbc.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "Paramount+", + "logo_filename": "cbs", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\cbs.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "Hulu", + "logo_filename": "espn", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "Disney+", + "logo_filename": "espn", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "Apple TV+", + "logo_filename": "nbc", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\nbc.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "MASN", + "logo_filename": "cbs", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\cbs.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "MASN2", + "logo_filename": "cbs", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\cbs.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "MAS+", + "logo_filename": "cbs", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\cbs.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "SportsNet", + "logo_filename": "nbc", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\nbc.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "FanDuel SN", + "logo_filename": "fox", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\fox.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "FanDuel SN DET", + "logo_filename": "fox", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\fox.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "FanDuel SN FL", + "logo_filename": "fox", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\fox.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "SportsNet PIT", + "logo_filename": "nbc", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\nbc.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "Padres.TV", + "logo_filename": "espn", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + }, + { + "broadcast_name": "CLEGuardians.TV", + "logo_filename": "espn", + "path": "C:\\Users\\Charles\\Documents\\GitHub\\LEDMatrix\\assets\\broadcast_logos\\espn.png", + "error": "Failed to analyze image: 'Stat' object has no attribute 'min'", + "is_problematic": true + } + ], + "recommendations": [ + "Fix 44 problematic logos", + "Consider mapping 1 orphaned logo files", + "Ensure all logos are PNG format with transparency support", + "Use consistent dimensions (preferably 64x64 or 128x128 pixels)", + "Test logos on the actual LED matrix display", + "Consider creating fallback logos for missing channels" + ], + "orphaned_logos": [ + "prime" + ] +} \ No newline at end of file