# Download Filename Format Fix ## Problem Songs downloaded from artist detail page and remote search results sometimes download the wrong file because: - Multiple songs with the same title but different artists exist - yt-dlp might pick a different version when searching by title only - File organization is poor without artist information in filename ## Solution Changed download filename format from: ``` Song Title.mp3 ``` To: ``` Artist Name - Song Title.mp3 ``` ## Changes Made ### Backend #### 1. `backend/app/api/download.py` - Updated `process_download()` to accept `artist` parameter - Format filename as `"{artist} - {title}"` when artist is provided - Pass artist from request to background task **Before:** ```python success, file_path, error = await music_downloader.download_music(url, title) ``` **After:** ```python output_filename = f"{artist} - {title}" if artist else title success, file_path, error = await music_downloader.download_music(url, output_filename) ``` #### 2. `backend/app/api/auto_download.py` - Updated auto-download to format filename with artist - Uses artist from `selected_result` **Before:** ```python success, file_path, error = await music_downloader.download_music( selected_result.url, selected_result.title ) ``` **After:** ```python output_filename = f"{selected_result.artist} - {selected_result.title}" if selected_result.artist else selected_result.title success, file_path, error = await music_downloader.download_music( selected_result.url, output_filename ) ``` #### 3. `backend/app/services/downloader.py` - Added `sanitize_filename()` function to handle special characters - Prevents filesystem errors from characters like `/`, `\`, `:`, `*`, etc. - Limits filename length to 200 characters **New function:** ```python def sanitize_filename(filename: str) -> str: """Sanitize filename by removing/replacing problematic characters""" replacements = { '/': '-', '\\': '-', ':': '-', '*': '', '?': '', '"': "'", '<': '', '>': '', '|': '-', } # ... sanitization logic ``` ### Frontend #### 4. `frontend/src/components/search/SearchPage.tsx` - Fixed mutation to actually pass `artist` and `thumbnail` to API - Was accepting parameters but not sending them **Before:** ```typescript mutationFn: ({ url, title }: { url: string; title: string; thumbnail?: string; artist?: string }) => downloadApi.downloadMusic({ url, title }), ``` **After:** ```typescript mutationFn: ({ url, title, thumbnail, artist }: { url: string; title: string; thumbnail?: string; artist?: string }) => downloadApi.downloadMusic({ url, title, thumbnail, artist }), ``` ## Examples ### Example 1: Search Page Download **User searches for:** "Shape of You" **Before:** - Filename: `Shape of You.mp3` - Could download any "Shape of You" (Ed Sheeran, cover, remix, etc.) **After:** - Filename: `Ed Sheeran - Shape of You.mp3` - Downloads the correct version with artist specified ### Example 2: Artist Detail Page **User is on "Taylor Swift" artist page, downloads "Love Story"** **Before:** - Filename: `Love Story.mp3` - Might download a different artist's "Love Story" **After:** - Filename: `Taylor Swift - Love Story.mp3` - Guaranteed to download the correct artist's version ### Example 3: Special Characters **Song:** `AC/DC - Back In Black: Remastered` **After sanitization:** - Filename: `AC-DC - Back In Black- Remastered.mp3` - Safe for all filesystems ## Testing ### Test Basic Download ```bash # Via API curl -X POST "http://localhost:8000/api/download/music" \ -H "Content-Type: application/json" \ -d '{ "url": "https://youtube.com/watch?v=xxx", "title": "Shape of You", "artist": "Ed Sheeran" }' # Check the downloaded file ls -la data/music/ # Should see: "Ed Sheeran - Shape of You.mp3" ``` ### Test Auto Download ```bash # From artist page, download "Love Story" from Taylor Swift # Should create: "Taylor Swift - Love Story.mp3" ``` ### Test Special Characters ```bash # Download song with special characters in name curl -X POST "http://localhost:8000/api/download/music" \ -H "Content-Type: application/json" \ -d '{ "url": "https://youtube.com/watch?v=xxx", "title": "Don'\''t Stop Me Now", "artist": "Queen" }' # Should create: "Queen - Don't Stop Me Now.mp3" ``` ## Migration No database migration needed. Existing files are not affected. New downloads will follow the new format: - ✅ Downloads from search page: `Artist - Title.mp3` - ✅ Downloads from artist detail page: `Artist - Title.mp3` - ✅ Auto-downloads: `Artist - Title.mp3` ## Benefits 1. **Prevents wrong downloads** - Artist name ensures correct version 2. **Better organization** - Easy to identify songs by filename 3. **Consistent naming** - All downloads follow same format 4. **Filesystem safe** - Special characters are sanitized 5. **Backward compatible** - Old files still work ## Files Changed - `backend/app/api/download.py` - Pass artist to formatter - `backend/app/api/auto_download.py` - Format auto-download filenames - `backend/app/services/downloader.py` - Add sanitization function - `frontend/src/components/search/SearchPage.tsx` - Fix mutation to pass artist ## Related Issues This fix addresses: - Wrong songs being downloaded when title is ambiguous - Poor file organization without artist info - Filesystem errors from special characters in filenames - Inconsistent naming across different download sources