/** * Utility to add a Deezer track to the download queue * Used by both search results and services/deezer pages */ import { deezerAPI } from '$lib/services/deezer'; import { addToQueue } from '$lib/stores/downloadQueue'; import { settings } from '$lib/stores/settings'; import { deezerAuth } from '$lib/stores/deezer'; import { trackExists } from './downloader'; import { setInfo, setWarning } from '$lib/stores/status'; import { get } from 'svelte/store'; /** * Fetch track metadata and add to download queue * Respects the overwrite setting - skips tracks that already exist if overwrite is false * @param trackId - Deezer track ID * @returns Promise that resolves when track is added to queue (or skipped message) */ export async function addDeezerTrackToQueue(trackId: string): Promise<{ added: boolean; reason?: string }> { // Ensure ARL is set for authentication const authState = get(deezerAuth); if (authState.arl) { deezerAPI.setArl(authState.arl); } // Fetch full track data from GW API const trackInfo = await deezerAPI.getTrack(trackId); if (!trackInfo || !trackInfo.SNG_ID) { throw new Error('Track not found or invalid track ID'); } // Fetch album data for cover art URLs let albumData = null; try { albumData = await deezerAPI.getAlbumData(trackInfo.ALB_ID.toString()); } catch (error) { console.warn('[AddToQueue] Could not fetch album data:', error); } // Fetch lyrics let lyricsData = null; try { lyricsData = await deezerAPI.getLyrics(trackInfo.SNG_ID.toString()); } catch (error) { console.warn('[AddToQueue] Could not fetch lyrics:', error); } // Parse lyrics if available let lyrics = undefined; if (lyricsData) { // Parse LRC format (synced lyrics) let syncLrc = ''; if (lyricsData.LYRICS_SYNC_JSON) { for (const line of lyricsData.LYRICS_SYNC_JSON) { const text = line.line || ''; const timestamp = line.lrc_timestamp || '[00:00.00]'; syncLrc += `${timestamp}${text}\n`; } } lyrics = { sync: syncLrc || undefined, unsync: lyricsData.LYRICS_TEXT || undefined, syncID3: undefined // No longer needed, handled by Rust tagger }; } // Build track object with enhanced metadata const track = { id: trackInfo.SNG_ID, title: trackInfo.SNG_TITLE, artist: trackInfo.ART_NAME, artistId: trackInfo.ART_ID, artists: [trackInfo.ART_NAME], album: trackInfo.ALB_TITLE, albumId: trackInfo.ALB_ID, albumArtist: trackInfo.ART_NAME, albumArtistId: trackInfo.ART_ID, trackNumber: typeof trackInfo.TRACK_NUMBER === 'number' ? trackInfo.TRACK_NUMBER : parseInt(trackInfo.TRACK_NUMBER, 10), discNumber: typeof trackInfo.DISK_NUMBER === 'number' ? trackInfo.DISK_NUMBER : parseInt(trackInfo.DISK_NUMBER, 10), duration: typeof trackInfo.DURATION === 'number' ? trackInfo.DURATION : parseInt(trackInfo.DURATION, 10), explicit: trackInfo.EXPLICIT_LYRICS === 1, md5Origin: trackInfo.MD5_ORIGIN, mediaVersion: trackInfo.MEDIA_VERSION, trackToken: trackInfo.TRACK_TOKEN, // Enhanced metadata lyrics, albumCoverUrl: albumData?.ALB_PICTURE ? `https://e-cdns-images.dzcdn.net/images/cover/${albumData.ALB_PICTURE}/500x500-000000-80-0-0.jpg` : undefined, albumCoverXlUrl: albumData?.ALB_PICTURE ? `https://e-cdns-images.dzcdn.net/images/cover/${albumData.ALB_PICTURE}/1000x1000-000000-80-0-0.jpg` : undefined, label: albumData?.LABEL_NAME, barcode: albumData?.UPC, releaseDate: trackInfo.PHYSICAL_RELEASE_DATE, genre: trackInfo.GENRE ? [trackInfo.GENRE] : undefined, copyright: trackInfo.COPYRIGHT }; // Check if we should skip this track (if it exists and overwrite is false) const appSettings = get(settings); if (!appSettings.deezerOverwrite && appSettings.musicFolder) { const exists = await trackExists(track, appSettings.musicFolder, appSettings.deezerFormat); if (exists) { console.log(`[AddToQueue] Skipping "${track.title}" - already exists`); setWarning(`Skipped: ${track.title} (already exists)`); return { added: false, reason: 'already_exists' }; } } // Add to queue (queue manager runs continuously in background) await addToQueue({ source: 'deezer', type: 'track', title: track.title, artist: track.artist, totalTracks: 1, downloadObject: track }); setInfo(`Queued: ${track.title}`); return { added: true }; }