Files
you-music/DOWNLOAD_FILENAME_FIX.md
2025-11-07 13:23:33 +11:00

5.4 KiB

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:

success, file_path, error = await music_downloader.download_music(url, title)

After:

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:

success, file_path, error = await music_downloader.download_music(
    selected_result.url,
    selected_result.title
)

After:

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:

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:

mutationFn: ({ url, title }: { url: string; title: string; thumbnail?: string; artist?: string }) => 
  downloadApi.downloadMusic({ url, title }),

After:

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

# 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

# From artist page, download "Love Story" from Taylor Swift
# Should create: "Taylor Swift - Love Story.mp3"

Test Special Characters

# 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

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