Commit Graph
7 Commits
Author SHA1 Message Date
vicrodh 857cb16e87 fix(mb): retry MusicBrainz 503s and transport failures behind a shared limiter
- Route every endpoint through a new send_with_retry: it waits on the rate
  limiter, GETs, logs the x-ratelimit budget, and on a 503/429 backs off the
  server's Retry-After (capped 8s) and retries, up to 3 attempts. get_artist_tags
  and get_recording_isrcs, which skipped status handling entirely, now go
  through it too.
- Also retry transient TRANSPORT failures (a hung connection to the request
  timeout, a drop or refusal). MusicBrainz under load hangs instead of returning
  503, which surfaced as "error sending request for url". Capped at 2 attempts
  with a 6s request timeout so a total failure is ~13s, not ~33s, while a hang
  that clears still recovers on the second try.
- Share ONE process-wide direct rate limiter across every client (core, the tag
  editor, remote metadata) so several clients on one public IP pace as one 1.1s
  stream instead of each pacing itself.
- Log MusicBrainz's x-ratelimit-limit/remaining/reset headers (debug on 2xx,
  warn on 429/503) as the only signal of whether the bucket was ours or MB's.

Tests: 503-then-200, a dropped connection, and shared-limiter serialization,
each red-to-green. Dev-only deps (tokio test features + rustls/aws-lc-rs to
install the crypto provider); no runtime dependency added.

cc
2026-09-10 13:23:53 -06:00
vicrodh 8964544891 chore(deps): reqwest 0.13 (rustls-no-provider; query/form are opt-in features now)
cc
2026-08-29 09:00:56 -06:00
vicrodh 6d8c951a38 chore(deps): rusqlite 0.40 (u64 casts; a latent two-statement execute fixed)
rusqlite 0.40 removed ToSql/FromSql for u64 (SQLite integers are i64):
every u64 column now reads/writes through an explicit i64 cast. It also
rejects a multi-statement execute() instead of silently running only the
first statement — which is what catalog.rs's editions/logical_albums
prune had been doing all along; it is an execute_batch now, so the
logical_albums prune finally runs.

cc
2026-08-29 08:36:21 -06:00
François Laignel 62cc4f9200 remove ring from the dependency tree
The crate `ring` was transitively pulled due to the feature `rustls-tls` being
selected for `reqwest`. In order to ensure `ring` is not pulled,
`rustls-tls-webpki-roots-no-provider` must be used instead.
2026-07-26 21:12:44 +02:00
vicrodh ef38e7a04e feat(slint): port Discord Rich Presence (opt-in) from Tauri
Frontend-agnostic core in qbz-integrations::discord (DiscordRpc +
NowListening) — the Tauri backend minus the tauri::command/State
wrappers: lazy IPC connect, Listening activity (details/state/assets +
"Get QBZ" button + timestamps), and the opt-in Flatpak socket bridge.
qbz-slint discord_rpc controller: process-global client, init AFTER the
session is active (PR #477 persistence fix — both online and offline
entry, never at early boot), push on the track-change and play/pause
edges, clear on logout. Opt-in toggle in Settings > Integrations
(DiscordState, persisted in ui_prefs.discord_rpc_enabled) + a Flatpak
socket-access note. The opt-in is per-machine (ui_prefs) rather than
Tauri's per-user.

cc
2026-06-22 22:56:05 -06:00
vicrodh c3ce3c6667 fix(ci): drop openssl dependency, use rustls-only for all crates
reqwest default features included native-tls which pulled in
openssl-sys. This broke zigbuild cross-compilation because zig's
C compiler doesn't support the glibc version suffix for openssl
header expansion.

Fix: default-features = false on reqwest in workspace and
qbz-integrations (which had its own reqwest dep with defaults).
Now the entire daemon tree uses rustls-tls exclusively.

cc
2026-04-09 06:48:37 -06:00
vicrodh bd30e7cf24 feat(qbz-integrations): create third-party integrations crate
New crate for Last.fm, ListenBrainz, and MusicBrainz integrations.
Designed to work WITHOUT Tauri for TUI/headless clients.

Modules:
- lastfm: Scrobbling and now-playing via Cloudflare Workers proxy
- listenbrainz: Direct API client with user token auth
- musicbrainz: Entity resolution with rate limiting

Features:
- `cache` (default): SQLite persistence for offline support
  - ListenBrainz: Credential storage, offline listen queue
  - MusicBrainz: Resolved entity cache with TTL

Architecture:
- Pure async Rust, no Tauri dependencies
- Shared error types via IntegrationError enum
- Rate limiting for MusicBrainz (1 req/sec direct, faster via proxy)
2026-02-15 10:36:53 -06:00