mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 13:02:59 +00:00
fix(logos): support logo downloads for custom soccer leagues (#247)
* fix(logos): support logo downloads for custom soccer leagues LogoDownloader.fetch_teams_data() and fetch_single_team() only had hardcoded API endpoints for predefined soccer leagues. Custom leagues (e.g., por.1, mex.1) would silently fail when the ESPN game data didn't include a direct logo URL. Now dynamically constructs the ESPN teams API URL for any soccer_* league not in the predefined map. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(logos): address PR review — directory, bulk download, and dedup - get_logo_directory: custom soccer leagues now resolve to shared assets/sports/soccer_logos/ instead of creating per-league dirs - download_all_missing_logos: use _resolve_api_url so custom soccer leagues are no longer silently skipped - Extract _resolve_api_url helper to deduplicate dynamic URL construction between fetch_teams_data and fetch_single_team Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Chuck <chuck@example.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -148,7 +148,13 @@ class LogoDownloader:
|
||||
|
||||
def get_logo_directory(self, league: str) -> str:
|
||||
"""Get the logo directory for a given league."""
|
||||
directory = LogoDownloader.LOGO_DIRECTORIES.get(league, f'assets/sports/{league}_logos')
|
||||
directory = LogoDownloader.LOGO_DIRECTORIES.get(league)
|
||||
if not directory:
|
||||
# Custom soccer leagues share the same logo directory as predefined ones
|
||||
if league.startswith('soccer_'):
|
||||
directory = 'assets/sports/soccer_logos'
|
||||
else:
|
||||
directory = f'assets/sports/{league}_logos'
|
||||
path = Path(directory)
|
||||
if not path.is_absolute():
|
||||
project_root = Path(__file__).resolve().parents[1]
|
||||
@@ -238,9 +244,18 @@ class LogoDownloader:
|
||||
logger.error(f"Unexpected error downloading logo for {team_abbreviation}: {e}")
|
||||
return False
|
||||
|
||||
def _resolve_api_url(self, league: str) -> Optional[str]:
|
||||
"""Resolve the ESPN API teams URL for a league, with dynamic fallback for custom soccer leagues."""
|
||||
api_url = self.API_ENDPOINTS.get(league)
|
||||
if not api_url and league.startswith('soccer_'):
|
||||
league_code = league[len('soccer_'):]
|
||||
api_url = f'https://site.api.espn.com/apis/site/v2/sports/soccer/{league_code}/teams'
|
||||
logger.info(f"Using dynamic ESPN endpoint for custom soccer league: {league}")
|
||||
return api_url
|
||||
|
||||
def fetch_teams_data(self, league: str) -> Optional[Dict]:
|
||||
"""Fetch team data from ESPN API for a specific league."""
|
||||
api_url = self.API_ENDPOINTS.get(league)
|
||||
api_url = self._resolve_api_url(league)
|
||||
if not api_url:
|
||||
logger.error(f"No API endpoint configured for league: {league}")
|
||||
return None
|
||||
@@ -263,7 +278,7 @@ class LogoDownloader:
|
||||
|
||||
def fetch_single_team(self, league: str, team_id: str) -> Optional[Dict]:
|
||||
"""Fetch team data from ESPN API for a specific league."""
|
||||
api_url = self.API_ENDPOINTS.get(league)
|
||||
api_url = self._resolve_api_url(league)
|
||||
if not api_url:
|
||||
logger.error(f"No API endpoint configured for league: {league}")
|
||||
return None
|
||||
@@ -570,7 +585,7 @@ class LogoDownloader:
|
||||
total_failed = 0
|
||||
|
||||
for league in leagues:
|
||||
if league not in self.API_ENDPOINTS:
|
||||
if not self._resolve_api_url(league):
|
||||
logger.warning(f"Skipping unknown league: {league}")
|
||||
continue
|
||||
|
||||
|
||||
Reference in New Issue
Block a user