Implement online music search in shanty-search #8

Closed
opened 2026-03-17 16:20:43 -04:00 by connor · 0 comments
Owner

The shanty-search crate provides the ability to search for music online — finding artists, albums, and tracks that can then be added to the user's library (watchlist). This is the "discovery" piece that feeds into shanty-watch. It wraps online music databases and returns structured results.

This issue covers:

  1. MusicBrainz search — implement search functionality against the MusicBrainz API:

    • Search for artists by name → returns list of matching artists with MusicBrainz IDs, disambiguation, and basic info
    • Search for albums (releases) by name and/or artist → returns matching releases with track listings
    • Search for tracks (recordings) by name and/or artist → returns matching recordings
    • Get an artist's discography (all releases) given a MusicBrainz artist ID
  2. Result types — define clean, serializable result types:

    • ArtistSearchResult — name, MBID, disambiguation, country, type (person/group)
    • AlbumSearchResult — title, artist, MBID, year, track count, cover art URL
    • TrackSearchResult — title, artist, album, MBID, duration, track number
    • Discography — list of releases grouped by type (album, single, EP, compilation)
  3. Search provider trait — define a SearchProvider trait so that alternative backends (Last.fm, Spotify API for metadata, Discogs, etc.) can be added later. The trait should cover:

    • search_artist(query) -> Vec<ArtistSearchResult>
    • search_album(query, artist_hint) -> Vec<AlbumSearchResult>
    • search_track(query, artist_hint) -> Vec<TrackSearchResult>
    • get_artist_discography(artist_id) -> Discography
  4. Caching — optionally cache search results in shanty-db to reduce API calls for repeated searches. Cache entries should have a TTL (e.g., 24 hours).

  5. CLI interface — the shanty-search binary should accept:

    • artist <query> — search for an artist
    • album <query> [--artist <artist>] — search for an album
    • track <query> [--artist <artist>] — search for a track
    • discography <artist_name_or_mbid> — show an artist's discography
    • --json — output results as JSON (useful for piping to other tools)
    • --limit <n> — max number of results (default 10)

Design Considerations

  • This crate shares the MusicBrainz client with shanty-tag. Consider whether the MB client should live in a shared utility crate (e.g., shanty-mb) or in shanty-db, or whether each crate has its own thin client. A shared client avoids duplication of rate-limiting logic.
  • The web interface will be the primary consumer of this crate — search results will be displayed in the UI and the user will click to add items to their watchlist. So the result types should be JSON-serializable and contain enough info for display.
  • MusicBrainz rate limits apply here too — reuse the rate limiter.

Acceptance Criteria

  • Artist search returns relevant results from MusicBrainz
  • Album search works, optionally filtered by artist
  • Track search works, optionally filtered by artist
  • Artist discography retrieval works and groups releases by type
  • Result types are well-defined and JSON-serializable
  • SearchProvider trait exists with MusicBrainz as the first implementation
  • CLI interface works as specified
  • --json output is valid JSON
  • Rate limiting is respected
  • Optional caching works and respects TTL
  • Tests exist with mocked API responses

Dependencies

  • Issue #1 (workspace scaffolding)
  • Issue #2 (shared database schema — for caching)
  • Consider: shared MusicBrainz client with Issue #4 (tagging)
The `shanty-search` crate provides the ability to search for music online — finding artists, albums, and tracks that can then be added to the user's library (watchlist). This is the "discovery" piece that feeds into `shanty-watch`. It wraps online music databases and returns structured results. This issue covers: 1. **MusicBrainz search** — implement search functionality against the MusicBrainz API: - Search for artists by name → returns list of matching artists with MusicBrainz IDs, disambiguation, and basic info - Search for albums (releases) by name and/or artist → returns matching releases with track listings - Search for tracks (recordings) by name and/or artist → returns matching recordings - Get an artist's discography (all releases) given a MusicBrainz artist ID 2. **Result types** — define clean, serializable result types: - `ArtistSearchResult` — name, MBID, disambiguation, country, type (person/group) - `AlbumSearchResult` — title, artist, MBID, year, track count, cover art URL - `TrackSearchResult` — title, artist, album, MBID, duration, track number - `Discography` — list of releases grouped by type (album, single, EP, compilation) 3. **Search provider trait** — define a `SearchProvider` trait so that alternative backends (Last.fm, Spotify API for metadata, Discogs, etc.) can be added later. The trait should cover: - `search_artist(query) -> Vec<ArtistSearchResult>` - `search_album(query, artist_hint) -> Vec<AlbumSearchResult>` - `search_track(query, artist_hint) -> Vec<TrackSearchResult>` - `get_artist_discography(artist_id) -> Discography` 4. **Caching** — optionally cache search results in `shanty-db` to reduce API calls for repeated searches. Cache entries should have a TTL (e.g., 24 hours). 5. **CLI interface** — the `shanty-search` binary should accept: - `artist <query>` — search for an artist - `album <query> [--artist <artist>]` — search for an album - `track <query> [--artist <artist>]` — search for a track - `discography <artist_name_or_mbid>` — show an artist's discography - `--json` — output results as JSON (useful for piping to other tools) - `--limit <n>` — max number of results (default 10) ### Design Considerations - This crate shares the MusicBrainz client with `shanty-tag`. Consider whether the MB client should live in a shared utility crate (e.g., `shanty-mb`) or in `shanty-db`, or whether each crate has its own thin client. A shared client avoids duplication of rate-limiting logic. - The web interface will be the primary consumer of this crate — search results will be displayed in the UI and the user will click to add items to their watchlist. So the result types should be JSON-serializable and contain enough info for display. - MusicBrainz rate limits apply here too — reuse the rate limiter. ### Acceptance Criteria - [ ] Artist search returns relevant results from MusicBrainz - [ ] Album search works, optionally filtered by artist - [ ] Track search works, optionally filtered by artist - [ ] Artist discography retrieval works and groups releases by type - [ ] Result types are well-defined and JSON-serializable - [ ] `SearchProvider` trait exists with MusicBrainz as the first implementation - [ ] CLI interface works as specified - [ ] `--json` output is valid JSON - [ ] Rate limiting is respected - [ ] Optional caching works and respects TTL - [ ] Tests exist with mocked API responses ### Dependencies - Issue #1 (workspace scaffolding) - Issue #2 (shared database schema — for caching) - Consider: shared MusicBrainz client with Issue #4 (tagging)
connor added the MVPHighPriority labels 2026-03-17 16:20:43 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Shanty/Main#8