mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-04-10 13:02:59 +00:00
added portuguese soccer league to documentation for soccer manager and added auto-download missing logos for soccer teams
This commit is contained in:
@@ -59,7 +59,7 @@ The system supports live, recent, and upcoming game information for multiple spo
|
||||
- NCAA Football
|
||||
- NCAA Men's Basketball
|
||||
- NCAA Men's Baseball
|
||||
- Soccer
|
||||
- Soccer (Premier League, La Liga, Bundesliga, Serie A, Ligue 1, Liga Portugal, Champions League, Europa League, MLS)
|
||||
- (Note, some of these sports seasons were not active during development and might need fine tuning when games are active)
|
||||
|
||||
|
||||
|
||||
@@ -755,6 +755,20 @@ MLB Conferences/Divisions
|
||||
OAK => Oakland Athletics
|
||||
SEA => Seattle Mariners
|
||||
TEX => Texas Rangers
|
||||
|
||||
Soccer Leagues:
|
||||
LEAGUE_SLUGS = {
|
||||
"eng.1": "Premier League",
|
||||
"esp.1": "La Liga",
|
||||
"ger.1": "Bundesliga",
|
||||
"ita.1": "Serie A",
|
||||
"fra.1": "Ligue 1",
|
||||
"uefa.champions": "Champions League",
|
||||
"uefa.europa": "Europa League",
|
||||
"usa.1": "MLS",
|
||||
"por.1": "Liga Portugal", # Add this line
|
||||
}
|
||||
|
||||
Soccer - Premier League (England)
|
||||
ARS => Arsenal
|
||||
AVL => Aston Villa
|
||||
@@ -886,6 +900,24 @@ Soccer - Champions League
|
||||
VFB => VfB Stuttgart
|
||||
VIL => Villarreal
|
||||
|
||||
Soccer - Liga Portugal (Portugal)
|
||||
ARO => Arouca
|
||||
BEN => SL Benfica
|
||||
BRA => SC Braga
|
||||
CHA => Chaves
|
||||
EST => Estoril Praia
|
||||
FAM => Famalicão
|
||||
GIL => Gil Vicente
|
||||
MOR => Moreirense
|
||||
POR => FC Porto
|
||||
PTM => Portimonense
|
||||
RIO => Rio Ave
|
||||
SR => Sporting CP
|
||||
VGU => Vitória de Guimarães
|
||||
VSC => Vitória de Setúbal
|
||||
|
||||
|
||||
|
||||
Soccer - Other Teams
|
||||
austin => Austin FC
|
||||
cf_montral => CF Montréal
|
||||
|
||||
BIN
assets/sports/soccer_logos/BEN.png
Normal file
BIN
assets/sports/soccer_logos/BEN.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 121 KiB |
BIN
assets/sports/soccer_logos/SCP.png
Normal file
BIN
assets/sports/soccer_logos/SCP.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
@@ -31,7 +31,17 @@ class LogoDownloader:
|
||||
'ncaa_fb_all': 'https://site.api.espn.com/apis/site/v2/sports/football/college-football/teams', # Includes FCS
|
||||
'fcs': 'https://site.api.espn.com/apis/site/v2/sports/football/college-football/teams', # FCS teams from same endpoint
|
||||
'ncaam_basketball': 'https://site.api.espn.com/apis/site/v2/sports/basketball/mens-college-basketball/teams',
|
||||
'ncaa_baseball': 'https://site.api.espn.com/apis/site/v2/sports/baseball/college-baseball/teams'
|
||||
'ncaa_baseball': 'https://site.api.espn.com/apis/site/v2/sports/baseball/college-baseball/teams',
|
||||
# Soccer leagues
|
||||
'soccer_eng.1': 'https://site.api.espn.com/apis/site/v2/sports/soccer/eng.1/teams',
|
||||
'soccer_esp.1': 'https://site.api.espn.com/apis/site/v2/sports/soccer/esp.1/teams',
|
||||
'soccer_ger.1': 'https://site.api.espn.com/apis/site/v2/sports/soccer/ger.1/teams',
|
||||
'soccer_ita.1': 'https://site.api.espn.com/apis/site/v2/sports/soccer/ita.1/teams',
|
||||
'soccer_fra.1': 'https://site.api.espn.com/apis/site/v2/sports/soccer/fra.1/teams',
|
||||
'soccer_por.1': 'https://site.api.espn.com/apis/site/v2/sports/soccer/por.1/teams',
|
||||
'soccer_uefa.champions': 'https://site.api.espn.com/apis/site/v2/sports/soccer/uefa.champions/teams',
|
||||
'soccer_uefa.europa': 'https://site.api.espn.com/apis/site/v2/sports/soccer/uefa.europa/teams',
|
||||
'soccer_usa.1': 'https://site.api.espn.com/apis/site/v2/sports/soccer/usa.1/teams'
|
||||
}
|
||||
|
||||
# Directory mappings for different leagues
|
||||
@@ -44,7 +54,17 @@ class LogoDownloader:
|
||||
'ncaa_fb_all': 'assets/sports/ncaa_fbs_logos', # FCS teams go in same directory
|
||||
'fcs': 'assets/sports/ncaa_fbs_logos', # FCS teams go in same directory
|
||||
'ncaam_basketball': 'assets/sports/ncaa_fbs_logos',
|
||||
'ncaa_baseball': 'assets/sports/ncaa_fbs_logos'
|
||||
'ncaa_baseball': 'assets/sports/ncaa_fbs_logos',
|
||||
# Soccer leagues - all use the same soccer_logos directory
|
||||
'soccer_eng.1': 'assets/sports/soccer_logos',
|
||||
'soccer_esp.1': 'assets/sports/soccer_logos',
|
||||
'soccer_ger.1': 'assets/sports/soccer_logos',
|
||||
'soccer_ita.1': 'assets/sports/soccer_logos',
|
||||
'soccer_fra.1': 'assets/sports/soccer_logos',
|
||||
'soccer_por.1': 'assets/sports/soccer_logos',
|
||||
'soccer_uefa.champions': 'assets/sports/soccer_logos',
|
||||
'soccer_uefa.europa': 'assets/sports/soccer_logos',
|
||||
'soccer_usa.1': 'assets/sports/soccer_logos'
|
||||
}
|
||||
|
||||
def __init__(self, request_timeout: int = 30, retry_attempts: int = 3):
|
||||
@@ -605,6 +625,20 @@ class LogoDownloader:
|
||||
return converted_count, failed_count
|
||||
|
||||
|
||||
# Helper function to map soccer league codes to logo downloader format
|
||||
def get_soccer_league_key(league_code: str) -> str:
|
||||
"""
|
||||
Map soccer league codes to logo downloader format.
|
||||
|
||||
Args:
|
||||
league_code: Soccer league code (e.g., 'eng.1', 'por.1')
|
||||
|
||||
Returns:
|
||||
Logo downloader league key (e.g., 'soccer_eng.1', 'soccer_por.1')
|
||||
"""
|
||||
return f"soccer_{league_code}"
|
||||
|
||||
|
||||
# Convenience function for easy integration
|
||||
def download_missing_logo(team_abbreviation: str, league: str, team_name: str = None, create_placeholder: bool = True) -> bool:
|
||||
"""
|
||||
|
||||
@@ -12,6 +12,7 @@ from src.display_manager import DisplayManager
|
||||
from src.cache_manager import CacheManager
|
||||
from src.config_manager import ConfigManager
|
||||
from src.odds_manager import OddsManager
|
||||
from src.logo_downloader import download_missing_logo, get_soccer_league_key
|
||||
import pytz
|
||||
|
||||
# Import the API counter function from web interface
|
||||
@@ -32,6 +33,7 @@ LEAGUE_SLUGS = {
|
||||
"ger.1": "Bundesliga",
|
||||
"ita.1": "Serie A",
|
||||
"fra.1": "Ligue 1",
|
||||
"por.1": "Liga Portugal",
|
||||
"uefa.champions": "Champions League",
|
||||
"uefa.europa": "Europa League",
|
||||
"usa.1": "MLS",
|
||||
@@ -408,42 +410,61 @@ class BaseSoccerManager:
|
||||
|
||||
try:
|
||||
if not os.path.exists(logo_path) and not (cache_logo_path and os.path.exists(cache_logo_path)):
|
||||
self.logger.info(f"Creating placeholder logo for {team_abbrev}")
|
||||
# Try to create placeholder in cache directory instead of assets directory
|
||||
cache_logo_path = None
|
||||
try:
|
||||
# Use cache directory for placeholder logos
|
||||
if hasattr(self.cache_manager, 'cache_dir') and self.cache_manager.cache_dir:
|
||||
cache_logo_dir = os.path.join(self.cache_manager.cache_dir, 'placeholder_logos')
|
||||
os.makedirs(cache_logo_dir, exist_ok=True)
|
||||
cache_logo_path = os.path.join(cache_logo_dir, f"{team_abbrev}.png")
|
||||
self.logger.info(f"Logo not found for {team_abbrev} at {logo_path}. Attempting to download from ESPN.")
|
||||
|
||||
# Try to download the logo from ESPN API for each configured league
|
||||
download_success = False
|
||||
for league_code in self.target_leagues_config:
|
||||
if league_code in LEAGUE_SLUGS:
|
||||
soccer_league_key = get_soccer_league_key(league_code)
|
||||
self.logger.debug(f"Attempting to download {team_abbrev} logo from {league_code} ({soccer_league_key})")
|
||||
|
||||
# Create placeholder logo
|
||||
success = download_missing_logo(team_abbrev, soccer_league_key, team_abbrev)
|
||||
if success:
|
||||
self.logger.info(f"Successfully downloaded logo for {team_abbrev} from {league_code}")
|
||||
download_success = True
|
||||
break
|
||||
else:
|
||||
self.logger.debug(f"Failed to download {team_abbrev} logo from {league_code}")
|
||||
|
||||
if not download_success:
|
||||
self.logger.warning(f"Failed to download logo for {team_abbrev} from any configured league. Creating placeholder.")
|
||||
# Try to create placeholder in cache directory instead of assets directory
|
||||
cache_logo_path = None
|
||||
try:
|
||||
# Use cache directory for placeholder logos
|
||||
if hasattr(self.cache_manager, 'cache_dir') and self.cache_manager.cache_dir:
|
||||
cache_logo_dir = os.path.join(self.cache_manager.cache_dir, 'placeholder_logos')
|
||||
os.makedirs(cache_logo_dir, exist_ok=True)
|
||||
cache_logo_path = os.path.join(cache_logo_dir, f"{team_abbrev}.png")
|
||||
|
||||
# Create placeholder logo
|
||||
logo = Image.new('RGBA', (36, 36), (random.randint(50, 200), random.randint(50, 200), random.randint(50, 200), 255))
|
||||
draw = ImageDraw.Draw(logo)
|
||||
# Optionally add text to placeholder
|
||||
try:
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
font_4x6 = os.path.abspath(os.path.join(script_dir, "../assets/fonts/4x6-font.ttf"))
|
||||
placeholder_font = ImageFont.truetype(font_4x6, 12)
|
||||
text_width = draw.textlength(team_abbrev, font=placeholder_font)
|
||||
text_x = (36 - text_width) // 2
|
||||
text_y = 10
|
||||
draw.text((text_x, text_y), team_abbrev, fill=(0,0,0,255), font=placeholder_font)
|
||||
except IOError:
|
||||
pass # Font not found, skip text
|
||||
logo.save(cache_logo_path)
|
||||
self.logger.info(f"Created placeholder logo in cache at {cache_logo_path}")
|
||||
# Update logo_path to use cache version
|
||||
logo_path = cache_logo_path
|
||||
else:
|
||||
# No cache directory available, just use in-memory placeholder
|
||||
raise PermissionError("No writable cache directory available")
|
||||
except (PermissionError, OSError) as pe:
|
||||
self.logger.debug(f"Could not create placeholder logo file for {team_abbrev}: {pe}")
|
||||
# Return a simple in-memory placeholder instead
|
||||
logo = Image.new('RGBA', (36, 36), (random.randint(50, 200), random.randint(50, 200), random.randint(50, 200), 255))
|
||||
draw = ImageDraw.Draw(logo)
|
||||
# Optionally add text to placeholder
|
||||
try:
|
||||
font_4x6 = os.path.abspath(os.path.join(script_dir, "../assets/fonts/4x6-font.ttf"))
|
||||
placeholder_font = ImageFont.truetype(font_4x6, 12)
|
||||
text_width = draw.textlength(team_abbrev, font=placeholder_font)
|
||||
text_x = (36 - text_width) // 2
|
||||
text_y = 10
|
||||
draw.text((text_x, text_y), team_abbrev, fill=(0,0,0,255), font=placeholder_font)
|
||||
except IOError:
|
||||
pass # Font not found, skip text
|
||||
logo.save(cache_logo_path)
|
||||
self.logger.info(f"Created placeholder logo in cache at {cache_logo_path}")
|
||||
# Update logo_path to use cache version
|
||||
logo_path = cache_logo_path
|
||||
else:
|
||||
# No cache directory available, just use in-memory placeholder
|
||||
raise PermissionError("No writable cache directory available")
|
||||
except (PermissionError, OSError) as pe:
|
||||
self.logger.debug(f"Could not create placeholder logo file for {team_abbrev}: {pe}")
|
||||
# Return a simple in-memory placeholder instead
|
||||
logo = Image.new('RGBA', (36, 36), (random.randint(50, 200), random.randint(50, 200), random.randint(50, 200), 255))
|
||||
self._logo_cache[team_abbrev] = logo
|
||||
return logo
|
||||
self._logo_cache[team_abbrev] = logo
|
||||
return logo
|
||||
|
||||
# Try to load logo from original path or cache directory
|
||||
logo_to_load = None
|
||||
|
||||
Reference in New Issue
Block a user