remove metadata updater tool for jellyfin since most of the support is lost.
This commit is contained in:
parent
fe84f1dbb8
commit
ceeb4c22dc
2 changed files with 295 additions and 57 deletions
|
|
@ -37,6 +37,13 @@ class JellyfinArtist:
|
|||
self.title = jellyfin_data.get('Name', 'Unknown Artist')
|
||||
self.addedAt = self._parse_date(jellyfin_data.get('DateCreated'))
|
||||
|
||||
# Create genres property from Jellyfin data (empty list for now since data structure needs investigation)
|
||||
self.genres = []
|
||||
# TODO: Map Jellyfin genre data to match Plex format
|
||||
|
||||
# Create summary property from Jellyfin data (used for timestamp storage)
|
||||
self.summary = jellyfin_data.get('Overview', '') or ''
|
||||
|
||||
def _parse_date(self, date_str: Optional[str]) -> Optional[datetime]:
|
||||
"""Parse Jellyfin date string to datetime"""
|
||||
if not date_str:
|
||||
|
|
@ -128,6 +135,9 @@ class JellyfinClient:
|
|||
self._album_cache = {}
|
||||
self._track_cache = {}
|
||||
self._artist_cache = {}
|
||||
|
||||
# Metadata-only mode flag for performance optimization
|
||||
self._metadata_only_mode = False
|
||||
self._all_albums_cache = None
|
||||
self._all_tracks_cache = None
|
||||
self._cache_populated = False
|
||||
|
|
@ -245,6 +255,12 @@ class JellyfinClient:
|
|||
"""Aggressively pre-populate ALL caches to eliminate individual API calls"""
|
||||
if self._cache_populated:
|
||||
return
|
||||
|
||||
# Check if we're in metadata-only mode and skip expensive operations
|
||||
if self._metadata_only_mode:
|
||||
logger.info("🎯 Skipping cache population for metadata-only operation")
|
||||
self._cache_populated = True
|
||||
return
|
||||
|
||||
logger.info("🚀 Starting aggressive Jellyfin cache population to eliminate slow individual API calls...")
|
||||
if self._progress_callback:
|
||||
|
|
@ -1155,4 +1171,183 @@ class JellyfinClient:
|
|||
|
||||
except Exception as e:
|
||||
logger.debug(f"Error checking if Jellyfin library is scanning: {e}")
|
||||
return False
|
||||
|
||||
# Metadata update methods for compatibility with metadata updater
|
||||
def update_artist_genres(self, artist, genres: List[str]):
|
||||
"""Update artist genres - currently not implemented for Jellyfin"""
|
||||
try:
|
||||
# TODO: Implement Jellyfin genre update API
|
||||
# For now, just log and return success to continue processing
|
||||
logger.debug(f"Genre update not yet implemented for Jellyfin artist: {artist.title}")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating genres for {artist.title}: {e}")
|
||||
return False
|
||||
|
||||
def update_artist_poster(self, artist, image_data: bytes):
|
||||
"""Update artist poster image using Jellyfin API"""
|
||||
try:
|
||||
artist_id = artist.ratingKey
|
||||
if not artist_id:
|
||||
return False
|
||||
|
||||
import requests
|
||||
|
||||
url = f"{self.base_url}/Items/{artist_id}/Images/Primary"
|
||||
headers = {
|
||||
'X-Emby-Token': self.api_key
|
||||
}
|
||||
|
||||
# Try multiple approaches to find what works with Jellyfin
|
||||
|
||||
# Method 1: Try with different field names that Jellyfin might expect
|
||||
method1_files = {'data': ('poster.jpg', image_data, 'image/jpeg')}
|
||||
try:
|
||||
response = requests.post(url, files=method1_files, headers=headers, timeout=30)
|
||||
response.raise_for_status()
|
||||
logger.info(f"Updated poster for {artist.title} (method 1)")
|
||||
return True
|
||||
except Exception as e1:
|
||||
logger.debug(f"Method 1 failed for {artist.title}: {e1}")
|
||||
|
||||
# Method 2: Try with raw data and proper content-type
|
||||
try:
|
||||
headers_raw = {
|
||||
'X-Emby-Token': self.api_key,
|
||||
'Content-Type': 'image/jpeg'
|
||||
}
|
||||
response = requests.post(url, data=image_data, headers=headers_raw, timeout=30)
|
||||
response.raise_for_status()
|
||||
logger.info(f"Updated poster for {artist.title} (method 2)")
|
||||
return True
|
||||
except Exception as e2:
|
||||
logger.debug(f"Method 2 failed for {artist.title}: {e2}")
|
||||
|
||||
# Method 3: Try with different endpoint structure
|
||||
try:
|
||||
alt_url = f"{self.base_url}/Items/{artist_id}/Images/Primary/0"
|
||||
response = requests.post(alt_url, data=image_data, headers=headers_raw, timeout=30)
|
||||
response.raise_for_status()
|
||||
logger.info(f"Updated poster for {artist.title} (method 3)")
|
||||
return True
|
||||
except Exception as e3:
|
||||
logger.debug(f"Method 3 failed for {artist.title}: {e3}")
|
||||
|
||||
# All methods failed
|
||||
logger.error(f"All image upload methods failed for {artist.title}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating poster for {artist.title}: {e}")
|
||||
return False
|
||||
|
||||
def update_album_poster(self, album, image_data: bytes):
|
||||
"""Update album poster image using Jellyfin API"""
|
||||
try:
|
||||
album_id = album.ratingKey
|
||||
if not album_id:
|
||||
return False
|
||||
|
||||
import requests
|
||||
|
||||
url = f"{self.base_url}/Items/{album_id}/Images/Primary"
|
||||
headers = {
|
||||
'X-Emby-Token': self.api_key
|
||||
}
|
||||
|
||||
# Try multiple approaches to find what works with Jellyfin
|
||||
|
||||
# Method 1: Try with different field names that Jellyfin might expect
|
||||
method1_files = {'data': ('poster.jpg', image_data, 'image/jpeg')}
|
||||
try:
|
||||
response = requests.post(url, files=method1_files, headers=headers, timeout=30)
|
||||
response.raise_for_status()
|
||||
logger.info(f"Updated poster for album '{album.title}' (method 1)")
|
||||
return True
|
||||
except Exception as e1:
|
||||
logger.debug(f"Method 1 failed for album '{album.title}': {e1}")
|
||||
|
||||
# Method 2: Try with raw data and proper content-type
|
||||
try:
|
||||
headers_raw = {
|
||||
'X-Emby-Token': self.api_key,
|
||||
'Content-Type': 'image/jpeg'
|
||||
}
|
||||
response = requests.post(url, data=image_data, headers=headers_raw, timeout=30)
|
||||
response.raise_for_status()
|
||||
logger.info(f"Updated poster for album '{album.title}' (method 2)")
|
||||
return True
|
||||
except Exception as e2:
|
||||
logger.debug(f"Method 2 failed for album '{album.title}': {e2}")
|
||||
|
||||
# Method 3: Try with different endpoint structure
|
||||
try:
|
||||
alt_url = f"{self.base_url}/Items/{album_id}/Images/Primary/0"
|
||||
response = requests.post(alt_url, data=image_data, headers=headers_raw, timeout=30)
|
||||
response.raise_for_status()
|
||||
logger.info(f"Updated poster for album '{album.title}' (method 3)")
|
||||
return True
|
||||
except Exception as e3:
|
||||
logger.debug(f"Method 3 failed for album '{album.title}': {e3}")
|
||||
|
||||
# All methods failed
|
||||
logger.error(f"All image upload methods failed for album '{album.title}'")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating poster for album '{album.title}': {e}")
|
||||
return False
|
||||
|
||||
def update_artist_biography(self, artist) -> bool:
|
||||
"""Update artist overview/biography - currently not implemented for Jellyfin"""
|
||||
try:
|
||||
# TODO: Implement Jellyfin biography update API
|
||||
# For now, just log and return success to continue processing
|
||||
logger.debug(f"Biography update not yet implemented for Jellyfin artist: {artist.title}")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating biography for {artist.title}: {e}")
|
||||
return False
|
||||
|
||||
def needs_update_by_age(self, artist, refresh_interval_days: int) -> bool:
|
||||
"""Check if artist needs updating based on age threshold - simplified for Jellyfin"""
|
||||
try:
|
||||
# For now, just return True for all artists since we don't have timestamp tracking yet
|
||||
# TODO: Implement timestamp tracking in Jellyfin artist metadata
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.debug(f"Error checking update age for {artist.title}: {e}")
|
||||
return True
|
||||
|
||||
def is_artist_ignored(self, artist) -> bool:
|
||||
"""Check if artist is manually marked to be ignored - simplified for Jellyfin"""
|
||||
try:
|
||||
# For now, no artists are ignored
|
||||
# TODO: Implement ignore flag tracking in Jellyfin artist metadata
|
||||
return False
|
||||
except Exception as e:
|
||||
logger.debug(f"Error checking ignore status for {artist.title}: {e}")
|
||||
return False
|
||||
|
||||
def parse_update_timestamp(self, artist) -> Optional[datetime]:
|
||||
"""Parse the last update timestamp from artist summary - not implemented for Jellyfin"""
|
||||
try:
|
||||
# TODO: Implement timestamp parsing from Jellyfin artist overview
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.debug(f"Error parsing timestamp for {artist.title}: {e}")
|
||||
return None
|
||||
|
||||
def set_metadata_only_mode(self, enabled: bool = True):
|
||||
"""Enable metadata-only mode to skip expensive track caching"""
|
||||
try:
|
||||
self._metadata_only_mode = enabled
|
||||
if enabled:
|
||||
logger.info("🎯 Metadata-only mode enabled - will skip expensive track caching")
|
||||
else:
|
||||
logger.info("🎯 Metadata-only mode disabled")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"Error setting metadata-only mode: {e}")
|
||||
return False
|
||||
|
|
@ -1404,18 +1404,19 @@ class SimpleWishlistDownloadWorker(QRunnable):
|
|||
|
||||
|
||||
class MetadataUpdateWorker(QThread):
|
||||
"""Worker thread for updating Plex artist metadata using Spotify data"""
|
||||
"""Worker thread for updating artist metadata using Spotify data (supports both Plex and Jellyfin)"""
|
||||
progress_updated = pyqtSignal(str, int, int, float) # current_artist, processed, total, percentage
|
||||
artist_updated = pyqtSignal(str, bool, str) # artist_name, success, details
|
||||
finished = pyqtSignal(int, int, int) # total_processed, successful, failed
|
||||
error = pyqtSignal(str) # error_message
|
||||
artists_loaded = pyqtSignal(int, int) # total_artists, artists_to_process
|
||||
|
||||
def __init__(self, artists, plex_client, spotify_client, refresh_interval_days=30):
|
||||
def __init__(self, artists, media_client, spotify_client, server_type, refresh_interval_days=30):
|
||||
super().__init__()
|
||||
self.artists = artists
|
||||
self.plex_client = plex_client
|
||||
self.media_client = media_client # Can be plex_client or jellyfin_client
|
||||
self.spotify_client = spotify_client
|
||||
self.server_type = server_type # "plex" or "jellyfin"
|
||||
self.matching_engine = MusicMatchingEngine()
|
||||
self.refresh_interval_days = refresh_interval_days
|
||||
self.should_stop = False
|
||||
|
|
@ -1428,14 +1429,23 @@ class MetadataUpdateWorker(QThread):
|
|||
def stop(self):
|
||||
self.should_stop = True
|
||||
|
||||
def get_artist_name(self, artist):
|
||||
"""Get artist name consistently across Plex and Jellyfin"""
|
||||
# Both Plex and Jellyfin wrapper objects have .title attribute
|
||||
return getattr(artist, 'title', 'Unknown Artist')
|
||||
|
||||
def run(self):
|
||||
"""Process all artists one by one"""
|
||||
try:
|
||||
# Load artists in background if not provided
|
||||
if self.artists is None:
|
||||
all_artists = self.plex_client.get_all_artists()
|
||||
# Enable lightweight mode for Jellyfin to skip track caching
|
||||
if self.server_type == "jellyfin":
|
||||
self.media_client.set_metadata_only_mode(True)
|
||||
|
||||
all_artists = self.media_client.get_all_artists()
|
||||
if not all_artists:
|
||||
self.error.emit("No artists found in Plex library")
|
||||
self.error.emit(f"No artists found in {self.server_type.title()} library")
|
||||
return
|
||||
|
||||
# Filter artists that need processing
|
||||
|
|
@ -1460,7 +1470,7 @@ class MetadataUpdateWorker(QThread):
|
|||
artist_name = getattr(artist, 'title', 'Unknown Artist')
|
||||
|
||||
# Double-check ignore flag right before processing (in case it was added after loading)
|
||||
if self.plex_client.is_artist_ignored(artist):
|
||||
if self.media_client.is_artist_ignored(artist):
|
||||
return (artist_name, True, "Skipped (ignored)")
|
||||
|
||||
try:
|
||||
|
|
@ -1505,9 +1515,12 @@ class MetadataUpdateWorker(QThread):
|
|||
def artist_needs_processing(self, artist):
|
||||
"""Check if an artist needs metadata processing using age-based detection"""
|
||||
try:
|
||||
# Use PlexClient's age-based checking with configured interval
|
||||
# This also handles the ignore flag check internally
|
||||
return self.plex_client.needs_update_by_age(artist, self.refresh_interval_days)
|
||||
# Check if artist is manually ignored
|
||||
if self.media_client.is_artist_ignored(artist):
|
||||
return False
|
||||
|
||||
# Use media client's age-based checking with configured interval
|
||||
return self.media_client.needs_update_by_age(artist, self.refresh_interval_days)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error checking artist {getattr(artist, 'title', 'Unknown')}: {e}")
|
||||
|
|
@ -1557,14 +1570,18 @@ class MetadataUpdateWorker(QThread):
|
|||
if genres_updated:
|
||||
changes_made.append("genres")
|
||||
|
||||
# Update album artwork
|
||||
albums_updated = self.update_album_artwork(artist, spotify_artist)
|
||||
if albums_updated > 0:
|
||||
changes_made.append(f"{albums_updated} album art")
|
||||
# Update album artwork (only for Plex, skip for Jellyfin due to API issues)
|
||||
if self.server_type == "plex":
|
||||
albums_updated = self.update_album_artwork(artist, spotify_artist)
|
||||
if albums_updated > 0:
|
||||
changes_made.append(f"{albums_updated} album art")
|
||||
else:
|
||||
# Skip album artwork for Jellyfin until API issues are resolved
|
||||
logger.debug(f"Skipping album artwork updates for Jellyfin artist: {artist.title}")
|
||||
|
||||
if changes_made:
|
||||
# Update artist biography with timestamp to track last update
|
||||
biography_updated = self.plex_client.update_artist_biography(artist)
|
||||
biography_updated = self.media_client.update_artist_biography(artist)
|
||||
if biography_updated:
|
||||
changes_made.append("timestamp")
|
||||
|
||||
|
|
@ -1572,7 +1589,7 @@ class MetadataUpdateWorker(QThread):
|
|||
return True, details
|
||||
else:
|
||||
# Even if no metadata changes, update biography to record we checked this artist
|
||||
self.plex_client.update_artist_biography(artist)
|
||||
self.media_client.update_artist_biography(artist)
|
||||
return True, "Already up to date"
|
||||
|
||||
except Exception as e:
|
||||
|
|
@ -1642,8 +1659,8 @@ class MetadataUpdateWorker(QThread):
|
|||
|
||||
print(f"[DEBUG] Updating genres for '{artist.title}' to: {genre_list}")
|
||||
|
||||
# Use Plex API to update genres
|
||||
success = self.plex_client.update_artist_genres(artist, genre_list)
|
||||
# Use media client API to update genres
|
||||
success = self.media_client.update_artist_genres(artist, genre_list)
|
||||
if success:
|
||||
print(f"[DEBUG] Successfully updated genres for '{artist.title}'")
|
||||
return True
|
||||
|
|
@ -1801,8 +1818,8 @@ class MetadataUpdateWorker(QThread):
|
|||
print(f"Invalid image data for album '{album_title}'")
|
||||
return False
|
||||
|
||||
# Upload to Plex using our new method
|
||||
success = self.plex_client.update_album_poster(album, image_data)
|
||||
# Upload using media client
|
||||
success = self.media_client.update_album_poster(album, image_data)
|
||||
if success:
|
||||
print(f"✅ Updated artwork for album '{album_title}'")
|
||||
else:
|
||||
|
|
@ -1852,26 +1869,31 @@ class MetadataUpdateWorker(QThread):
|
|||
return None
|
||||
|
||||
def upload_artist_poster(self, artist, image_data):
|
||||
"""Upload poster to Plex"""
|
||||
"""Upload poster using media client"""
|
||||
try:
|
||||
# Use Plex client's update method if available
|
||||
if hasattr(self.plex_client, 'update_artist_poster'):
|
||||
return self.plex_client.update_artist_poster(artist, image_data)
|
||||
# Use media client's update method if available
|
||||
if hasattr(self.media_client, 'update_artist_poster'):
|
||||
return self.media_client.update_artist_poster(artist, image_data)
|
||||
|
||||
# Fallback: direct Plex API call
|
||||
server = self.plex_client.server
|
||||
upload_url = f"{server._baseurl}/library/metadata/{artist.ratingKey}/posters"
|
||||
headers = {
|
||||
'X-Plex-Token': server._token,
|
||||
'Content-Type': 'image/jpeg'
|
||||
}
|
||||
|
||||
response = requests.post(upload_url, data=image_data, headers=headers)
|
||||
response.raise_for_status()
|
||||
|
||||
# Refresh artist to see changes
|
||||
artist.refresh()
|
||||
return True
|
||||
# Fallback for Plex: direct API call
|
||||
if self.server_type == "plex":
|
||||
import requests
|
||||
server = self.media_client.server
|
||||
upload_url = f"{server._baseurl}/library/metadata/{artist.ratingKey}/posters"
|
||||
headers = {
|
||||
'X-Plex-Token': server._token,
|
||||
'Content-Type': 'image/jpeg'
|
||||
}
|
||||
|
||||
response = requests.post(upload_url, data=image_data, headers=headers)
|
||||
response.raise_for_status()
|
||||
|
||||
# Refresh artist to see changes
|
||||
artist.refresh()
|
||||
return True
|
||||
else:
|
||||
# For other server types, return False since we only have fallback for Plex
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error uploading poster: {e}")
|
||||
|
|
@ -3092,13 +3114,20 @@ class DashboardPage(QWidget):
|
|||
self.database_widget = DatabaseUpdaterWidget()
|
||||
self.database_widget.start_button.clicked.connect(self.toggle_database_update)
|
||||
|
||||
# Metadata updater widget (SECOND)
|
||||
self.metadata_widget = MetadataUpdaterWidget()
|
||||
self.metadata_widget.start_button.clicked.connect(self.toggle_metadata_update)
|
||||
# Metadata updater widget (SECOND) - only show for Plex
|
||||
from config.settings import config_manager
|
||||
active_server = config_manager.get_active_media_server()
|
||||
|
||||
if active_server == "plex":
|
||||
self.metadata_widget = MetadataUpdaterWidget()
|
||||
self.metadata_widget.start_button.clicked.connect(self.toggle_metadata_update)
|
||||
else:
|
||||
self.metadata_widget = None # Hide for Jellyfin
|
||||
|
||||
layout.addWidget(header_label)
|
||||
layout.addWidget(self.database_widget)
|
||||
layout.addWidget(self.metadata_widget)
|
||||
if self.metadata_widget: # Only add if it exists
|
||||
layout.addWidget(self.metadata_widget)
|
||||
|
||||
return section
|
||||
|
||||
|
|
@ -3399,6 +3428,9 @@ class DashboardPage(QWidget):
|
|||
|
||||
def toggle_metadata_update(self):
|
||||
"""Toggle metadata update process"""
|
||||
if not self.metadata_widget:
|
||||
return # Metadata widget not available (Jellyfin server)
|
||||
|
||||
current_text = self.metadata_widget.start_button.text()
|
||||
if "Begin" in current_text:
|
||||
# Start metadata update
|
||||
|
|
@ -3418,13 +3450,17 @@ class DashboardPage(QWidget):
|
|||
active_server = config_manager.get_active_media_server()
|
||||
|
||||
# Currently metadata updater only supports Plex
|
||||
if active_server != "plex":
|
||||
self.add_activity_item("❌", "Metadata Update", f"Metadata updater only supports Plex (active: {active_server.title()})", "Now")
|
||||
return
|
||||
|
||||
if not hasattr(self, 'data_provider') or not self.data_provider.service_clients.get('plex_client'):
|
||||
self.add_activity_item("❌", "Metadata Update", "Plex client not available", "Now")
|
||||
return
|
||||
# Check if we have the active media server client
|
||||
if active_server == "jellyfin":
|
||||
media_client = self.data_provider.service_clients.get('jellyfin_client')
|
||||
if not media_client:
|
||||
self.add_activity_item("❌", "Metadata Update", "Jellyfin client not available", "Now")
|
||||
return
|
||||
else:
|
||||
media_client = self.data_provider.service_clients.get('plex_client')
|
||||
if not media_client:
|
||||
self.add_activity_item("❌", "Metadata Update", "Plex client not available", "Now")
|
||||
return
|
||||
|
||||
if not self.data_provider.service_clients.get('spotify_client'):
|
||||
self.add_activity_item("❌", "Metadata Update", "Spotify client not available", "Now")
|
||||
|
|
@ -3432,13 +3468,14 @@ class DashboardPage(QWidget):
|
|||
|
||||
try:
|
||||
# Get refresh interval from dropdown
|
||||
refresh_interval_days = self.metadata_widget.get_refresh_interval_days()
|
||||
refresh_interval_days = self.metadata_widget.get_refresh_interval_days() if self.metadata_widget else 30
|
||||
|
||||
# Start the metadata update worker (it will handle artist retrieval in background)
|
||||
self.metadata_worker = MetadataUpdateWorker(
|
||||
None, # Artists will be loaded in the worker thread
|
||||
self.data_provider.service_clients['plex_client'],
|
||||
media_client,
|
||||
self.data_provider.service_clients['spotify_client'],
|
||||
active_server,
|
||||
refresh_interval_days
|
||||
)
|
||||
|
||||
|
|
@ -3450,8 +3487,9 @@ class DashboardPage(QWidget):
|
|||
self.metadata_worker.artists_loaded.connect(self.on_artists_loaded)
|
||||
|
||||
# Update UI and start
|
||||
self.metadata_widget.update_progress(True, "Loading artists...", 0, 0, 0.0)
|
||||
self.add_activity_item("🎵", "Metadata Update", "Loading artists from Plex library...", "Now")
|
||||
if self.metadata_widget:
|
||||
self.metadata_widget.update_progress(True, "Loading artists...", 0, 0, 0.0)
|
||||
self.add_activity_item("🎵", "Metadata Update", "Loading artists from library...", "Now")
|
||||
|
||||
self.metadata_worker.start()
|
||||
|
||||
|
|
@ -3473,7 +3511,8 @@ class DashboardPage(QWidget):
|
|||
if self.metadata_worker.isRunning():
|
||||
self.metadata_worker.terminate()
|
||||
|
||||
self.metadata_widget.update_progress(False, "", 0, 0, 0.0)
|
||||
if self.metadata_widget:
|
||||
self.metadata_widget.update_progress(False, "", 0, 0, 0.0)
|
||||
self.add_activity_item("⏹️", "Metadata Update", "Stopped metadata update process", "Now")
|
||||
|
||||
def artist_needs_processing(self, artist):
|
||||
|
|
@ -3512,7 +3551,8 @@ class DashboardPage(QWidget):
|
|||
|
||||
def on_metadata_progress(self, current_artist, processed, total, percentage):
|
||||
"""Handle metadata update progress"""
|
||||
self.metadata_widget.update_progress(True, current_artist, processed, total, percentage)
|
||||
if self.metadata_widget:
|
||||
self.metadata_widget.update_progress(True, current_artist, processed, total, percentage)
|
||||
|
||||
def on_artist_updated(self, artist_name, success, details):
|
||||
"""Handle individual artist update completion"""
|
||||
|
|
@ -3523,13 +3563,15 @@ class DashboardPage(QWidget):
|
|||
|
||||
def on_metadata_finished(self, total_processed, successful, failed):
|
||||
"""Handle metadata update completion"""
|
||||
self.metadata_widget.update_progress(False, "", 0, 0, 0.0)
|
||||
if self.metadata_widget:
|
||||
self.metadata_widget.update_progress(False, "", 0, 0, 0.0)
|
||||
summary = f"Processed {total_processed} artists: {successful} updated, {failed} failed"
|
||||
self.add_activity_item("🎵", "Metadata Complete", summary, "Now")
|
||||
|
||||
def on_metadata_error(self, error_message):
|
||||
"""Handle metadata update error"""
|
||||
self.metadata_widget.update_progress(False, "", 0, 0, 0.0)
|
||||
if self.metadata_widget:
|
||||
self.metadata_widget.update_progress(False, "", 0, 0, 0.0)
|
||||
self.add_activity_item("❌", "Metadata Error", error_message, "Now")
|
||||
|
||||
def on_service_status_updated(self, service: str, connected: bool, response_time: float, error: str):
|
||||
|
|
@ -3569,7 +3611,8 @@ class DashboardPage(QWidget):
|
|||
|
||||
def on_metadata_progress_updated(self, is_running: bool, current_artist: str, processed: int, total: int, percentage: float):
|
||||
"""Handle metadata update progress"""
|
||||
self.metadata_widget.update_progress(is_running, current_artist, processed, total, percentage)
|
||||
if self.metadata_widget:
|
||||
self.metadata_widget.update_progress(is_running, current_artist, processed, total, percentage)
|
||||
|
||||
def on_sync_progress_updated(self, current_playlist: str, active_syncs: int):
|
||||
"""Handle sync progress updates"""
|
||||
|
|
|
|||
Loading…
Reference in a new issue