Commit graph

2 commits

Author SHA1 Message Date
BoulderBadgeDad
217a5eda70 #798: Spotify Free as a real dropdown source + automatic rate-limit bridge
Consistency fix: Spotify Free is now its own entry in the metadata-source
dropdown (alongside Spotify / iTunes / Deezer / MusicBrainz) instead of a
side-toggle. Stored as fallback_source='spotify' + spotify_free=true so all
downstream 'spotify' routing and the spotify_* columns are unchanged.

Refined gate model (no toggle):
- Connected user (has credentials) -> official; bridges to free AUTOMATICALLY
  during a rate-limit ban (no opt-in needed).
- No-auth user -> must pick 'Spotify Free' in the dropdown; then free serves.
- Never opted into Spotify (no creds, didn't pick it) -> free never runs, so no
  surprise scraping. _free_wanted() = has_credentials OR picked-spotify-free is
  the guard.
- AUTHED + healthy -> official always; free never opens.

UI: dropdown gains 'Spotify Free (no credentials)' (selectable when the package
is installed — surfaced via status.free_installed, since selecting it is the
opt-in and can't depend on having selected it); load/save map the dropdown value
to the (fallback_source, spotify_free) pair; old checkbox removed.

Gate model pinned by 6 scenario tests (connected/healthy, connected/ratelimited
bridge, no-auth picked, no-auth not-opted-in, package-missing). 117 tests green.
2026-06-05 14:23:28 -07:00
BoulderBadgeDad
0eff9e3708 #798: Spotify Free metadata mode — backend (opt-in, shared spotify tables)
Adds an opt-in no-creds Spotify metadata path: SpotifyClient serves SpotipyFree
data (real Spotify IDs) when metadata.spotify_free is enabled AND SpotipyFree is
installed AND there's no real Spotify auth. The data lands in the SAME spotify_*
columns, so the enrichment worker, search, and #775 lookups work UNCHANGED —
they just receive free-sourced data. The worker's only change is its availability
gate.

- core/spotify_free_metadata.py: SpotifyFreeMetadataClient + normalize_artist +
  pure gate fns (should_use_free_fallback / should_offer_spotify_metadata /
  spotify_free_installed).
- SpotifyClient: _free_enabled (opt-in, default OFF) / _free_available /
  is_spotify_metadata_available / _free_active + in-client routing for
  search_artists/tracks + get_album/artist/track_details/album_tracks/artist_albums.
- 3 scoped availability gates use is_spotify_metadata_available(): enrichment
  worker loop, search resolve_client, watchlist. The ~40 discovery/user-library
  sites stay auth-only (no sprawl, no user-data risk).

Authed users are untouched (gate closed when auth healthy). UI surfacing comes
next. Pure gates + normalizer tested; orchestrator resolve test added.
2026-06-05 13:32:37 -07:00