diff --git a/web_server.py b/web_server.py index 7414f177..f0e47edb 100644 --- a/web_server.py +++ b/web_server.py @@ -4079,6 +4079,44 @@ def cancel_batch(batch_id): print(f"❌ Error cancelling batch {batch_id}: {e}") return jsonify({"success": False, "error": str(e)}), 500 +# NEW ENDPOINT: Add this function to web_server.py +@app.route('/api/playlists/cleanup_batch', methods=['POST']) +def cleanup_batch(): + """ + Cleans up a completed or cancelled batch from the server's in-memory state. + This is called by the client after the user closes a finished modal. + """ + data = request.get_json() + batch_id = data.get('batch_id') + if not batch_id: + return jsonify({"success": False, "error": "Missing batch_id"}), 400 + + try: + with tasks_lock: + # Check if the batch exists before trying to delete + if batch_id in download_batches: + # Get the list of task IDs before deleting the batch + task_ids_to_remove = download_batches[batch_id].get('queue', []) + + # Delete the batch record + del download_batches[batch_id] + + # Clean up the associated tasks from the tasks dictionary + for task_id in task_ids_to_remove: + if task_id in download_tasks: + del download_tasks[task_id] + + print(f"✅ Cleaned up batch '{batch_id}' and its associated tasks from server state.") + return jsonify({"success": True, "message": f"Batch {batch_id} cleaned up."}) + else: + # It's not an error if the batch is already gone + print(f"⚠️ Cleanup requested for non-existent batch '{batch_id}'. Already cleaned up?") + return jsonify({"success": True, "message": "Batch already cleaned up."}) + + except Exception as e: + print(f"❌ Error during batch cleanup for '{batch_id}': {e}") + return jsonify({"success": False, "error": str(e)}), 500 + # =============================== # == UNIFIED MISSING TRACKS API == # =============================== diff --git a/webui/static/script.js b/webui/static/script.js index 37726bd2..0284e59a 100644 --- a/webui/static/script.js +++ b/webui/static/script.js @@ -1536,13 +1536,29 @@ function updatePlaylistCardUI(playlistId) { } } -function cleanupDownloadProcess(playlistId) { - if (!activeDownloadProcesses[playlistId]) return; +async function cleanupDownloadProcess(playlistId) { + const process = activeDownloadProcesses[playlistId]; + if (!process) return; console.log(`Cleaning up download process for playlist ${playlistId}`); - const process = activeDownloadProcesses[playlistId]; - // Stop polling + // --- THIS IS THE FIX --- + // If the process has a batchId, tell the server to clean it up. + if (process.batchId) { + try { + console.log(`🚀 Sending cleanup request to server for batch: ${process.batchId}`); + await fetch('/api/playlists/cleanup_batch', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ batch_id: process.batchId }) + }); + } catch (error) { + console.error('Failed to send cleanup request to server:', error); + } + } + // --- END OF FIX --- + + // Stop client-side polling if (process.poller) { clearInterval(process.poller); } @@ -1552,7 +1568,7 @@ function cleanupDownloadProcess(playlistId) { process.modalElement.parentElement.removeChild(process.modalElement); } - // Remove from global state + // Remove from client-side global state delete activeDownloadProcesses[playlistId]; // Restore card UI