From ef69eb698b9c36f239473cae0bff484cfc575555 Mon Sep 17 00:00:00 2001 From: Broque Thomas Date: Sat, 27 Sep 2025 00:10:58 -0700 Subject: [PATCH] beatport progress --- web_server.py | 67 ++---------------------------------------- webui/static/script.js | 54 ++++++++++++++++++++++------------ 2 files changed, 38 insertions(+), 83 deletions(-) diff --git a/web_server.py b/web_server.py index 244d7ce9..7d6292e7 100644 --- a/web_server.py +++ b/web_server.py @@ -12557,71 +12557,8 @@ def convert_beatport_results_to_spotify_tracks(discovery_results): return spotify_tracks -@app.route('/api/beatport/download/missing/', methods=['POST']) -def start_beatport_download_missing(url_hash): - """Start download missing tracks for a Beatport chart""" - try: - if url_hash not in beatport_chart_states: - return jsonify({"error": "Beatport chart not found"}), 404 - - state = beatport_chart_states[url_hash] - state['last_accessed'] = time.time() # Update access time - - if state['phase'] not in ['discovered', 'sync_complete', 'downloading', 'download_complete']: - return jsonify({"error": "Beatport chart not ready for download"}), 400 - - # Get the converted Spotify playlist ID or create one from discovery results - converted_playlist_id = state.get('converted_spotify_playlist_id') - - if not converted_playlist_id: - # If no converted playlist, create a virtual one from discovery results - spotify_tracks = convert_beatport_results_to_spotify_tracks(state['discovery_results']) - if not spotify_tracks: - return jsonify({"error": "No Spotify matches found for download"}), 400 - - # Create a virtual playlist ID for download tracking - converted_playlist_id = f"beatport_{url_hash}" - state['converted_spotify_playlist_id'] = converted_playlist_id - - # Use the existing download missing functionality - chart_name = state.get('chart', {}).get('name', 'Unknown Chart') - - # Create download batch using existing infrastructure - download_data = { - 'playlist_id': converted_playlist_id, - 'playlist_name': f"Beatport: {chart_name}", - 'source': 'beatport', - 'source_id': url_hash - } - - # Start download using existing download system - batch_id = f"beatport_download_{url_hash}_{int(time.time())}" - - # Add to download batches - download_batches[batch_id] = { - 'id': batch_id, - 'playlist_id': converted_playlist_id, - 'status': 'starting', - 'progress': 0, - 'created_at': time.time(), - 'source': 'beatport', - 'source_id': url_hash - } - - # Update Beatport state - state['phase'] = 'downloading' - state['download_process_id'] = batch_id - - # Start download in background (this will use the existing download infrastructure) - future = download_executor.submit(process_playlist_download, converted_playlist_id, batch_id) - download_batches[batch_id]['future'] = future - - print(f"🎧 Started Beatport download for chart: {chart_name}") - return jsonify({"success": True, "batch_id": batch_id}) - - except Exception as e: - print(f"❌ Error starting Beatport download: {e}") - return jsonify({"error": str(e)}), 500 +# Beatport download missing tracks is handled frontend-only (like YouTube) +# No backend endpoint needed - uses existing download modal infrastructure class WebMetadataUpdateWorker: """Web-based metadata update worker - EXACT port of dashboard.py MetadataUpdateWorker""" diff --git a/webui/static/script.js b/webui/static/script.js index b1f5e482..ebfda4eb 100644 --- a/webui/static/script.js +++ b/webui/static/script.js @@ -3248,6 +3248,7 @@ async function openDownloadMissingModalForYouTube(virtualPlaylistId, playlistNam } process.modalElement.style.display = 'flex'; } + hideLoadingOverlay(); // Hide overlay when reopening existing modal return; } @@ -10395,35 +10396,52 @@ async function startBeatportDownloadMissing(urlHash) { console.log('🔍 Starting download missing tracks for Beatport playlist:', urlHash); const state = youtubePlaylistStates[urlHash]; - if (!state || !state.is_beatport_playlist) { - console.error('❌ Invalid Beatport playlist state for download'); - showToast('Invalid Beatport playlist state', 'error'); + if (!state || !state.discovery_results) { + showToast('No discovery results available for download', 'error'); return; } - // Call Beatport download endpoint - const response = await fetch(`/api/beatport/download/missing/${urlHash}`, { - method: 'POST' - }); + // Convert Beatport results to a format compatible with the download modal (same as YouTube) + const spotifyTracks = state.discovery_results + .filter(result => result.spotify_data) + .map(result => { + const track = result.spotify_data; + // Ensure artists is an array of strings (like YouTube format) + if (track.artists && Array.isArray(track.artists)) { + track.artists = track.artists.map(artist => + typeof artist === 'string' ? artist : (artist.name || artist) + ); + } + return track; + }); - const result = await response.json(); - - if (result.error) { - showToast(`Error starting download: ${result.error}`, 'error'); + if (spotifyTracks.length === 0) { + showToast('No Spotify matches found for download', 'error'); return; } - // Update state to downloading - state.phase = 'downloading'; - updateBeatportCardPhase(state.beatport_chart_hash || urlHash, 'downloading'); + // Create a virtual playlist for the download system (same as YouTube) + const virtualPlaylistId = `beatport_${urlHash}`; + const playlistName = `[Beatport] ${state.playlist.name}`; - showToast('Starting Beatport track downloads...', 'success'); + // Store reference for card navigation (same as YouTube) + state.convertedSpotifyPlaylistId = virtualPlaylistId; - // The download progress will be handled by the existing download monitoring system + // Close the discovery modal if it's open (same as YouTube) + const discoveryModal = document.getElementById(`youtube-discovery-modal-${urlHash}`); + if (discoveryModal) { + discoveryModal.classList.add('hidden'); + console.log('🔄 Closed Beatport discovery modal to show download modal'); + } + + // Open download missing tracks modal for Beatport playlist (same as YouTube) + await openDownloadMissingModalForYouTube(virtualPlaylistId, playlistName, spotifyTracks); + + // Phase will change to 'downloading' when user clicks "Begin Analysis" button } catch (error) { - console.error('❌ Error starting Beatport download:', error); - showToast(`Error starting download: ${error.message}`, 'error'); + console.error('❌ Error starting download missing tracks:', error); + showToast(`Error starting downloads: ${error.message}`, 'error'); } }