diff --git a/.spotify_cache b/.spotify_cache index 20b48515..2fdda7a6 100644 --- a/.spotify_cache +++ b/.spotify_cache @@ -1 +1 @@ -{"access_token": "BQCOv8fOrv4GnSSOovKVMwFz8YN_6oKKiuxjvfiS2m_jhbXRHKwiuL2JkoFWRwtNRjOcJ8HLYBboNNColGWmPtH-jxxSp1dQcn0Ln-vJC6R8MXbjVqiNlVgALF1UaK4-KKzbHaenIy7tPx7BMbZrwhBErrouJttReJB3jqLHGqRAajZI7A3un1x5wC5qAPVHkiI3aX2Z3VTkke5WVzChkt30vrlArNY72K9XXhKZTC4qiUuqcq89tLiusgYLmhCP", "token_type": "Bearer", "expires_in": 3600, "scope": "user-library-read user-read-private playlist-read-private playlist-read-collaborative user-read-email", "expires_at": 1753491117, "refresh_token": "AQDmfQkPCGObfJeTUIbW1hAAwhSqkuHRA3Qh2dqVYMRh0eCkFMQgPNJDDzF8y-BiaVbj80zePkK_XSfYH1aJutMtNbnsqRKWuxP31BTrMc7pdUdbE7Fma4oH8wpDUKdG3MM"} \ No newline at end of file +{"access_token": "BQCCZ_QN3sFdtefCigaIuPuMYIdP2K25HRJ-NAQs1yLwHQkj9YxyvN3zAUEj6A3kANHI5yqH3DGN7oRzAO778PTcxQwcFFbpOWAKgi80owbwXVva_SwcjBL3MyLEAQJh2TN3iolRTWycnfHx0LSvT2Ddkm6o09xjQfxIfI14t5dEwummt4Ceqb0AykByuhtEpSCzjh6Z0cfTayvOYPv_1lgm2JSLalKSaz3osh9PhT-PRLAmbA-F1yCaTs73bnhc", "token_type": "Bearer", "expires_in": 3600, "scope": "user-library-read user-read-private playlist-read-private playlist-read-collaborative user-read-email", "expires_at": 1753495023, "refresh_token": "AQDmfQkPCGObfJeTUIbW1hAAwhSqkuHRA3Qh2dqVYMRh0eCkFMQgPNJDDzF8y-BiaVbj80zePkK_XSfYH1aJutMtNbnsqRKWuxP31BTrMc7pdUdbE7Fma4oH8wpDUKdG3MM"} \ No newline at end of file diff --git a/core/__pycache__/matching_engine.cpython-310.pyc b/core/__pycache__/matching_engine.cpython-310.pyc new file mode 100644 index 00000000..c6dac3e1 Binary files /dev/null and b/core/__pycache__/matching_engine.cpython-310.pyc differ diff --git a/core/__pycache__/matching_engine.cpython-312.pyc b/core/__pycache__/matching_engine.cpython-312.pyc index d45be7fd..21c3d252 100644 Binary files a/core/__pycache__/matching_engine.cpython-312.pyc and b/core/__pycache__/matching_engine.cpython-312.pyc differ diff --git a/core/__pycache__/plex_client.cpython-310.pyc b/core/__pycache__/plex_client.cpython-310.pyc new file mode 100644 index 00000000..0dcbbbe9 Binary files /dev/null and b/core/__pycache__/plex_client.cpython-310.pyc differ diff --git a/core/__pycache__/plex_client.cpython-312.pyc b/core/__pycache__/plex_client.cpython-312.pyc index 6734a464..ae8b0587 100644 Binary files a/core/__pycache__/plex_client.cpython-312.pyc and b/core/__pycache__/plex_client.cpython-312.pyc differ diff --git a/core/matching_engine.py b/core/matching_engine.py index d5923c1f..90e0a95f 100644 --- a/core/matching_engine.py +++ b/core/matching_engine.py @@ -88,6 +88,37 @@ class MusicMatchingEngine: return self.normalize_string(cleaned) + def clean_album_name(self, album_name: str) -> str: + """Clean album name by removing version info, deluxe editions, etc.""" + if not album_name: + return "" + + cleaned = album_name + + # Common album suffixes to remove + album_patterns = [ + r'\s*\(deluxe\s*edition?\)', + r'\s*\(expanded\s*edition?\)', + r'\s*\(remastered?\)', + r'\s*\(remaster\)', + r'\s*\(anniversary\s*edition?\)', + r'\s*\(special\s*edition?\)', + r'\s*\(bonus\s*track\s*version\)', + r'\s*\(.*version\)', # Covers "Taylor's Version", "Radio Version", etc. + r'\s*\[deluxe\]', + r'\s*\[remastered?\]', + r'\s*\[.*version\]', + r'\s*-\s*deluxe', + r'\s*-\s*remastered?', + r'\s*\d{4}\s*remaster', # Year remaster + r'\s*\(\d{4}\s*remaster\)' + ] + + for pattern in album_patterns: + cleaned = re.sub(pattern, '', cleaned, flags=re.IGNORECASE).strip() + + return self.normalize_string(cleaned) + def similarity_score(self, str1: str, str2: str) -> float: """Calculates similarity score between two strings.""" if not str1 or not str2: @@ -259,4 +290,77 @@ class MusicMatchingEngine: # A threshold of 0.6 means the title and artist had to have some reasonable similarity. confident_results = [r for r in sorted_results if r.confidence > 0.6] - return confident_results \ No newline at end of file + return confident_results + + def calculate_album_confidence(self, spotify_album, plex_album_info: Dict[str, Any]) -> float: + """Calculate confidence score for album matching""" + if not spotify_album or not plex_album_info: + return 0.0 + + score = 0.0 + + # 1. Album name similarity (40% weight) + spotify_album_clean = self.clean_album_name(spotify_album.name) + plex_album_clean = self.clean_album_name(plex_album_info['title']) + + name_similarity = self.similarity_score(spotify_album_clean, plex_album_clean) + score += name_similarity * 0.4 + + # 2. Artist similarity (40% weight) + if spotify_album.artists and plex_album_info.get('artist'): + spotify_artist_clean = self.clean_artist(spotify_album.artists[0]) + plex_artist_clean = self.clean_artist(plex_album_info['artist']) + + artist_similarity = self.similarity_score(spotify_artist_clean, plex_artist_clean) + score += artist_similarity * 0.4 + + # 3. Track count similarity (10% weight) + spotify_track_count = getattr(spotify_album, 'total_tracks', 0) + plex_track_count = plex_album_info.get('track_count', 0) + + if spotify_track_count > 0 and plex_track_count > 0: + # Calculate track count similarity (perfect match = 1.0, close matches get partial credit) + track_diff = abs(spotify_track_count - plex_track_count) + if track_diff == 0: + track_similarity = 1.0 + elif track_diff <= 2: # Allow for slight differences (bonus tracks, etc.) + track_similarity = 0.8 + elif track_diff <= 5: + track_similarity = 0.5 + else: + track_similarity = 0.2 + + score += track_similarity * 0.1 + + # 4. Year similarity bonus (10% weight) + spotify_year = spotify_album.release_date[:4] if spotify_album.release_date else None + plex_year = str(plex_album_info.get('year', '')) if plex_album_info.get('year') else None + + if spotify_year and plex_year: + if spotify_year == plex_year: + score += 0.1 # Perfect year match + elif abs(int(spotify_year) - int(plex_year)) <= 1: + score += 0.05 # Close year match (remaster, etc.) + + return min(score, 1.0) # Cap at 1.0 + + def find_best_album_match(self, spotify_album, plex_albums: List[Dict[str, Any]]) -> Tuple[Optional[Dict[str, Any]], float]: + """Find the best matching album from Plex candidates""" + if not plex_albums: + return None, 0.0 + + best_match = None + best_confidence = 0.0 + + for plex_album in plex_albums: + confidence = self.calculate_album_confidence(spotify_album, plex_album) + + if confidence > best_confidence: + best_confidence = confidence + best_match = plex_album + + # Only return matches above confidence threshold + if best_confidence >= 0.8: # High threshold for album matching + return best_match, best_confidence + else: + return None, best_confidence \ No newline at end of file diff --git a/core/plex_client.py b/core/plex_client.py index 2a1dddc2..318924b4 100644 --- a/core/plex_client.py +++ b/core/plex_client.py @@ -441,3 +441,104 @@ class PlexClient: except Exception as e: logger.error(f"Error updating track metadata: {e}") return False + + def search_albums(self, album_name: str = "", artist_name: str = "", limit: int = 20) -> List[Dict[str, Any]]: + """Search for albums in Plex library""" + if not self.ensure_connection() or not self.music_library: + return [] + + try: + albums = [] + + # Perform search - different approaches based on what we're searching for + search_results = [] + + if album_name and artist_name: + # Search for albums by specific artist and title + try: + # First try searching for the artist, then filter their albums + artist_results = self.music_library.searchArtists(title=artist_name, limit=3) + for artist in artist_results: + try: + artist_albums = artist.albums() + for album in artist_albums: + if album_name.lower() in album.title.lower(): + search_results.append(album) + except Exception as e: + logger.debug(f"Error getting albums for artist {artist.title}: {e}") + except Exception as e: + logger.debug(f"Artist search failed, trying general search: {e}") + # Fallback to general album search + try: + search_results = self.music_library.search(title=album_name) + # Filter to only albums + search_results = [r for r in search_results if isinstance(r, PlexAlbum)] + except Exception as e2: + logger.debug(f"General search also failed: {e2}") + + elif album_name: + # Search for albums by title only + try: + search_results = self.music_library.search(title=album_name) + # Filter to only albums + search_results = [r for r in search_results if isinstance(r, PlexAlbum)] + except Exception as e: + logger.debug(f"Album title search failed: {e}") + + elif artist_name: + # Search for all albums by artist + try: + artist_results = self.music_library.searchArtists(title=artist_name, limit=1) + if artist_results: + search_results = artist_results[0].albums() + except Exception as e: + logger.debug(f"Artist album search failed: {e}") + else: + # Get all albums if no search terms + try: + search_results = self.music_library.albums() + except Exception as e: + logger.debug(f"Get all albums failed: {e}") + + # Process results and convert to standardized format + if search_results: + for result in search_results: + if isinstance(result, PlexAlbum): + try: + # Get album info + album_info = { + 'id': str(result.ratingKey), + 'title': result.title, + 'artist': result.artist().title if result.artist() else "Unknown Artist", + 'year': result.year, + 'track_count': len(result.tracks()) if hasattr(result, 'tracks') else 0, + 'plex_album': result # Keep reference to original object + } + albums.append(album_info) + + if len(albums) >= limit: + break + + except Exception as e: + logger.debug(f"Error processing album {result.title}: {e}") + continue + + logger.debug(f"Found {len(albums)} albums matching query: album='{album_name}', artist='{artist_name}'") + return albums + + except Exception as e: + logger.error(f"Error searching albums: {e}") + return [] + + def get_album_by_name_and_artist(self, album_name: str, artist_name: str) -> Optional[Dict[str, Any]]: + """Get a specific album by name and artist""" + albums = self.search_albums(album_name, artist_name, limit=5) + + # Look for exact matches first + for album in albums: + if (album['title'].lower() == album_name.lower() and + album['artist'].lower() == artist_name.lower()): + return album + + # Return first result if no exact match + return albums[0] if albums else None diff --git a/logs/app.log b/logs/app.log index 46061f11..532b2dee 100644 --- a/logs/app.log +++ b/logs/app.log @@ -45333,3 +45333,209 @@ 2025-07-25 17:51:45 - newmusic.main - INFO - closeEvent:186 - Stopping status monitoring thread... 2025-07-25 17:51:46 - newmusic.main - INFO - closeEvent:191 - Closing Soulseek client... 2025-07-25 17:51:46 - newmusic.main - INFO - closeEvent:197 - Application closed successfully +2025-07-25 17:56:28 - newmusic - INFO - setup_logging:57 - Logging initialized with level: DEBUG +2025-07-25 17:56:28 - newmusic.main - INFO - main:211 - Starting NewMusic application +2025-07-25 17:56:28 - newmusic.spotify_client - INFO - _setup_client:179 - Spotify client initialized (user info will be fetched when needed) +2025-07-25 17:56:28 - newmusic.soulseek_client - INFO - _setup_client:220 - Soulseek client configured with slskd at http://localhost:5030 +2025-07-25 17:56:28 - newmusic.spotify_client - INFO - _setup_client:179 - Spotify client initialized (user info will be fetched when needed) +2025-07-25 17:56:29 - newmusic.spotify_client - INFO - _setup_client:179 - Spotify client initialized (user info will be fetched when needed) +2025-07-25 17:56:29 - newmusic.soulseek_client - INFO - _setup_client:220 - Soulseek client configured with slskd at http://localhost:5030 +2025-07-25 17:56:29 - newmusic.main - INFO - change_page:163 - Changed to page: dashboard +2025-07-25 17:56:29 - newmusic.main - INFO - setup_media_player_connections:150 - Media player connections established between sidebar and downloads page +2025-07-25 17:56:29 - newmusic.plex_client - INFO - _find_music_library:127 - Found music library: Music +2025-07-25 17:56:29 - newmusic.plex_client - INFO - _setup_client:113 - Successfully connected to Plex server: PLEX-MACHINE +2025-07-25 17:56:58 - newmusic.main - INFO - change_page:163 - Changed to page: artists +2025-07-25 17:57:04 - newmusic.spotify_client - INFO - get_artist_albums:452 - Retrieved 30 albums for artist 06HL4z0CvFAxyc27GXpf02 +2025-07-25 17:57:04 - newmusic.plex_client - INFO - _find_music_library:127 - Found music library: Music +2025-07-25 17:57:04 - newmusic.plex_client - INFO - _setup_client:113 - Successfully connected to Plex server: PLEX-MACHINE +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:57:04 - newmusic.plex_client - ERROR - search_albums:493 - Error searching albums: Unknown filter field "artist" for libtype "artist". Available filter fields: ['artist.title', 'artist.userRating', 'artist.genre', 'artist.collection', 'artist.country', 'artist.mood', 'artist.style', 'artist.addedAt', 'artist.lastViewedAt', 'artist.unmatched', 'artist.guid', 'artist.id', 'artist.index', 'artist.lastRatedAt', 'artist.updatedAt', 'group', 'having', 'artist.label'] +2025-07-25 17:59:05 - newmusic.main - INFO - closeEvent:176 - Closing application... +2025-07-25 17:59:05 - newmusic.main - INFO - closeEvent:181 - Cleaning up Downloads page threads... +2025-07-25 17:59:05 - newmusic.main - INFO - closeEvent:186 - Stopping status monitoring thread... +2025-07-25 17:59:06 - newmusic.main - INFO - closeEvent:191 - Closing Soulseek client... +2025-07-25 17:59:06 - newmusic.main - INFO - closeEvent:197 - Application closed successfully +2025-07-25 17:59:44 - newmusic - INFO - setup_logging:57 - Logging initialized with level: DEBUG +2025-07-25 17:59:44 - newmusic.main - INFO - main:211 - Starting NewMusic application +2025-07-25 17:59:44 - newmusic.spotify_client - INFO - _setup_client:179 - Spotify client initialized (user info will be fetched when needed) +2025-07-25 17:59:44 - newmusic.soulseek_client - INFO - _setup_client:220 - Soulseek client configured with slskd at http://localhost:5030 +2025-07-25 17:59:44 - newmusic.spotify_client - INFO - _setup_client:179 - Spotify client initialized (user info will be fetched when needed) +2025-07-25 17:59:44 - newmusic.spotify_client - INFO - _setup_client:179 - Spotify client initialized (user info will be fetched when needed) +2025-07-25 17:59:44 - newmusic.soulseek_client - INFO - _setup_client:220 - Soulseek client configured with slskd at http://localhost:5030 +2025-07-25 17:59:45 - newmusic.main - INFO - change_page:163 - Changed to page: dashboard +2025-07-25 17:59:45 - newmusic.main - INFO - setup_media_player_connections:150 - Media player connections established between sidebar and downloads page +2025-07-25 17:59:45 - newmusic.plex_client - INFO - _find_music_library:127 - Found music library: Music +2025-07-25 17:59:45 - newmusic.plex_client - INFO - _setup_client:113 - Successfully connected to Plex server: PLEX-MACHINE +2025-07-25 17:59:51 - newmusic.main - INFO - change_page:163 - Changed to page: artists +2025-07-25 18:00:19 - newmusic.spotify_client - INFO - get_artist_albums:452 - Retrieved 30 albums for artist 06HL4z0CvFAxyc27GXpf02 +2025-07-25 18:00:19 - newmusic.plex_client - INFO - _find_music_library:127 - Found music library: Music +2025-07-25 18:00:19 - newmusic.plex_client - INFO - _setup_client:113 - Successfully connected to Plex server: PLEX-MACHINE +2025-07-25 18:00:20 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='THE TORTURED POETS DEPARTMENT: THE ANTHOLOGY', artist='taylor swift' +2025-07-25 18:00:20 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='the tortured poets department the anthology', artist='taylor swift' +2025-07-25 18:00:20 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='the tortured poets department the anthology', artist='' +2025-07-25 18:00:20 - newmusic.plex_client - DEBUG - search_albums:526 - Found 2 albums matching query: album='THE TORTURED POETS DEPARTMENT', artist='taylor swift' +2025-07-25 18:00:20 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='1989 (Taylor's Version) [Deluxe]', artist='taylor swift' +2025-07-25 18:00:20 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='1989 (Taylor's Version) [Deluxe]', artist='' +2025-07-25 18:00:20 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='1989', artist='taylor swift' +2025-07-25 18:00:20 - newmusic.plex_client - DEBUG - search_albums:526 - Found 2 albums matching query: album='1989 (Taylor's Version)', artist='taylor swift' +2025-07-25 18:00:21 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='1989', artist='taylor swift' +2025-07-25 18:00:21 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Speak Now (Taylor's Version)', artist='taylor swift' +2025-07-25 18:00:21 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='speak now', artist='taylor swift' +2025-07-25 18:00:21 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Midnights (The Til Dawn Edition)', artist='taylor swift' +2025-07-25 18:00:21 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='midnights the til dawn edition', artist='taylor swift' +2025-07-25 18:00:21 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='midnights the til dawn edition', artist='' +2025-07-25 18:00:21 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Midnights (3am Edition)', artist='taylor swift' +2025-07-25 18:00:21 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='midnights 3am edition', artist='taylor swift' +2025-07-25 18:00:21 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='midnights 3am edition', artist='' +2025-07-25 18:00:22 - newmusic.plex_client - DEBUG - search_albums:526 - Found 3 albums matching query: album='Midnights', artist='taylor swift' +2025-07-25 18:00:22 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Red (Taylor's Version)', artist='taylor swift' +2025-07-25 18:00:22 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='red', artist='taylor swift' +2025-07-25 18:00:22 - newmusic.plex_client - DEBUG - search_albums:526 - Found 3 albums matching query: album='Fearless (Taylor's Version)', artist='taylor swift' +2025-07-25 18:00:22 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='fearless', artist='taylor swift' +2025-07-25 18:00:22 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='evermore (deluxe version)', artist='taylor swift' +2025-07-25 18:00:23 - newmusic.plex_client - DEBUG - search_albums:526 - Found 2 albums matching query: album='evermore', artist='taylor swift' +2025-07-25 18:00:23 - newmusic.plex_client - DEBUG - search_albums:526 - Found 2 albums matching query: album='evermore', artist='taylor swift' +2025-07-25 18:00:23 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='folklore: the long pond studio sessions (from the Disney+ special) [deluxe edition]', artist='taylor swift' +2025-07-25 18:00:23 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='folklore: the long pond studio sessions (from the Disney+ special) [deluxe edition]', artist='' +2025-07-25 18:00:23 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='folklore the long pond studio sessions from the disney special deluxe edition', artist='taylor swift' +2025-07-25 18:00:23 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='folklore the long pond studio sessions from the disney special deluxe edition', artist='' +2025-07-25 18:00:23 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='folklore (deluxe version)', artist='taylor swift' +2025-07-25 18:00:23 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='folklore', artist='taylor swift' +2025-07-25 18:00:23 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='folklore', artist='taylor swift' +2025-07-25 18:00:24 - newmusic.plex_client - DEBUG - search_albums:526 - Found 2 albums matching query: album='Lover', artist='taylor swift' +2025-07-25 18:00:24 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Taylor Swift Karaoke: reputation', artist='taylor swift' +2025-07-25 18:00:24 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='taylor swift karaoke reputation', artist='taylor swift' +2025-07-25 18:00:24 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='taylor swift karaoke reputation', artist='' +2025-07-25 18:00:24 - newmusic.plex_client - DEBUG - search_albums:526 - Found 4 albums matching query: album='reputation', artist='taylor swift' +2025-07-25 18:00:24 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='reputation Stadium Tour Surprise Song Playlist', artist='taylor swift' +2025-07-25 18:00:24 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='1989 (Deluxe Edition)', artist='taylor swift' +2025-07-25 18:00:24 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='1989', artist='taylor swift' +2025-07-25 18:00:25 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='1989', artist='taylor swift' +2025-07-25 18:00:25 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Red (Deluxe Edition)', artist='taylor swift' +2025-07-25 18:00:25 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='red', artist='taylor swift' +2025-07-25 18:00:25 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='Red', artist='taylor swift' +2025-07-25 18:00:25 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Speak Now World Tour Live', artist='taylor swift' +2025-07-25 18:00:26 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Speak Now (Deluxe Edition)', artist='taylor swift' +2025-07-25 18:00:26 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='speak now', artist='taylor swift' +2025-07-25 18:00:26 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='Speak Now', artist='taylor swift' +2025-07-25 18:00:26 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='Fearless Platinum Edition', artist='taylor swift' +2025-07-25 18:00:26 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='Fearless Platinum Edition', artist='' +2025-07-25 18:00:26 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='Fearless', artist='taylor swift' +2025-07-25 18:00:27 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Live From Clear Channel Stripped 2008', artist='taylor swift' +2025-07-25 18:00:27 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='Taylor Swift', artist='taylor swift' +2025-07-25 18:02:16 - newmusic.main - INFO - closeEvent:176 - Closing application... +2025-07-25 18:02:16 - newmusic.main - INFO - closeEvent:181 - Cleaning up Downloads page threads... +2025-07-25 18:02:16 - newmusic.main - INFO - closeEvent:186 - Stopping status monitoring thread... +2025-07-25 18:02:18 - newmusic.main - INFO - closeEvent:191 - Closing Soulseek client... +2025-07-25 18:02:18 - newmusic.main - INFO - closeEvent:197 - Application closed successfully +2025-07-25 18:02:26 - newmusic - INFO - setup_logging:57 - Logging initialized with level: DEBUG +2025-07-25 18:02:26 - newmusic.main - INFO - main:211 - Starting NewMusic application +2025-07-25 18:02:26 - newmusic.spotify_client - INFO - _setup_client:179 - Spotify client initialized (user info will be fetched when needed) +2025-07-25 18:02:26 - newmusic.soulseek_client - INFO - _setup_client:220 - Soulseek client configured with slskd at http://localhost:5030 +2025-07-25 18:02:26 - newmusic.spotify_client - INFO - _setup_client:179 - Spotify client initialized (user info will be fetched when needed) +2025-07-25 18:02:26 - newmusic.spotify_client - INFO - _setup_client:179 - Spotify client initialized (user info will be fetched when needed) +2025-07-25 18:02:26 - newmusic.soulseek_client - INFO - _setup_client:220 - Soulseek client configured with slskd at http://localhost:5030 +2025-07-25 18:02:26 - newmusic.main - INFO - change_page:163 - Changed to page: dashboard +2025-07-25 18:02:26 - newmusic.main - INFO - setup_media_player_connections:150 - Media player connections established between sidebar and downloads page +2025-07-25 18:02:27 - newmusic.plex_client - INFO - _find_music_library:127 - Found music library: Music +2025-07-25 18:02:27 - newmusic.plex_client - INFO - _setup_client:113 - Successfully connected to Plex server: PLEX-MACHINE +2025-07-25 18:02:39 - newmusic.main - INFO - change_page:163 - Changed to page: artists +2025-07-25 18:02:48 - newmusic.spotify_client - INFO - get_artist_albums:452 - Retrieved 30 albums for artist 06HL4z0CvFAxyc27GXpf02 +2025-07-25 18:02:48 - newmusic.plex_client - INFO - _find_music_library:127 - Found music library: Music +2025-07-25 18:02:48 - newmusic.plex_client - INFO - _setup_client:113 - Successfully connected to Plex server: PLEX-MACHINE +2025-07-25 18:02:48 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='THE TORTURED POETS DEPARTMENT: THE ANTHOLOGY', artist='taylor swift' +2025-07-25 18:02:48 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='the tortured poets department the anthology', artist='taylor swift' +2025-07-25 18:02:48 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='the tortured poets department the anthology', artist='' +2025-07-25 18:02:48 - newmusic.plex_client - DEBUG - search_albums:526 - Found 2 albums matching query: album='THE TORTURED POETS DEPARTMENT', artist='taylor swift' +2025-07-25 18:02:48 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='1989 (Taylor's Version) [Deluxe]', artist='taylor swift' +2025-07-25 18:02:48 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='1989 (Taylor's Version) [Deluxe]', artist='' +2025-07-25 18:02:48 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='1989', artist='taylor swift' +2025-07-25 18:02:49 - newmusic.plex_client - DEBUG - search_albums:526 - Found 2 albums matching query: album='1989 (Taylor's Version)', artist='taylor swift' +2025-07-25 18:02:49 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='1989', artist='taylor swift' +2025-07-25 18:02:49 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Speak Now (Taylor's Version)', artist='taylor swift' +2025-07-25 18:02:49 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='speak now', artist='taylor swift' +2025-07-25 18:02:49 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Midnights (The Til Dawn Edition)', artist='taylor swift' +2025-07-25 18:02:49 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='midnights the til dawn edition', artist='taylor swift' +2025-07-25 18:02:49 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='midnights the til dawn edition', artist='' +2025-07-25 18:02:49 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Midnights (3am Edition)', artist='taylor swift' +2025-07-25 18:02:49 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='midnights 3am edition', artist='taylor swift' +2025-07-25 18:02:49 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='midnights 3am edition', artist='' +2025-07-25 18:02:50 - newmusic.plex_client - DEBUG - search_albums:526 - Found 3 albums matching query: album='Midnights', artist='taylor swift' +2025-07-25 18:02:50 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Red (Taylor's Version)', artist='taylor swift' +2025-07-25 18:02:50 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='red', artist='taylor swift' +2025-07-25 18:02:50 - newmusic.plex_client - DEBUG - search_albums:526 - Found 3 albums matching query: album='Fearless (Taylor's Version)', artist='taylor swift' +2025-07-25 18:02:50 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='fearless', artist='taylor swift' +2025-07-25 18:02:51 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='evermore (deluxe version)', artist='taylor swift' +2025-07-25 18:02:51 - newmusic.plex_client - DEBUG - search_albums:526 - Found 2 albums matching query: album='evermore', artist='taylor swift' +2025-07-25 18:02:51 - newmusic.plex_client - DEBUG - search_albums:526 - Found 2 albums matching query: album='evermore', artist='taylor swift' +2025-07-25 18:02:51 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='folklore: the long pond studio sessions (from the Disney+ special) [deluxe edition]', artist='taylor swift' +2025-07-25 18:02:51 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='folklore: the long pond studio sessions (from the Disney+ special) [deluxe edition]', artist='' +2025-07-25 18:02:51 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='folklore the long pond studio sessions from the disney special deluxe edition', artist='taylor swift' +2025-07-25 18:02:51 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='folklore the long pond studio sessions from the disney special deluxe edition', artist='' +2025-07-25 18:02:51 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='folklore (deluxe version)', artist='taylor swift' +2025-07-25 18:02:51 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='folklore', artist='taylor swift' +2025-07-25 18:02:52 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='folklore', artist='taylor swift' +2025-07-25 18:02:52 - newmusic.plex_client - DEBUG - search_albums:526 - Found 2 albums matching query: album='Lover', artist='taylor swift' +2025-07-25 18:02:52 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Taylor Swift Karaoke: reputation', artist='taylor swift' +2025-07-25 18:02:52 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='taylor swift karaoke reputation', artist='taylor swift' +2025-07-25 18:02:52 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='taylor swift karaoke reputation', artist='' +2025-07-25 18:02:52 - newmusic.plex_client - DEBUG - search_albums:526 - Found 4 albums matching query: album='reputation', artist='taylor swift' +2025-07-25 18:02:52 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='reputation Stadium Tour Surprise Song Playlist', artist='taylor swift' +2025-07-25 18:02:52 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='1989 (Deluxe Edition)', artist='taylor swift' +2025-07-25 18:02:52 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='1989', artist='taylor swift' +2025-07-25 18:02:53 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='1989', artist='taylor swift' +2025-07-25 18:02:53 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Red (Deluxe Edition)', artist='taylor swift' +2025-07-25 18:02:53 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='red', artist='taylor swift' +2025-07-25 18:02:53 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='Red', artist='taylor swift' +2025-07-25 18:02:53 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Speak Now World Tour Live', artist='taylor swift' +2025-07-25 18:02:53 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Speak Now (Deluxe Edition)', artist='taylor swift' +2025-07-25 18:02:54 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='speak now', artist='taylor swift' +2025-07-25 18:02:54 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='Speak Now', artist='taylor swift' +2025-07-25 18:02:54 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='Fearless Platinum Edition', artist='taylor swift' +2025-07-25 18:02:54 - newmusic.plex_client - DEBUG - search_albums:526 - Found 0 albums matching query: album='Fearless Platinum Edition', artist='' +2025-07-25 18:02:54 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='Fearless', artist='taylor swift' +2025-07-25 18:02:54 - newmusic.plex_client - DEBUG - search_albums:526 - Found 1 albums matching query: album='Live From Clear Channel Stripped 2008', artist='taylor swift' +2025-07-25 18:02:55 - newmusic.plex_client - DEBUG - search_albums:526 - Found 5 albums matching query: album='Taylor Swift', artist='taylor swift' diff --git a/ui/pages/__pycache__/artists.cpython-310.pyc b/ui/pages/__pycache__/artists.cpython-310.pyc index d2ebe48a..9ef393be 100644 Binary files a/ui/pages/__pycache__/artists.cpython-310.pyc and b/ui/pages/__pycache__/artists.cpython-310.pyc differ diff --git a/ui/pages/__pycache__/artists.cpython-312.pyc b/ui/pages/__pycache__/artists.cpython-312.pyc index c61e7038..b793437d 100644 Binary files a/ui/pages/__pycache__/artists.cpython-312.pyc and b/ui/pages/__pycache__/artists.cpython-312.pyc differ diff --git a/ui/pages/artists.py b/ui/pages/artists.py index 41e513c9..e311d398 100644 --- a/ui/pages/artists.py +++ b/ui/pages/artists.py @@ -208,7 +208,7 @@ class PlexLibraryWorker(QThread): def run(self): try: - print("🔍 Starting Plex library check...") + print("🔍 Starting robust Plex album matching...") owned_albums = set() if not self.plex_client or not self.plex_client.ensure_connection(): @@ -219,36 +219,77 @@ class PlexLibraryWorker(QThread): if self._stop_requested: return - # Get a smaller sample of tracks to avoid loading 10,000 items - print("📚 Searching Plex library for albums...") - plex_tracks = self.plex_client.search_tracks("", "", limit=1000) # Reduced from 10000 + print(f"📚 Checking {len(self.albums)} Spotify albums against Plex library...") - if self._stop_requested: - return - - # Extract unique album names from Plex - plex_album_names = set() - for track in plex_tracks: + # Use robust matching for each album + for i, spotify_album in enumerate(self.albums): if self._stop_requested: return + + print(f"🎵 Checking album {i+1}/{len(self.albums)}: {spotify_album.name}") + + # Create multiple search variations + album_variations = [] + + # Original name + album_variations.append(spotify_album.name) + + # Cleaned name (removes versions, etc.) + cleaned_name = self.matching_engine.clean_album_name(spotify_album.name) + if cleaned_name != spotify_album.name.lower(): + album_variations.append(cleaned_name) + + # Try different artist combinations + artists_to_try = spotify_album.artists[:2] if spotify_album.artists else [""] + + all_plex_matches = [] + + # Search with different combinations + for artist in artists_to_try: + if self._stop_requested: + return - if track.album and track.album != "Unknown Album": - plex_album_names.add(track.album.lower()) - - print(f"📀 Found {len(plex_album_names)} unique albums in Plex library") - - # Check each Spotify album against Plex albums - for album in self.albums: - if self._stop_requested: - return + artist_clean = self.matching_engine.clean_artist(artist) if artist else "" - album_name_lower = album.name.lower() - for plex_album in plex_album_names: - if self.matching_engine.similarity_score(album_name_lower, plex_album) > 0.8: - owned_albums.add(album.name) - break + for album_name in album_variations: + if self._stop_requested: + return + + # Search Plex for this combination + print(f" 🔍 Searching Plex: album='{album_name}', artist='{artist_clean}'") + plex_albums = self.plex_client.search_albums(album_name, artist_clean, limit=5) + print(f" 📀 Found {len(plex_albums)} Plex albums") + all_plex_matches.extend(plex_albums) + + # Also try album-only search if artist+album didn't work + if not plex_albums and artist_clean: + print(f" 🔍 Trying album-only search: album='{album_name}'") + album_only_results = self.plex_client.search_albums(album_name, "", limit=5) + print(f" 📀 Found {len(album_only_results)} albums (album-only)") + all_plex_matches.extend(album_only_results) + + # Remove duplicates based on album ID + unique_matches = {} + for match in all_plex_matches: + unique_matches[match['id']] = match + + unique_plex_albums = list(unique_matches.values()) + + if unique_plex_albums: + # Use robust matching to find best match + best_match, confidence = self.matching_engine.find_best_album_match( + spotify_album, unique_plex_albums + ) + + if best_match and confidence >= 0.8: + owned_albums.add(spotify_album.name) + print(f"✅ Match found: '{spotify_album.name}' -> '{best_match['title']}' (confidence: {confidence:.2f})") + else: + print(f"❌ No confident match for '{spotify_album.name}' (best: {confidence:.2f})") + else: + print(f"❌ No Plex candidates found for '{spotify_album.name}'") - print(f"✅ Found {len(owned_albums)} owned albums") + print(f"🎯 Final result: {len(owned_albums)} owned albums out of {len(self.albums)}") self.library_checked.emit(owned_albums) except Exception as e: @@ -743,6 +784,7 @@ class AlbumCard(QFrame): super().__init__(parent) self.album = album self.is_owned = is_owned + print(f"🎨 AlbumCard created: '{album.name}' - is_owned: {is_owned}") self.setup_ui() self.load_album_image() @@ -803,7 +845,10 @@ class AlbumCard(QFrame): self.overlay.setFixedSize(164, 164) self.overlay.setAlignment(Qt.AlignmentFlag.AlignCenter) + print(f"🎨 Setting up overlay for '{self.album.name}' - is_owned: {self.is_owned}") + if self.is_owned: + print(f"🎨 Creating OWNED overlay for '{self.album.name}'") self.overlay.setStyleSheet(""" QLabel { background: rgba(29, 185, 84, 0.8); @@ -815,6 +860,7 @@ class AlbumCard(QFrame): """) self.overlay.setText("✓") else: + print(f"🎨 Creating DOWNLOAD overlay for '{self.album.name}'") self.overlay.setStyleSheet(""" QLabel { background: rgba(0, 0, 0, 0.7); @@ -1359,6 +1405,8 @@ class ArtistsPage(QWidget): def display_albums(self, albums, owned_albums): """Display albums in the grid""" + print(f"🎨 Refreshing UI with {len(albums)} albums, {len(owned_albums)} owned") + # Clear existing albums self.clear_albums() @@ -1367,6 +1415,8 @@ class ArtistsPage(QWidget): for album in albums: is_owned = album.name in owned_albums + print(f"🎨 Creating card for '{album.name}' - owned: {is_owned}") + card = AlbumCard(album, is_owned) if not is_owned: card.download_requested.connect(self.on_album_download_requested) @@ -1402,6 +1452,10 @@ class ArtistsPage(QWidget): self.albums_status.setText(f"Found {total_count} albums • {owned_count} owned • {missing_count} available for download") + # Debug output + print(f"🎯 UI Update: {owned_count} owned albums found") + print(f"🎯 Owned albums: {list(owned_albums)}") + # Refresh the display with ownership info self.display_albums(self.current_albums, owned_albums)