From c1ef32acd2a220d39c21ae8d7bdba91efba3017c Mon Sep 17 00:00:00 2001 From: Broque Thomas <26755000+Nezreka@users.noreply.github.com> Date: Tue, 14 Apr 2026 12:30:39 -0700 Subject: [PATCH] Fix source-info popover showing no data due to path format mismatch track_downloads stores local Windows paths but tracks table stores server-side paths (Plex/Jellyfin). Both the track_id lookup (NULL due to failed auto-link at insert time) and exact file_path fallback were failing. Added filename-suffix LIKE matching as a final fallback in get_track_source_info, plus a back-link so the track_id gets written back for fast future lookups. Also improved the auto-link in record_track_download to use the same suffix matching when exact path fails. --- database/music_database.py | 37 +++++++++++++++++++++++++++++++++++++ web_server.py | 11 ++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/database/music_database.py b/database/music_database.py index 4addff94..70ca1e9c 100644 --- a/database/music_database.py +++ b/database/music_database.py @@ -9513,6 +9513,16 @@ class MusicDatabase: if not track_id and file_path: cursor.execute("SELECT id FROM tracks WHERE file_path = ? LIMIT 1", (file_path,)) row = cursor.fetchone() + if not row: + # Fallback: match by filename suffix (handles server path vs local path differences) + import os as _os + fname = _os.path.basename(file_path.replace('\\', '/')) + if fname: + cursor.execute( + "SELECT id FROM tracks WHERE file_path LIKE ? OR file_path LIKE ? LIMIT 1", + (f'%/{fname}', f'%\\{fname}') + ) + row = cursor.fetchone() if row: track_id = str(row[0]) @@ -9577,6 +9587,33 @@ class MusicDatabase: logger.error(f"Error getting download by file path: {e}") return None + def get_download_by_filename(self, filename: str, link_track_id: str = None) -> Optional[dict]: + """Find a download record by filename suffix (handles server vs local path mismatches). + Optionally back-links the track_id on the found record for future fast lookups.""" + try: + conn = self._get_connection() + cursor = conn.cursor() + # Match using both separator styles to handle Windows vs Unix paths + cursor.execute(""" + SELECT * FROM track_downloads + WHERE file_path LIKE ? OR file_path LIKE ? + ORDER BY created_at DESC + LIMIT 1 + """, (f'%/{filename}', f'%\\{filename}')) + row = cursor.fetchone() + if row and link_track_id: + # Back-link this record so future track_id lookups work directly + cursor.execute( + "UPDATE track_downloads SET track_id = ? WHERE id = ? AND track_id IS NULL", + (str(link_track_id), row['id']) + ) + conn.commit() + conn.close() + return dict(row) if row else None + except Exception as e: + logger.error(f"Error getting download by filename: {e}") + return None + # ==================== Discovery Pool Methods ==================== def get_discovery_pool_matched(self, limit: int = 500) -> list: diff --git a/web_server.py b/web_server.py index f39de1df..5a1418f5 100644 --- a/web_server.py +++ b/web_server.py @@ -14362,7 +14362,7 @@ def get_track_source_info(track_id): downloads = database.get_track_downloads(str(track_id)) if not downloads: - # Try matching by file path as fallback + # Try matching by file path as fallback (exact, then filename suffix) conn = database._get_connection() cursor = conn.cursor() cursor.execute("SELECT file_path FROM tracks WHERE id = ?", (track_id,)) @@ -14372,6 +14372,15 @@ def get_track_source_info(track_id): dl = database.get_download_by_file_path(row['file_path']) if dl: downloads = [dl] + else: + # Path format mismatch (e.g. Plex path vs local Windows path) — + # fall back to filename-only match and back-link the track_id + import os as _os + fname = _os.path.basename(row['file_path'].replace('\\', '/')) + if fname: + dl = database.get_download_by_filename(fname, link_track_id=track_id) + if dl: + downloads = [dl] return jsonify({"success": True, "downloads": downloads}) except Exception as e: