Track server push status, expand push to all playlist types, rename to _push_playlist_to_server

This commit is contained in:
JohnBaumb 2026-04-23 00:55:11 -07:00
parent 5415d0fe3c
commit ed013d79b9
2 changed files with 74 additions and 23 deletions

View file

@ -636,7 +636,8 @@ class MusicDatabase:
playlist_folder_mode INTEGER DEFAULT 0,
started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
completed_at TIMESTAMP,
track_results TEXT
track_results TEXT,
server_push_status TEXT
)
""")
cursor.execute("CREATE INDEX IF NOT EXISTS idx_sh_started_at ON sync_history (started_at DESC)")
@ -662,6 +663,16 @@ class MusicDatabase:
except Exception:
pass
# Migration: add server_push_status column to sync_history
try:
cursor.execute("SELECT server_push_status FROM sync_history LIMIT 1")
except Exception:
try:
cursor.execute("ALTER TABLE sync_history ADD COLUMN server_push_status TEXT")
logger.info("Added server_push_status column to sync_history table")
except Exception:
pass
# Migration: add track_artist column for per-track artist on compilations/DJ mixes
try:
cursor.execute("SELECT track_artist FROM tracks LIMIT 1")
@ -10497,6 +10508,20 @@ class MusicDatabase:
logger.debug(f"Error updating sync history track results: {e}")
return False
def update_sync_history_push_status(self, batch_id, status):
"""Update the server push status for a sync_history entry."""
try:
conn = self._get_connection()
cursor = conn.cursor()
cursor.execute("""
UPDATE sync_history SET server_push_status = ? WHERE batch_id = ?
""", (status, batch_id))
conn.commit()
return cursor.rowcount > 0
except Exception as e:
logger.debug(f"Error updating sync history push status: {e}")
return False
def refresh_sync_history_entry(self, entry_id, tracks_found=0, tracks_downloaded=0, tracks_failed=0):
"""Update an existing sync_history entry with new stats and reset timestamps to move it to the top."""
try:
@ -10611,7 +10636,8 @@ class MusicDatabase:
cursor.execute("""
SELECT id, batch_id, playlist_name, source, sync_type, source_page,
total_tracks, tracks_found, tracks_downloaded, tracks_failed,
thumb_url, is_album_download, started_at, completed_at
thumb_url, is_album_download, started_at, completed_at,
server_push_status
FROM sync_history
WHERE completed_at IS NOT NULL
AND started_at >= datetime('now', ? || ' days')

View file

@ -28652,11 +28652,17 @@ def _on_download_completed(batch_id, task_id, success=True):
except Exception:
pass
# Push discover playlists to media server after downloads complete
# Push playlists to media server after downloads complete
playlist_id = batch.get('playlist_id')
if playlist_id and playlist_id.startswith('discover_'):
_push_prefixes = (
'discover_', 'auto_mirror_', 'youtube_mirrored_',
'youtube_', 'tidal_', 'deezer_', 'spotify_public_',
'listenbrainz_', 'beatport_',
)
if playlist_id and playlist_id.startswith(_push_prefixes):
database.update_sync_history_push_status(batch_id, 'pending')
threading.Thread(
target=_push_discover_playlist_to_server,
target=_push_playlist_to_server,
args=(batch_id, batch),
daemon=True
).start()
@ -31912,11 +31918,17 @@ def _check_batch_completion_v2(batch_id):
except Exception:
pass
# Push discover playlists to media server after downloads complete
# Push playlists to media server after downloads complete
playlist_id = batch.get('playlist_id')
if playlist_id and playlist_id.startswith('discover_'):
_push_prefixes = (
'discover_', 'auto_mirror_', 'youtube_mirrored_',
'youtube_', 'tidal_', 'deezer_', 'spotify_public_',
'listenbrainz_', 'beatport_',
)
if playlist_id and playlist_id.startswith(_push_prefixes):
database.update_sync_history_push_status(batch_id, 'pending')
threading.Thread(
target=_push_discover_playlist_to_server,
target=_push_playlist_to_server,
args=(batch_id, batch),
daemon=True
).start()
@ -32464,18 +32476,23 @@ def _record_sync_history_completion(batch_id, batch):
traceback.print_exc()
def _push_discover_playlist_to_server(batch_id, batch):
"""After a discover batch completes, push the playlist to the media server.
Runs in a background thread. Triggers a scan, waits, then searches for tracks and creates/updates the playlist."""
def _push_playlist_to_server(batch_id, batch):
"""After a batch completes, push the playlist to the media server.
Runs in a background thread. Triggers a scan, waits, then searches for tracks and creates/updates the playlist.
Supports discover, mirrored, and auto-mirror playlists."""
database = get_database()
try:
playlist_id = batch.get('playlist_id', '')
playlist_name = batch.get('playlist_name', '')
if not playlist_name:
return
database.update_sync_history_push_status(batch_id, 'pushing')
analysis_results = batch.get('analysis_results', [])
if not analysis_results:
logger.info(f"[DiscoverPush] No analysis results for {playlist_name} - skipping server push")
logger.info(f"[PlaylistPush] No analysis results for {playlist_name} - skipping server push")
database.update_sync_history_push_status(batch_id, 'skipped')
return
# Build list of tracks that should be in the playlist (found in library OR successfully downloaded)
@ -32508,16 +32525,17 @@ def _push_discover_playlist_to_server(batch_id, batch):
})
if not tracks_to_find:
logger.info(f"[DiscoverPush] No tracks to push for {playlist_name}")
logger.info(f"[PlaylistPush] No tracks to push for {playlist_name}")
database.update_sync_history_push_status(batch_id, 'skipped')
return
logger.info(f"[DiscoverPush] {playlist_name}: {len(tracks_to_find)} tracks to push to server, triggering scan first")
logger.info(f"[PlaylistPush] {playlist_name}: {len(tracks_to_find)} tracks to push to server, triggering scan first")
# Trigger a library scan so newly downloaded tracks are indexed
if navidrome_client and navidrome_client.is_connected():
navidrome_client.trigger_library_scan()
elif hasattr(web_scan_manager, 'request_scan'):
web_scan_manager.request_scan(f"Discover playlist push: {playlist_name}")
web_scan_manager.request_scan(f"Playlist push: {playlist_name}")
# Wait for scan to finish (poll every 5s, up to 90s)
if navidrome_client and navidrome_client.is_connected():
@ -32525,7 +32543,7 @@ def _push_discover_playlist_to_server(batch_id, batch):
time.sleep(5)
if not navidrome_client.is_library_scanning():
break
logger.info(f"[DiscoverPush] Scan complete, searching for tracks")
logger.info(f"[PlaylistPush] Scan complete, searching for tracks")
else:
time.sleep(30)
@ -32540,27 +32558,34 @@ def _push_discover_playlist_to_server(batch_id, batch):
nav_track = getattr(best, '_original_navidrome_track', None)
if nav_track:
matched_server_tracks.append(nav_track)
logger.debug(f"[DiscoverPush] Matched: '{t['title']}' by '{t['artist']}'{best.id}")
logger.debug(f"[PlaylistPush] Matched: '{t['title']}' by '{t['artist']}'{best.id}")
else:
matched_server_tracks.append(best)
else:
logger.info(f"[DiscoverPush] No match for: '{t['title']}' by '{t['artist']}'")
logger.info(f"[PlaylistPush] No match for: '{t['title']}' by '{t['artist']}'")
if not matched_server_tracks:
logger.warning(f"[DiscoverPush] No tracks matched on server for {playlist_name}")
logger.warning(f"[PlaylistPush] No tracks matched on server for {playlist_name}")
database.update_sync_history_push_status(batch_id, 'failed')
return
logger.info(f"[DiscoverPush] Pushing {len(matched_server_tracks)}/{len(tracks_to_find)} tracks to '{playlist_name}' on server")
logger.info(f"[PlaylistPush] Pushing {len(matched_server_tracks)}/{len(tracks_to_find)} tracks to '{playlist_name}' on server")
success = navidrome_client.update_playlist(playlist_name, matched_server_tracks)
if success:
logger.info(f"[DiscoverPush] Successfully pushed '{playlist_name}' to server with {len(matched_server_tracks)} tracks")
logger.info(f"[PlaylistPush] Successfully pushed '{playlist_name}' to server with {len(matched_server_tracks)} tracks")
database.update_sync_history_push_status(batch_id, 'success')
else:
logger.warning(f"[DiscoverPush] Failed to push '{playlist_name}' to server")
logger.warning(f"[PlaylistPush] Failed to push '{playlist_name}' to server")
database.update_sync_history_push_status(batch_id, 'failed')
except Exception as e:
logger.error(f"[DiscoverPush] Error pushing playlist to server: {e}")
logger.error(f"[PlaylistPush] Error pushing playlist to server: {e}")
import traceback
traceback.print_exc()
try:
database.update_sync_history_push_status(batch_id, 'failed')
except Exception:
pass
# ===============================