soulsync/PLAN-download-quality-flags.md
JohnBaumb 62797c68af discover: replace Force DL toggle with Any Quality placeholder (Phase 0)
Replace the misleading Force DL toggle on the Sync page Discover tab with
a disabled Any Quality toggle. Stop sending force_download_all from
discover sync so discover playlists run ownership analysis instead of
blindly re-downloading owned tracks.

Adds PLAN-download-quality-flags.md describing the full refactor plan.
2026-04-23 13:37:59 -07:00

5.3 KiB

Plan: Download Quality Flags Refactor

Background

The current force_download_all flag is misleadingly named. It does NOT lower quality requirements or "force download any quality". It only skips the library ownership check so every track is treated as missing and re-downloaded regardless of whether the user already owns it.

This causes two distinct problems:

  1. The name implies quality-related behavior that doesn't exist.
  2. The discover sync tab currently sends force_download_all: true, which means every discover playlist sync re-downloads tracks the user already owns.

Additionally, users have expressed a real need for a per-batch quality override: their main library should stay strict (FLAC preferred, high bitrate) while rotating/ephemeral playlists (discover) should grab whatever is available for quantity over quality.

Per-client fallback settings already exist (Soulseek quality profile fallback_enabled, Deezer/Tidal/Qobuz allow_fallback chains) but they are global all-or-nothing flags. There is no way today to say "relax quality just for this one batch".

Goals

  1. Rename force_download_all to reflect what it actually does (skip ownership check / re-download owned).
  2. Stop discover sync from blindly re-downloading owned tracks.
  3. Add a new per-batch "Any Quality" flag that bypasses quality filtering for that specific batch only, without touching the user's global quality settings.

Non-Goals

  • No changes to the global per-client quality/fallback settings.
  • No changes to the matching engine scoring.
  • No changes to album consistency / MusicBrainz preflight logic.

Phase 0 (this PR): UI framework only

Scope is tiny and safe to ship immediately.

  • Replace the "Force DL" toggle in the Sync page Discover tab with an "Any Quality" toggle.
  • Leave the new toggle permanently disabled / greyed out for now.
  • Tooltip on the toggle reads something like "Coming soon: download any available quality for this batch".
  • Remove the force_download_all: true body payload from the discover sync path. Discover playlists will now always run ownership analysis.
  • No backend changes in this phase.

Files touched:

  • webui/static/discover.js - replace toggle HTML, remove forceDownload plumbing from syncDiscoverPlaylistFromTab / _doSyncDiscoverPlaylist.

Phase 1: Rename force_download_all

Rename to skip_ownership_check (backend) and surface in the UI as "Re-download Owned" (or equivalent).

  • Backend: add new key skip_ownership_check everywhere the flag is used. Accept both keys on inbound API payloads for one release (back-compat).
  • Frontend: rename the Wishlist / Downloads modal toggles, keep the same default behavior (wishlists still skip the library check by default).
  • Update helper.js tooltip description to match the new name and behavior.

Files touched:

  • web_server.py (lines ~15663, 24858, 25858, 26065, 29051, 29057, 29062, 29104, 29135, 33556, 33596)
  • webui/static/downloads.js (lines ~195, 598, 2152, 2155, 2195, 2436)
  • webui/static/wishlist-tools.js (line ~6347)
  • webui/static/helper.js (lines ~663)

Phase 2: Implement "Any Quality" per-batch override

Introduce a new batch flag any_quality that, when set, bypasses quality filtering for that batch only.

Backend behavior:

  • Add any_quality to the batch dict alongside skip_ownership_check.
  • For Soulseek: when any_quality is true, skip the call to soulseek_client.filter_results_by_quality_preference() and pass ranked candidates through unchanged.
  • For Deezer / Tidal / Qobuz: when any_quality is true, temporarily force the candidate selection path to treat allow_fallback=True AND start from the lowest quality tier so downloads succeed fastest.
  • The flag is per-batch only. Global quality profile / allow_fallback settings remain untouched.

Frontend behavior:

  • Enable the "Any Quality" toggle added in Phase 0.
  • Remove the "Coming soon" tooltip, replace with a real description.
  • Wire the toggle into the discover sync POST body as any_quality: true.
  • Consider exposing the same toggle on the Wishlist / Downloads modal.

Files touched:

  • web_server.py - batch creation + candidate selection path
  • core/soulseek_client.py - accept override in filter call
  • core/deezer_download_client.py, core/tidal_download_client.py, core/qobuz_client.py - accept per-request quality override
  • webui/static/discover.js - enable toggle, send flag
  • webui/static/downloads.js - add matching toggle on manual download modals

Risks / Open Questions

  • Soulseek quality profile bypass: is it safe to pass all density-filtered candidates through without the priority filter? Likely yes, since the matching engine already ranks by confidence and peer quality.
  • Streaming clients with strict API quality params (Tidal HiRes vs Lossless entitlement, Qobuz subscription tiers): forcing lowest tier should be safe for all users regardless of subscription.
  • Back-compat on the renamed flag: keep the old force_download_all key accepted for at least one release cycle to avoid breaking any third-party callers or stale browser sessions.

Rollout

  • Phase 0 ships with this PR (UI framework + discover fix).
  • Phase 1 and Phase 2 can ship as separate PRs on dev.
  • No migrations required; all flags are request-scoped and batch-scoped.