Track server push status, expand push to all playlist types, rename to _push_playlist_to_server
This commit is contained in:
parent
5415d0fe3c
commit
ed013d79b9
2 changed files with 74 additions and 23 deletions
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
# ===============================
|
||||
|
|
|
|||
Loading…
Reference in a new issue