improved metadata speed
This commit is contained in:
parent
86561b60e1
commit
6bc87cc0f5
5 changed files with 183 additions and 0 deletions
Binary file not shown.
|
|
@ -472,6 +472,28 @@ class PlexClient:
|
|||
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"""
|
||||
try:
|
||||
# Upload poster using Plex API
|
||||
upload_url = f"{self.server._baseurl}/library/metadata/{album.ratingKey}/posters"
|
||||
headers = {
|
||||
'X-Plex-Token': self.server._token,
|
||||
'Content-Type': 'image/jpeg'
|
||||
}
|
||||
|
||||
response = requests.post(upload_url, data=image_data, headers=headers)
|
||||
response.raise_for_status()
|
||||
|
||||
# Refresh album to see changes
|
||||
album.refresh()
|
||||
logger.info(f"Updated poster for album '{album.title}' by '{album.parentTitle}'")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating poster for album '{album.title}': {e}")
|
||||
return False
|
||||
|
||||
def parse_update_timestamp(self, artist: PlexArtist) -> Optional[datetime]:
|
||||
"""Parse the last update timestamp from artist summary"""
|
||||
try:
|
||||
|
|
|
|||
BIN
ui/pages/__pycache__/dashboard.cpython-310.pyc
Normal file
BIN
ui/pages/__pycache__/dashboard.cpython-310.pyc
Normal file
Binary file not shown.
Binary file not shown.
|
|
@ -175,6 +175,11 @@ 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")
|
||||
|
||||
if changes_made:
|
||||
# Update artist biography with timestamp to track last update
|
||||
biography_updated = self.plex_client.update_artist_biography(artist)
|
||||
|
|
@ -271,6 +276,162 @@ class MetadataUpdateWorker(QThread):
|
|||
print(f"Error updating genres for {getattr(artist, 'title', 'Unknown')}: {e}")
|
||||
return False
|
||||
|
||||
def update_album_artwork(self, artist, spotify_artist):
|
||||
"""Update album artwork for all albums by this artist"""
|
||||
try:
|
||||
updated_count = 0
|
||||
skipped_count = 0
|
||||
|
||||
# Get all albums for this artist
|
||||
try:
|
||||
albums = list(artist.albums())
|
||||
except Exception:
|
||||
print(f"Could not access albums for artist '{artist.title}'")
|
||||
return 0
|
||||
|
||||
if not albums:
|
||||
print(f"No albums found for artist '{artist.title}'")
|
||||
return 0
|
||||
|
||||
print(f"🎨 Checking artwork for {len(albums)} albums by '{artist.title}'...")
|
||||
|
||||
for album in albums:
|
||||
try:
|
||||
album_title = getattr(album, 'title', 'Unknown Album')
|
||||
|
||||
# Check if album already has good artwork (debug=True to see detection logic)
|
||||
if self.album_has_valid_artwork(album, debug=True):
|
||||
skipped_count += 1
|
||||
continue
|
||||
|
||||
print(f"Album '{album_title}' needs artwork - searching Spotify...")
|
||||
|
||||
# Search for this specific album on Spotify
|
||||
album_query = f"album:{album_title} artist:{spotify_artist.name}"
|
||||
spotify_albums = self.spotify_client.search_albums(album_query, limit=3)
|
||||
|
||||
if not spotify_albums:
|
||||
print(f"No Spotify results for album '{album_title}'")
|
||||
continue
|
||||
|
||||
# Find the best matching album
|
||||
best_album = None
|
||||
highest_score = 0.0
|
||||
|
||||
plex_album_normalized = self.matching_engine.normalize_string(album_title)
|
||||
|
||||
for spotify_album in spotify_albums:
|
||||
spotify_album_normalized = self.matching_engine.normalize_string(spotify_album.name)
|
||||
score = self.matching_engine.similarity_score(plex_album_normalized, spotify_album_normalized)
|
||||
|
||||
if score > highest_score:
|
||||
highest_score = score
|
||||
best_album = spotify_album
|
||||
|
||||
# If we found a good match with artwork, download it
|
||||
if best_album and highest_score > 0.7 and best_album.image_url:
|
||||
print(f"Found Spotify match: '{best_album.name}' (score: {highest_score:.2f})")
|
||||
|
||||
# Download and upload the artwork
|
||||
if self.download_and_upload_album_artwork(album, best_album.image_url):
|
||||
updated_count += 1
|
||||
|
||||
else:
|
||||
print(f"No good Spotify match for album '{album_title}' (best score: {highest_score:.2f})")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error processing album '{getattr(album, 'title', 'Unknown')}': {e}")
|
||||
continue
|
||||
|
||||
total_processed = updated_count + skipped_count
|
||||
print(f"🎨 Artwork summary for '{artist.title}': {updated_count} updated, {skipped_count} skipped (already have good artwork)")
|
||||
|
||||
if updated_count == 0 and skipped_count == len(albums):
|
||||
print(f" ✅ All albums already have good artwork - no Spotify API calls needed!")
|
||||
return updated_count
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error updating album artwork for artist '{getattr(artist, 'title', 'Unknown')}': {e}")
|
||||
return 0
|
||||
|
||||
def album_has_valid_artwork(self, album, debug=False):
|
||||
"""Check if album has valid artwork - conservative approach"""
|
||||
try:
|
||||
album_title = getattr(album, 'title', 'Unknown Album')
|
||||
|
||||
# Check if album has any thumb at all
|
||||
if not hasattr(album, 'thumb') or not album.thumb:
|
||||
if debug: print(f" 🎨 Album '{album_title}' has NO THUMB - needs update")
|
||||
return False
|
||||
|
||||
thumb_url = str(album.thumb)
|
||||
if debug: print(f" 🔍 Album '{album_title}' artwork URL: {thumb_url}")
|
||||
|
||||
# CONSERVATIVE APPROACH: Only mark as "needs update" in very obvious cases
|
||||
|
||||
# Case 1: Completely empty or None
|
||||
if not thumb_url or thumb_url.strip() == '':
|
||||
if debug: print(f" 🎨 Album '{album_title}' has empty URL - needs update")
|
||||
return False
|
||||
|
||||
# Case 2: Obvious placeholder text in URL
|
||||
obvious_placeholders = [
|
||||
'no-image',
|
||||
'placeholder',
|
||||
'missing',
|
||||
'default-album',
|
||||
'blank.jpg',
|
||||
'empty.png'
|
||||
]
|
||||
|
||||
thumb_lower = thumb_url.lower()
|
||||
for placeholder in obvious_placeholders:
|
||||
if placeholder in thumb_lower:
|
||||
if debug: print(f" 🎨 Album '{album_title}' has obvious placeholder ({placeholder}) - needs update")
|
||||
return False
|
||||
|
||||
# Case 3: Extremely short URLs (likely broken)
|
||||
if len(thumb_url) < 20:
|
||||
if debug: print(f" 🎨 Album '{album_title}' has very short URL ({len(thumb_url)} chars) - needs update")
|
||||
return False
|
||||
|
||||
# OTHERWISE: Assume it has valid artwork and SKIP updating
|
||||
if debug: print(f" ✅ Album '{album_title}' appears to have artwork - SKIPPING (URL: {len(thumb_url)} chars)")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
if debug: print(f" ❌ Error checking artwork for album '{album_title}': {e}")
|
||||
# If we can't check, be conservative and skip updating
|
||||
return True
|
||||
|
||||
def download_and_upload_album_artwork(self, album, image_url):
|
||||
"""Download artwork from Spotify and upload to Plex"""
|
||||
try:
|
||||
album_title = getattr(album, 'title', 'Unknown Album')
|
||||
|
||||
# Download image from Spotify
|
||||
response = requests.get(image_url, timeout=10)
|
||||
response.raise_for_status()
|
||||
|
||||
# Validate and convert image (reuse existing function)
|
||||
image_data = self.validate_and_convert_image(response.content)
|
||||
if not image_data:
|
||||
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)
|
||||
if success:
|
||||
print(f"✅ Updated artwork for album '{album_title}'")
|
||||
else:
|
||||
print(f"❌ Failed to upload artwork for album '{album_title}'")
|
||||
|
||||
return success
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error downloading/uploading artwork for album '{getattr(album, 'title', 'Unknown')}': {e}")
|
||||
return False
|
||||
|
||||
def artist_has_valid_photo(self, artist):
|
||||
"""Check if artist has a valid photo"""
|
||||
try:
|
||||
|
|
|
|||
Loading…
Reference in a new issue