feat: Qobuz auth-token (user_id + token) login as a reliable alternative to email/password

Qobuz's email/password API login returns 401 even with valid credentials
(a known Qobuz limitation, unaffected by streamrip version). Add settings
fields for a Qobuz user ID + auth token (token stored encrypted); when both
are present StreamripClient uses use_auth_token=True, else falls back to
email/password.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jonathan
2026-07-11 00:46:17 +02:00
parent caa0d542ea
commit 00b3dddca6
5 changed files with 73 additions and 11 deletions
+15 -5
View File
@@ -19,18 +19,28 @@ class StreamripClient:
def __init__(self, config: dict):
self._email = config.get("qobuz.email", "")
self._password = config.get("qobuz.password", "")
self._user_id = config.get("qobuz.user_id", "")
self._token = config.get("qobuz.auth_token", "")
def is_configured(self) -> bool:
return bool(self._email and self._password)
# either a user_id + auth token, or an email + password
return bool((self._user_id and self._token) or (self._email and self._password))
def _make_config(self, download_folder: str | None = None):
from streamrip.config import Config
cfg = Config.defaults()
cfg.session.qobuz.use_auth_token = False
cfg.session.qobuz.email_or_userid = self._email
cfg.session.qobuz.password_or_token = _hashed_password(self._password)
cfg.session.qobuz.quality = 3
q = cfg.session.qobuz
if self._user_id and self._token:
# token auth: more reliable than email/password, which Qobuz often rejects
q.use_auth_token = True
q.email_or_userid = self._user_id
q.password_or_token = self._token
else:
q.use_auth_token = False
q.email_or_userid = self._email
q.password_or_token = _hashed_password(self._password)
q.quality = 3
if download_folder is not None:
cfg.session.downloads.folder = download_folder
return cfg