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.
123 lines
5.3 KiB
Markdown
123 lines
5.3 KiB
Markdown
# 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.
|