Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions plugins.json
Original file line number Diff line number Diff line change
Expand Up @@ -272,10 +272,10 @@
"plugin_path": "plugins/baseball-scoreboard",
"stars": 0,
"downloads": 0,
"last_updated": "2025-10-20",
"last_updated": "2026-02-12",
"verified": true,
"screenshot": "",
"latest_version": "1.0.4"
"latest_version": "1.0.5"
},
{
"id": "soccer-scoreboard",
Expand Down
78 changes: 76 additions & 2 deletions plugins/baseball-scoreboard/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@
SportsRecent = None
SportsUpcoming = None

# Import data manager for background fetching
try:
from data_manager import BaseballDataManager
DATA_MANAGER_AVAILABLE = True
except ImportError:
BaseballDataManager = None
DATA_MANAGER_AVAILABLE = False

# Import scroll display components
try:
Expand Down Expand Up @@ -185,6 +192,15 @@ def __init__(self, plugin_id: str, config: Dict[str, Any],

self.initialized = True

# Initialize data manager for background fetching
self.data_manager = None
if DATA_MANAGER_AVAILABLE:
try:
self.data_manager = BaseballDataManager(cache_manager, self.logger)
self.logger.info("Baseball data manager initialized with background service support")
except Exception as e:
self.logger.warning(f"Could not initialize data manager, using sync fetching: {e}")

# Load fonts for rendering
self.fonts = self._load_fonts()

Expand Down Expand Up @@ -352,7 +368,62 @@ def sort_key(game):
self.current_games.sort(key=sort_key)

def _fetch_league_data(self, league_key: str, league_config: Dict) -> List[Dict]:
"""Fetch game data for a specific league."""
"""Fetch game data for a specific league.

Uses data_manager with background_data_service when available,
falls back to direct synchronous API calls otherwise.
"""
if self.data_manager:
return self._fetch_via_data_manager(league_key, league_config)
return self._fetch_league_data_sync(league_key, league_config)

def _fetch_via_data_manager(self, league_key: str, league_config: Dict) -> List[Dict]:
"""Fetch game data via data_manager (supports background_data_service)."""
try:
if league_key == 'milb':
milb_games = self.data_manager.fetch_milb_games(league_config)
if not milb_games:
return []
return [self._convert_milb_game(g) for g in milb_games.values()]
else:
result = self.data_manager.fetch_season_data(league_key, league_config)
if result and 'events' in result:
return self._process_api_response(result, league_key, league_config)
return []
except Exception as e:
self.logger.exception(f"Error fetching {league_key} via data manager, falling back to sync")
return self._fetch_league_data_sync(league_key, league_config)

def _convert_milb_game(self, milb_data: Dict) -> Dict:
"""Convert data_manager MiLB format to the game dict format used by display methods."""
return {
'league': 'milb',
'game_id': milb_data.get('id'),
'home_team': {
'name': '',
'abbrev': milb_data.get('home_team', ''),
'score': milb_data.get('home_score', 0),
'logo': None
},
'away_team': {
'name': '',
'abbrev': milb_data.get('away_team', ''),
'score': milb_data.get('away_score', 0),
'logo': None
},
'status': {
'state': milb_data.get('status_state', 'pre'),
'detail': milb_data.get('detailed_state', ''),
'short_detail': milb_data.get('detailed_state', ''),
'period': milb_data.get('inning', 0),
'display_clock': ''
},
'start_time': milb_data.get('start_time', ''),
'venue': ''
}

def _fetch_league_data_sync(self, league_key: str, league_config: Dict) -> List[Dict]:
"""Synchronous fallback for fetching game data when data_manager is unavailable."""
cache_key = f"baseball_{league_key}_{datetime.now().strftime('%Y%m%d')}"
try:
update_interval = int(league_config.get('update_interval_seconds', 60))
Expand All @@ -372,7 +443,7 @@ def _fetch_league_data(self, league_key: str, league_config: Dict) -> List[Dict]
self.logger.error(f"Unknown league key: {league_key}")
return []

self.logger.info(f"Fetching {league_key} data from ESPN API...")
self.logger.info(f"Fetching {league_key} data from ESPN API (sync)...")
response = requests.get(url, timeout=league_config.get('background_service', {}).get('request_timeout', 30))
response.raise_for_status()

Expand Down Expand Up @@ -990,4 +1061,7 @@ def cleanup(self) -> None:
"""Cleanup resources."""
with self._games_lock:
self.current_games = []
if hasattr(self, 'data_manager') and self.data_manager:
# Background service is a global singleton, no explicit shutdown needed
self.data_manager = None
self.logger.info("Baseball scoreboard plugin cleaned up")
12 changes: 10 additions & 2 deletions plugins/baseball-scoreboard/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "baseball-scoreboard",
"name": "Baseball Scoreboard",
"version": "1.0.4",
"version": "1.0.5",
"author": "ChuckBuilds",
"description": "Live, recent, and upcoming baseball games across MLB, MiLB, and NCAA Baseball with real-time scores and schedules",
"category": "sports",
Expand All @@ -20,7 +20,15 @@
"baseball_recent",
"baseball_upcoming"
],
"repo": "https://github.com/ChuckBuilds/ledmatrix-plugins",
"branch": "main",
"plugin_path": "plugins/baseball-scoreboard",
"versions": [
{
"released": "2026-02-12",
"version": "1.0.5",
"ledmatrix_min": "2.0.0"
},
{
"released": "2025-10-20",
"version": "1.0.4",
Expand All @@ -37,7 +45,7 @@
"ledmatrix_min": "2.0.0"
}
],
"last_updated": "2025-10-19",
"last_updated": "2026-02-12",
"stars": 0,
"downloads": 0,
"verified": true,
Expand Down