crabidy/plan/jamendo.md

3.6 KiB
Raw Permalink Blame History

Task plan — jamendo provider

Ordered, independently verifiable tasks for /jamendo (architecture/jamendo-provider.md, quality/jamendo.md). Each cites the gate/test it satisfies.

Crate scaffold

  • P1 — Add jamendody to Cargo.toml workspace members; create jamendody/Cargo.toml mirroring soundclouddy (deps: async-trait, crabidy-core, reqwest, serde, thiserror, tokio, toml, tracing; dev-dep tokio full). Verify: cargo metadata lists the crate.

Network seam (api.rs)

  • P2 — Domain types JamTrack (id, title, artist, album, duration_secs) and JamAlbum (id, title, artist, tracks); FetchError (Http, Decode, NotFound, Unauthorized, NotStreamable). Verify: compiles. (G2)
  • P3Jam trait: search_tracks, search_albums, album_tracks, track_detail, track_stream. Doc each with error behavior. Verify: compiles. (G2/G10)
  • P4JamApi (reqwest): new(client_id, audioformat, timeout) with a timeout-bearing client and redacting Debug; get_json helper adding client_id + format=json, decoding the {headers, results} envelope, mapping non-success/404/401 to FetchError. limit.min(200) cap. Verify: cargo build. (G3/G4/G5/G9)
  • P5 — Defensive DTOs (#[serde(default)]) for track/album/envelope and into_track/into_album. Verify: build + a decode unit test on a JSON fixture. (G9)

Provider logic (lib.rs)

  • P6PROVIDER_ROOT, segment consts, JamPath enum + parse_path. Verify: T2, foreign_and_malformed_paths_reject. (D3)
  • P7Settings (client_id: Option<String> + bounds) with redacting Debug. Verify: T10 settings_debug_redacts_client_id. (G3)
  • P8Client + with_api, search-term store helpers (store_add/remove/snapshot), search_limit/album_limit. Verify: compiles. (D3)
  • P9 — Node builders: root_node (search only), store_node, search_term_node (tracks + albums), album_node, list_node, jam_track. Verify: T1, T4, T5, T7, T11. (D3/D4)
  • P10ProviderClient impl: init (require non-empty client_id, else Config), settings, is_track_path, get_urls_for_track (→ track_stream), get_metadata_for_track, get_lib_root, get_lib_node (download blessing), create/rename/delete_lib_node. Verify: T3, T6, T8, T9. (D4/G1/G2/G6)

Tests (tests.rs)

  • P11FakeJam + FailingJam fixtures and all T1T11. Verify: cargo test -p jamendody. (all tests)

Orchestrator + settings wiring (crabidy-server)

  • P12settings.rs: jamendo in ALL_PROVIDERS (8→9), ProviderToggles.jamendo, defaults, provider_toggles(). Verify: build + existing settings tests. (G6)
  • P13provider.rs: jamendo_client field, jamendo_owns, jamendo_provider, non-fatal build() block (reads jamendo.toml), is_track_path arm, get_lib_root child (gated on is_some), get_lib_node arm, get_urls_for_track/get_metadata_for_track arms, create/rename/delete arms. Verify: cargo build -p crabidy-server. (D1/G6/G8)

Verification gate

  • P14cargo fmt --check, cargo clippy -- -D warnings, cargo test green across the workspace. Re-read G1G10 against the diff.
  • P15 (live gate, R1) — with a real client_id in jamendo.toml, browse /jamendo/search/<term>, queue and play a track: confirm audio plays via the existing windowed-HTTP path, seek bar correct (duration from metadata), clean EOS, no panic. Deferred to a run with network + a key.