soulsync/core/metadata
BoulderBadgeDad 50c17ec9f7 discography 'add to wishlist': batch the per-track ownership check (fixes ~15-30s/track)
clicking Download Discography → Add all to wishlist added ~1 track every 15-30s. trace: the
endpoint's per-track library-ownership check (track_already_owned → check_track_exists) ran the
LEGACY path — firing search_tracks for every title-variation × artist-variation, per track. on
a large library and an artist you own NOTHING of, STRATEGY-1 (indexed LIKE) always missed and
fell through to the fuzzy fallback (full-table scan), ~10-15 scans/track = the 15-30s. metadata
fetch was never the bottleneck (deezer returns each album in ~1s).

fix: pre-fetch the artist's owned tracks ONCE (get_candidate_albums_for_artist →
get_candidate_tracks_for_albums) and pass candidate_tracks to check_track_exists's batched
in-memory path — the same path the discography backfill job + completion-stream already use.
pass an EMPTY list (not None) when nothing is owned so the owns-nothing case still takes the
fast path → instant. per-track cost drops from ~20s to ~1ms.

safe: track_already_owned's only real caller is this endpoint; the new param is optional
(None = unchanged legacy behaviour for any other caller). normal ownership still detected (same
artist-variation breadth); the one divergence is a track owned ONLY via a compilation → a
harmless redundant wishlist add, which is the endpoint's explicitly-accepted failure mode and
already how the backfill job behaves. 4 new tests; 1134 discog/metadata/wishlist tests green.
2026-06-27 19:51:28 -07:00
..
__init__.py
album_mbid_cache.py
album_tracks.py
art_apply.py Cover Art Filler: write cover.jpg to the RESOLVED folder, not the raw DB path (Sokhi — the actual bug) 2026-06-08 18:25:50 -07:00
art_lookup.py Cover art: a numeric difference is a different release — Vol.4 stops wearing Vol.4.5's cover 2026-06-07 10:21:23 -07:00
art_preservation.py
art_sources.py
artist_album_cache.py Cache artist album lists across metadata sources 2026-06-11 22:33:04 +02:00
artist_image.py
artist_resolution.py
artwork.py Special-edition cover art: prefer the pinned release own cover over the release-group representative 2026-06-21 22:47:09 -07:00
caa_art.py Special-edition cover art: prefer the pinned release own cover over the release-group representative 2026-06-21 22:47:09 -07:00
cache.py Artist pages: stop watchlist probes from poisoning the album-list cache 2026-06-07 09:49:30 -07:00
canonical_resolver.py #767-2: reorganize finds the right album edition instead of mislabeling singles as deluxe 2026-06-06 10:53:13 -07:00
canonical_version.py canonical: recognize musicbrainz as a readable album source (PR #929 follow-up) 2026-06-26 19:04:24 -07:00
common.py Import: atomic tag saves so an interrupted/OOM save can't destroy the file (#819) 2026-06-08 13:46:28 -07:00
completion.py
discography.py
discography_filters.py discography 'add to wishlist': batch the per-track ownership check (fixes ~15-30s/track) 2026-06-27 19:51:28 -07:00
enrichment.py Multi-disc albums: never write a disc-less track (floor disc to >=1) 2026-06-22 09:30:04 -07:00
lookup.py
lyrics.py
multi_source_search.py
registry.py #922: import search labelled Spotify Free users' primary source as 'Deezer' 2026-06-24 08:43:52 -07:00
release_dates.py #705: release-date gate — unreleased tracks stay out of the wishlist cycle and Fresh Tape 2026-06-07 00:29:05 -07:00
release_type.py
relevance.py
service.py
similar_artists.py
source.py Multi-disc: file the track in the disc folder that matches its tag (Sokhi) 2026-06-22 10:56:53 -07:00
status.py
track_number_format.py
types.py