You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(spotify): require user API app for search (client-credentials)
Spotify rejects Web API calls made with librespot-session tokens (429 on
every endpoint; Mercury keymaster and searchview are retired), so search
now uses SPOTIFY_CLIENT_ID/SPOTIFY_CLIENT_SECRET from the user's own free
API app via the client-credentials flow, cached in-process. The search
overlay shows setup instructions when the variables are missing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
//! Spotify catalog search via the public Web API.
2
2
//!
3
3
//! Playback and metadata go through librespot's own protocols, but librespot
4
-
//! exposes no search. The Web API's `/v1/search` does, and the librespot
5
-
//! session can mint a bearer token for it — so search needs no second login
6
-
//! and no developer app.
4
+
//! exposes no search, and Spotify rejects Web API calls made with tokens from
5
+
//! librespot's shared client id (every endpoint answers 429; the Mercury
6
+
//! keymaster and searchview routes are retired outright). Search therefore
7
+
//! needs the user's own — free — Spotify API app: `SPOTIFY_CLIENT_ID` and
8
+
//! `SPOTIFY_CLIENT_SECRET` feed a client-credentials token (no browser flow,
9
+
//! no user context), cached in-process for its ~1h lifetime.
10
+
11
+
use std::sync::Mutex;
12
+
use std::time::{Duration,Instant};
7
13
8
14
use color_eyre::eyre::{eyre,Result,WrapErr};
9
15
use serde::Deserialize;
10
-
use stream_download::http::reqwest::ClientasHttpClient;
11
16
12
17
/// Display limits per section (spec: 8 tracks, 5 albums, 5 playlists).
13
18
constTRACK_LIMIT:usize = 8;
@@ -32,34 +37,98 @@ pub struct SearchItem {
32
37
puburi:String,
33
38
}
34
39
35
-
/// Search Spotify's catalog. Blocking: runs one Web API request on the shared
36
-
/// Spotify runtime (~300ms). Requires a prior `looper spotify login`.
40
+
/// Shown in the search overlay when the API app env vars are missing.
41
+
constSETUP_HELP:&str = "Spotify search needs your own (free) Spotify API app:\n 1. create an app at developer.spotify.com/dashboard\n 2. export SPOTIFY_CLIENT_ID=... and SPOTIFY_CLIENT_SECRET=...\n 3. restart looper\nPlayback is unaffected — see the README's \"Spotify search\" section.";
42
+
43
+
/// Search Spotify's catalog. Blocking (~300ms), called from the TUI thread
44
+
/// after a "searching…" frame has been drawn. Requires `SPOTIFY_CLIENT_ID` /
45
+
/// `SPOTIFY_CLIENT_SECRET`; does NOT require the librespot Premium login.
0 commit comments