From 6fe316b2ffba45d3cf65400a06b7008c1a617485 Mon Sep 17 00:00:00 2001 From: Connor Johnstone Date: Wed, 18 Mar 2026 13:45:07 -0400 Subject: [PATCH] Lots of fixes for artist detail page --- Cargo.lock | 1 + UI_ISSUES.md | 167 -------------------------------------------------- readme.md | 131 +++++++++++++++++++++++++++++++++------ shanty-search | 2 +- shanty-tag | 2 +- shanty-watch | 2 +- shanty-web | 2 +- 7 files changed, 116 insertions(+), 191 deletions(-) delete mode 100644 UI_ISSUES.md diff --git a/Cargo.lock b/Cargo.lock index 2c784fa..bce3669 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3100,6 +3100,7 @@ dependencies = [ "chrono", "clap", "dirs", + "reqwest", "sea-orm", "serde", "serde_json", diff --git a/UI_ISSUES.md b/UI_ISSUES.md deleted file mode 100644 index 54677a2..0000000 --- a/UI_ISSUES.md +++ /dev/null @@ -1,167 +0,0 @@ -# Shanty — UI Improvement Issues - -Issues generated from manual testing of the Yew frontend MVP. Each is self-contained and can be copy-pasted into Gitea. - ---- - -## Issue: "Set Sail" — one-click full pipeline with progress tracking - -**Labels:** `enhancement`, `frontend`, `backend`, `priority:high` - -### Description - -The core value proposition of Shanty is automation: the user adds music to their watchlist and the app handles everything else. Currently this requires manually triggering 4-5 separate actions. There should be a single "Set Sail" button (or similarly pirate-themed name — "Weigh Anchor", "Hoist the Colors", "Full Speed Ahead", etc.) that runs the entire pipeline: - -1. **Sync** — sync wanted items to the download queue -2. **Download** — process the download queue -3. **Index** — index newly downloaded files -4. **Tag** — auto-tag tracks that need metadata -5. **Organize** — organize tagged files into the library structure - -### Requirements - -1. **Backend**: Add a new endpoint `POST /api/pipeline` that: - - Runs each step sequentially (sync → download → index → tag → organize) - - Returns a task ID immediately - - Reports progress as it moves through each phase - - Can be paused/cancelled (stretch goal) - -2. **Progress model**: The task should report which phase it's in and the progress within that phase: - ```json - { - "task_id": "...", - "phase": "downloading", - "phase_number": 2, - "total_phases": 5, - "phase_progress": { "current": 5, "total": 14 }, - "overall_progress": 35 - } - ``` - -3. **Frontend**: - - Prominent "Set Sail" button on the dashboard (with a fun icon — maybe a ship wheel ⎈ or pirate flag) - - When running, shows a multi-phase progress view: - - Phase indicator (which step we're on) - - Progress bar for the current phase - - Overall progress bar - - Estimated time remaining (based on rate so far) - - Can be started from the dashboard - -4. **Smart behavior**: - - Skip phases with nothing to do (e.g., if sync returns 0 new items but there are already pending downloads, go straight to download) - - After completion, show a summary: "Downloaded 14 tracks, tagged 14, organized 14" - -### Acceptance Criteria - -- [ ] "Set Sail" button on the dashboard triggers the full pipeline -- [ ] Backend runs sync → download → index → tag → organize sequentially -- [ ] Progress is reported per-phase with current/total counts -- [ ] Frontend shows multi-phase progress visualization -- [ ] Summary is displayed on completion -- [ ] Pipeline handles "nothing to do" phases gracefully - -### Dependencies - -- All existing pipeline crates (shanty-dl, shanty-index, shanty-tag, shanty-org) -- Backend task system needs progress reporting enhancement - ---- - -## Issue: Rich artist/album/track metadata — photos, bios, album art, lyrics - -**Labels:** `enhancement`, `post-mvp`, `frontend`, `backend` - -### Description - -Currently the UI looks like a file manager — just tables of names and IDs. To feel like a proper music library, it should display rich metadata: artist photos, biographies, album artwork, track lyrics, and links to external profiles. - -This is a post-MVP enhancement but will significantly improve the user experience. - -### Requirements - -1. **Artist pages**: - - Profile photo (from MusicBrainz → Wikimedia Commons, or from fanart.tv API) - - Biography text (from Wikipedia via MusicBrainz's URL relationships, or Last.fm API) - - External links: official website, social media, streaming profiles - - Genre tags - - Formation year, country, members (if group) - -2. **Album pages**: - - Album cover art (from Cover Art Archive via MusicBrainz release MBID — this API is free) - - Release date, label, genre - - Track listing with durations - - Total album duration - -3. **Track pages** (or inline on album page): - - Lyrics (via external API — Genius, Musixmatch, or LRCLIB for synced lyrics) - - Duration, bitrate, codec info - - MusicBrainz recording link - -4. **Backend work**: - - Cover Art Archive integration: `https://coverartarchive.org/release/{mbid}/front-250` (free, no auth) - - Artist image: MusicBrainz URL relationships → Wikimedia Commons - - Bio: Wikipedia API via MusicBrainz URL relationships - - Cache fetched metadata to avoid repeated API calls - -### Data Sources (all free) -- **Cover Art Archive** — album art via MBID (no auth, generous rate limits) -- **Wikipedia API** — artist biographies (free, no auth) -- **MusicBrainz URL relationships** — links to Wikipedia, social media, official sites -- **fanart.tv** — artist images (free tier with API key) -- **LRCLIB** — synced lyrics (free, open source) - -### Acceptance Criteria - -- [ ] Artist pages display a photo and biography -- [ ] Album pages display cover art -- [ ] External links are shown where available -- [ ] Cover art is cached to avoid repeated fetches -- [ ] Graceful degradation when metadata isn't available (placeholder images, "no bio available") - -### Dependencies - -- Backend: new endpoints or enrichment of existing artist/album responses -- External API integrations (Cover Art Archive, Wikipedia) - ---- - -## Issue: Consolidate action buttons — all actions accessible from dashboard - -**Labels:** `enhancement`, `frontend`, `priority:low` - -### Description - -Currently, action buttons are scattered across pages: -- Download sync and process buttons are on the Downloads page -- Re-index, auto-tag, and organize buttons are on the Settings page - -All action buttons should be accessible from the dashboard as the central "command center". Keep copies on their respective pages for convenience, but the dashboard should be the one-stop shop. - -### Requirements - -1. **Dashboard actions section** — a card or section with all available actions: - - "Sync from Watchlist" — syncs wanted items to download queue - - "Process Downloads" — starts downloading queued items - - "Re-index Library" — scans library directory for new files - - "Auto-tag Tracks" — tags tracks missing metadata - - "Organize Files" — moves files into organized structure - - "Set Sail" — full pipeline (see separate issue) - -2. **Keep existing button locations** — don't remove buttons from Downloads or Settings pages. Users who navigate directly to those pages should still find the relevant actions there. - -3. **Visual grouping** — on the dashboard, group related actions: - - "Watchlist" group: Sync - - "Downloads" group: Process, Retry All Failed - - "Library" group: Re-index, Auto-tag, Organize - - "Pipeline" group: Set Sail - -### Acceptance Criteria - -- [ ] All action buttons are present on the dashboard -- [ ] Buttons are visually grouped by category -- [ ] Existing button placements on other pages are preserved -- [ ] Each button shows feedback when clicked (task started, task ID, etc.) - -### Dependencies - -- Dashboard enhancement issue diff --git a/readme.md b/readme.md index 03374d5..75419e7 100644 --- a/readme.md +++ b/readme.md @@ -1,33 +1,124 @@ # shanty -A modular music management application for the high seas. Shanty aims to be a better -all-in-one solution for managing, tagging, organizing, and downloading music — built -as a collection of standalone tools that work together seamlessly. +A modular, self-hosted music management application for the high seas. Shanty aims to be a +better alternative to Lidarr — managing, tagging, organizing, and downloading music, all +built as a collection of standalone Rust tools that work together seamlessly through a web UI. + +## Features + +- **Search** MusicBrainz for artists, albums, and tracks +- **Watch** artists/albums — automatically expands to individual track-level monitoring +- **Download** music via yt-dlp with YouTube Music search (ytmusicapi) +- **Tag** files with MusicBrainz metadata (fuzzy matching + MBID-based lookup) +- **Organize** files into clean directory structures with configurable templates +- **Web UI** — Yew (Rust/WASM) dashboard with real-time status, search, library browser ## Architecture -Shanty is organized as a Cargo workspace. Each component is its own crate, usable both -as a library and (where applicable) a standalone CLI binary. +Shanty is a Cargo workspace where each component is its own crate and git submodule. +Each crate is both a library (for the web app) and a standalone CLI binary. -| Crate | Description | -|-------|-------------| -| `shanty-db` | Shared database schema and access layer | -| `shanty-index` | Music file indexing and metadata extraction | -| `shanty-tag` | Metadata tagging via online databases | -| `shanty-org` | File organization and renaming | -| `shanty-watch` | Library watchlist management | -| `shanty-dl` | Music downloading (yt-dlp and more) | -| `shanty-search` | Online music search | -| `shanty-notify` | Notifications for new releases and events | -| `shanty-playlist` | Playlist generation | -| `shanty-serve` | Music serving and streaming | -| `shanty-play` | Built-in playback | -| `shanty-web` | Web interface backend (Actix) with Elm frontend | +| Crate | Description | Status | +|-------|-------------|--------| +| `shanty-db` | Sea-ORM + SQLite schema, migrations, queries | Done | +| `shanty-index` | Music file scanning and metadata extraction (lofty) | Done | +| `shanty-tag` | MusicBrainz client, fuzzy matching, file tag writing | Done | +| `shanty-org` | File organization with configurable format templates | Done | +| `shanty-watch` | Watchlist management, MB discography expansion | Done | +| `shanty-dl` | yt-dlp backend, rate limiting, download queue | Done | +| `shanty-search` | SearchProvider trait, MB search + release groups | Done | +| `shanty-web` | Actix backend + Yew frontend | Done (MVP) | +| `shanty-notify` | Notifications (Apprise, webhooks) | Stub | +| `shanty-playlist` | Playlist generation | Stub | +| `shanty-serve` | Subsonic-compatible music streaming | Stub | +| `shanty-play` | Built-in web player | Stub | -## Building +## Quick Start + +### Prerequisites + +- Rust (edition 2024) +- [yt-dlp](https://github.com/yt-dlp/yt-dlp) + ffmpeg +- Python 3 + `pip install ytmusicapi` +- [Trunk](https://trunkrs.dev/) (for building the frontend) + +### Build ```sh +# Backend (all crates) cargo build --workspace + +# Frontend (Yew/WASM) +cd shanty-web/frontend && trunk build +``` + +### Run the web app + +```sh +cargo run --bin shanty-web -- -v +# Open http://localhost:8085 +``` + +### CLI tools + +Each crate also works as a standalone CLI: + +```sh +# Index a music directory +cargo run --bin shanty-index -- /path/to/music -v + +# Tag untagged tracks +cargo run --bin shanty-tag -- --all --write-tags -v + +# Search MusicBrainz +cargo run --bin shanty-search -- artist "Pink Floyd" + +# Add to watchlist (expands album to individual tracks) +cargo run --bin shanty-watch -- add album "Green Day" "Dookie" + +# Sync watchlist to download queue and process +cargo run --bin shanty-dl -- queue sync -v +cargo run --bin shanty-dl -- queue process -v + +# Organize files +cargo run --bin shanty-org -- --from-db --target ~/Music -v +``` + +### Full pipeline (CLI) + +```sh +shanty-watch add album "Green Day" "Dookie" --mbid +shanty-dl queue sync -v +shanty-dl queue process -v +shanty-tag --all --write-tags -v +shanty-org --from-db --target ~/Music -v +``` + +## Configuration + +Create `~/.config/shanty/config.yaml`: + +```yaml +library_path: ~/Music +download_path: ~/.local/share/shanty/downloads +organization_format: "{artist}/{album}/{track_number} - {title}.{ext}" + +# Filter which release types to show (empty = studio only) +# Options: Compilation, Live, Soundtrack, Remix, DJ-mix, Demo +allowed_secondary_types: [] + +web: + port: 8085 + bind: 0.0.0.0 + +tagging: + write_tags: true + confidence: 0.85 + +download: + format: opus + search_source: ytmusic + # cookies_path: ~/.config/shanty/cookies.txt # for higher YT rate limits ``` ## Testing diff --git a/shanty-search b/shanty-search index 208dbf4..d09557d 160000 --- a/shanty-search +++ b/shanty-search @@ -1 +1 @@ -Subproject commit 208dbf422b34dea3c5bb0837e5f425206119baa9 +Subproject commit d09557d953ee918fb83d952149f77a564b5631f3 diff --git a/shanty-tag b/shanty-tag index 0572722..966dc6c 160000 --- a/shanty-tag +++ b/shanty-tag @@ -1 +1 @@ -Subproject commit 05727221846beff65c4908aff0324f5a98e1fce8 +Subproject commit 966dc6ca864faae07d0b5b3ecfea1603bf4d0020 diff --git a/shanty-watch b/shanty-watch index 7bee8a9..3d01fa8 160000 --- a/shanty-watch +++ b/shanty-watch @@ -1 +1 @@ -Subproject commit 7bee8a9afa875c66234ac2269d428ef3b1554775 +Subproject commit 3d01fa85c9575683204a9a875d9ff7bb7711c17c diff --git a/shanty-web b/shanty-web index 2314346..a268ec4 160000 --- a/shanty-web +++ b/shanty-web @@ -1 +1 @@ -Subproject commit 2314346925394e9003209041324c2d7f207fc860 +Subproject commit a268ec4e568f918657f321f6ccb241b85c8abe35