From 5101795cbfea65df0c0c80ac9db83138b999db68 Mon Sep 17 00:00:00 2001 From: Chuck <33324927+ChuckBuilds@users.noreply.github.com> Date: Fri, 12 Sep 2025 14:55:18 -0400 Subject: [PATCH] handle special characters in team names (TA&M A&M) --- assets/sports/ncaa_fbs_logos/AANDM.png | Bin 0 -> 409 bytes assets/sports/ncaa_fbs_logos/TAANDM.png | Bin 0 -> 433 bytes assets/sports/ncaa_fbs_logos/TAMU.png | Bin 0 -> 378 bytes src/logo_downloader.py | 111 +++++++++++++++++++++++- 4 files changed, 107 insertions(+), 4 deletions(-) create mode 100644 assets/sports/ncaa_fbs_logos/AANDM.png create mode 100644 assets/sports/ncaa_fbs_logos/TAANDM.png create mode 100644 assets/sports/ncaa_fbs_logos/TAMU.png diff --git a/assets/sports/ncaa_fbs_logos/AANDM.png b/assets/sports/ncaa_fbs_logos/AANDM.png new file mode 100644 index 0000000000000000000000000000000000000000..38632e9aab8dce392dafd73000455be8d5403343 GIT binary patch literal 409 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEU`+6IaSW-L^Y+%m+-3uTwuk2P zXRt17)J)LY){vPnGerF4L}%|6Qd}$d*$D}4hvpcl6GMqs zmt6Y(_wf5d8OgSX!7-Oju9W`0aIN%i+WgZq_RQb<-%5pf)v8^*YG*#zNT1ncJ3qkg zMTh^}(>IpdsJ&0;uX_4$MuyZG6W{OVfzzH|c65t5^8cmoh4o7^?kpGSoe>^v()sUO z&F6OUgX>$fKU_{RM~w({0`+3Jh)#L_gk9nH__Z4zFS>Rz`* t?&+uhy%Q`G{bmS1YaxzG=YNnR&z3&1>dqZy1z?afc)I$ztaD0e0stp|y?_7! literal 0 HcmV?d00001 diff --git a/assets/sports/ncaa_fbs_logos/TAANDM.png b/assets/sports/ncaa_fbs_logos/TAANDM.png new file mode 100644 index 0000000000000000000000000000000000000000..2791f99fb8f60b8f4dbefbd819d76f4db6ea28e0 GIT binary patch literal 433 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV65t64YKGtHH=r=?788Ot( zzmpbh%gvmXX7sFRXMx@P`rf&I%WuxO^{4i}eXZZTVwuU$SK7W_%EWW{!w!47ei^>@ z-+#YW)&9wq5f1O`Y&{yGW2CR6F4C>{`S_0*A@=1C>-Hv|m-dwnHl3JZX_|DoXLXrMT`l9Z z6S?;PQo1DcTP3xZUzo4!5caySX34tT@BgJ0ix15)P(Q;-9JMX(z_mJt0k literal 0 HcmV?d00001 diff --git a/assets/sports/ncaa_fbs_logos/TAMU.png b/assets/sports/ncaa_fbs_logos/TAMU.png new file mode 100644 index 0000000000000000000000000000000000000000..1f3893f0accae0663dec7aa0051ea18fb02d6ca1 GIT binary patch literal 378 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEV083!aSW-L^Y+%;-X;eTw}+3V zvo2-oX3EV}F zdMEI4(!4HYZB5!46W4q5ZCTFt+xgGUW}o#n%)QWpnUfo%mqIEG(ZP$!nvEQ#6 zrl!qXy7N2pajz}6VmrU3SFKq0|I4nwH(fX6-oAW*=eB$(W3B1q+Pk|x_|0;+`!jRt zpJ~h&;%+VzVg4Y!)xhtr>bs9!rZqGE str: """Normalize team abbreviation for consistent filename usage.""" - return abbreviation.upper() + # Handle special characters that can cause filesystem issues + normalized = abbreviation.upper() + # Replace problematic characters with safe alternatives + normalized = normalized.replace('&', 'AND') + normalized = normalized.replace('/', '_') + normalized = normalized.replace('\\', '_') + normalized = normalized.replace(':', '_') + normalized = normalized.replace('*', '_') + normalized = normalized.replace('?', '_') + normalized = normalized.replace('"', '_') + normalized = normalized.replace('<', '_') + normalized = normalized.replace('>', '_') + normalized = normalized.replace('|', '_') + return normalized def get_logo_directory(self, league: str) -> str: """Get the logo directory for a given league.""" @@ -249,6 +262,42 @@ class LogoDownloader: # Default to FBS for unknown conferences return 'FBS' + def _get_team_name_variations(self, abbreviation: str) -> List[str]: + """Generate common variations of a team abbreviation for matching.""" + variations = set() + abbr = abbreviation.upper() + variations.add(abbr) + + # Add normalized version + variations.add(self.normalize_abbreviation(abbr)) + + # Common substitutions + substitutions = { + '&': ['AND', 'A'], + 'A&M': ['TAMU', 'TA&M', 'TEXASAM'], + 'STATE': ['ST', 'ST.'], + 'UNIVERSITY': ['U', 'UNIV'], + 'COLLEGE': ['C', 'COL'], + 'TECHNICAL': ['TECH', 'T'], + 'NORTHERN': ['NORTH', 'N'], + 'SOUTHERN': ['SOUTH', 'S'], + 'EASTERN': ['EAST', 'E'], + 'WESTERN': ['WEST', 'W'] + } + + # Apply substitutions + for original, replacements in substitutions.items(): + if original in abbr: + for replacement in replacements: + variations.add(abbr.replace(original, replacement)) + variations.add(abbr.replace(original, '')) # Remove the word entirely + + # Add common abbreviations for Texas A&M + if 'A&M' in abbr or 'TAMU' in abbr: + variations.update(['TAMU', 'TA&M', 'TEXASAM', 'TEXAS_A&M', 'TEXAS_AM']) + + return list(variations) + def download_missing_logos_for_league(self, league: str, force_download: bool = False) -> Tuple[int, int]: """Download missing logos for a specific league.""" logger.info(f"Starting logo download for league: {league}") @@ -384,13 +433,34 @@ class LogoDownloader: teams = self.extract_teams_from_data(data, league) - # Find the specific team + # Find the specific team with improved matching target_team = None + normalized_search = self.normalize_abbreviation(team_abbreviation) + + # First try exact match for team in teams: if team['abbreviation'].upper() == team_abbreviation.upper(): target_team = team break + # If not found, try normalized match + if not target_team: + for team in teams: + normalized_team_abbr = self.normalize_abbreviation(team['abbreviation']) + if normalized_team_abbr == normalized_search: + target_team = team + break + + # If still not found, try partial matching for common variations + if not target_team: + search_variations = self._get_team_name_variations(team_abbreviation) + for team in teams: + team_variations = self._get_team_name_variations(team['abbreviation']) + if any(var in team_variations for var in search_variations): + target_team = team + logger.info(f"Found team {team_abbreviation} as {team['abbreviation']} ({team['display_name']})") + break + if not target_team: logger.warning(f"Team {team_abbreviation} not found in {league} data") return False @@ -426,9 +496,27 @@ class LogoDownloader: def create_placeholder_logo(self, team_abbreviation: str, logo_dir: str, team_name: str = None) -> bool: """Create a placeholder logo when real logo cannot be downloaded.""" try: + # Ensure the logo directory exists + if not self.ensure_logo_directory(logo_dir): + logger.error(f"Failed to create logo directory: {logo_dir}") + return False + filename = f"{self.normalize_abbreviation(team_abbreviation)}.png" filepath = Path(logo_dir) / filename + # Check if we can write to the directory + try: + # Test write permissions by creating a temporary file + test_file = filepath.parent / "test_write.tmp" + test_file.touch() + test_file.unlink() # Remove the test file + except PermissionError: + logger.error(f"Permission denied: Cannot write to directory {logo_dir}") + return False + except Exception as e: + logger.error(f"Directory access error for {logo_dir}: {e}") + return False + # Create a simple placeholder logo logo = Image.new('RGBA', (64, 64), (100, 100, 100, 255)) # Gray background draw = ImageDraw.Draw(logo) @@ -471,7 +559,7 @@ def download_missing_logo(team_abbreviation: str, league: str, team_name: str = Convenience function to download a missing team logo. Args: - team_abbreviation: Team abbreviation (e.g., 'UGA', 'BAMA') + team_abbreviation: Team abbreviation (e.g., 'UGA', 'BAMA', 'TA&M') league: League identifier (e.g., 'ncaa_fb', 'nfl') team_name: Optional team name for logging create_placeholder: Whether to create a placeholder if download fails @@ -481,14 +569,29 @@ def download_missing_logo(team_abbreviation: str, league: str, team_name: str = """ downloader = LogoDownloader() + # Check if logo already exists + logo_dir = downloader.get_logo_directory(league) + filename = f"{downloader.normalize_abbreviation(team_abbreviation)}.png" + filepath = Path(logo_dir) / filename + + if filepath.exists(): + logger.debug(f"Logo already exists for {team_abbreviation} ({league})") + return True + # Try to download the real logo first + logger.info(f"Attempting to download logo for {team_abbreviation} ({team_name or 'Unknown'}) from {league}") success = downloader.download_missing_logo_for_team(team_abbreviation, league, team_name) if not success and create_placeholder: + logger.info(f"Creating placeholder logo for {team_abbreviation} ({team_name or 'Unknown'})") # Create placeholder as fallback - logo_dir = downloader.get_logo_directory(league) success = downloader.create_placeholder_logo(team_abbreviation, logo_dir, team_name) + if success: + logger.info(f"Successfully handled logo for {team_abbreviation} ({team_name or 'Unknown'})") + else: + logger.warning(f"Failed to download or create logo for {team_abbreviation} ({team_name or 'Unknown'})") + return success