- Imports reorganized: use lofty::prelude::*, lofty::tag::*, lofty::picture::*
- Picture::new_unchecked -> Picture::unchecked().pic_type().mime_type().build()
- set_year/remove_year -> set_date/remove_date with Timestamp
- ItemKey::Unknown("ISRC") -> ItemKey::Isrc
- save_to_path(path) -> save_to_path(path, WriteOptions::default())
- get_string/remove_key now take ItemKey by value
- Bump qbz-library crate lofty dep to 0.23
cc
is_disc_folder() was matching any folder name containing "Disc N" or
"CDN" anywhere in the name. This caused albums like "100 Popular
Classics, Disc 1" or "Now 75 - CD1" under Various Artists to be treated
as disc subfolders, collapsing all tracks into a single album group.
Now is_disc_folder() only returns true when the folder name consists
exclusively of disc-related tokens (disc/cd/disk, digits, and modifiers
like "bonus"). Album names with extra words are correctly left as-is.
Users must re-scan their library for the fix to take effect.
- Add filename-based track number inference as fallback when tags lack track_number
- Detect degenerate track numbering (all tracks same number) and use index fallback
- Flatten single-track-per-disc box sets into sequential numbering
- Replace fragile SELECT * with explicit column list in track queries
insert_qobuz_cached_track_direct was hardcoding track_number to 0,
causing all imported tracks to show wrong numbers. Now accepts
track_number and disc_number params, and both callers (backfill
downloads and offline cache sync) extract metadata from the audio
file via MetadataExtractor before inserting.
Also fix LocalLibraryView to use || instead of ?? for track_number
fallback, so 0 correctly falls back to index-based numbering.
Closes#147
insert_track() now checks downloaded_purchases table to set source.
get_downloaded_purchase_track_ids() verifies file existence and
auto-removes stale entries. Closes#115
The library scanner's album_root_dir() only knew to skip disc folders
(Disc 1, CD2, etc.) when resolving the album directory. Files stored
in quality subfolders like artist/album/FLAC 24-bit - 96 kHz/track.flac
caused each encoding variant to appear as a separate album card.
Add is_encoding_folder() to detect common audio format directory names
(FLAC, MP3, AAC, WAV, etc.) and make album_root_dir() skip past both
encoding and disc subdirectories, handling chained nesting too.
Fixes the workaround from #116.
Migrate downloaded_purchases to compound PK (track_id, format_id) so
the same track downloaded in MP3 and FLAC are tracked separately.
Album detail endpoint now returns downloaded_format_ids per track.
Add get_all_custom_artist_images() database method and
v2_library_get_all_custom_artist_images command to support
loading all custom artist image overrides at once for the
global resolution store.
- downloaded_purchases table in library DB (permanent, per-user)
- V2 commands: mark_downloaded, remove_downloaded, get_downloaded_track_ids
- Frontend enriches purchase data with download status from backend
- Grid overlay for unavailable albums centered on artwork
- Quality filter expanded: All / Hi-Res / CD / Lossy (radio group)
- Album download status derived from track-level registry
Create qbz-library crate with:
- LibraryScanner: directory scanning for audio files
- MetadataExtractor: audio metadata extraction via lofty
- LibraryDatabase: SQLite persistence with WAL mode
- CueParser: CUE sheet parsing for single-file albums
- Thumbnails: artwork extraction and thumbnail generation
- Tag sidecar: album metadata override files
src-tauri re-exports from qbz-library for backwards compatibility.
Enables TUI/headless clients to manage local libraries without Tauri.