diff --git a/src-tauri/src/library/commands.rs b/src-tauri/src/library/commands.rs index 83bc87bf2..62c2707bc 100644 --- a/src-tauri/src/library/commands.rs +++ b/src-tauri/src/library/commands.rs @@ -6,7 +6,7 @@ use tauri::State; use tokio::sync::Mutex; use crate::library::{ - cue_to_tracks, CueParser, LibraryDatabase, LibraryError, LibraryScanner, LibraryStats, + cue_to_tracks, get_artwork_cache_dir, CueParser, LibraryDatabase, LibraryScanner, LibraryStats, LocalAlbum, LocalArtist, LocalTrack, MetadataExtractor, ScanError, ScanProgress, ScanStatus, }; @@ -158,7 +158,15 @@ pub async fn library_scan(state: State<'_, LibraryState>) -> Result<(), String> } match MetadataExtractor::extract(audio_path) { - Ok(track) => { + Ok(mut track) => { + // Try to extract embedded artwork, fallback to folder artwork + let artwork_cache = get_artwork_cache_dir(); + if let Some(artwork_path) = MetadataExtractor::extract_artwork(audio_path, &artwork_cache) { + track.artwork_path = Some(artwork_path); + } else if let Some(folder_art) = MetadataExtractor::find_folder_artwork(audio_path) { + track.artwork_path = Some(folder_art); + } + let db = state.db.lock().await; if let Err(e) = db.insert_track(&track) { all_errors.push(ScanError { diff --git a/src-tauri/src/library/metadata.rs b/src-tauri/src/library/metadata.rs index bbb64abdc..a73bf8a67 100644 --- a/src-tauri/src/library/metadata.rs +++ b/src-tauri/src/library/metadata.rs @@ -197,6 +197,31 @@ impl MetadataExtractor { } hash } + + /// Look for folder artwork (cover.jpg, folder.jpg, etc.) + /// Returns the path if found + pub fn find_folder_artwork(audio_file_path: &Path) -> Option { + let parent_dir = audio_file_path.parent()?; + + // Common artwork filenames in order of preference + const ARTWORK_NAMES: &[&str] = &[ + "cover.jpg", "cover.jpeg", "cover.png", + "folder.jpg", "folder.jpeg", "folder.png", + "front.jpg", "front.jpeg", "front.png", + "album.jpg", "album.jpeg", "album.png", + "Cover.jpg", "Cover.jpeg", "Cover.png", + "Folder.jpg", "Folder.jpeg", "Folder.png", + ]; + + for name in ARTWORK_NAMES { + let artwork_path = parent_dir.join(name); + if artwork_path.exists() { + return Some(artwork_path.to_string_lossy().to_string()); + } + } + + None + } } #[cfg(test)] diff --git a/src-tauri/src/library/mod.rs b/src-tauri/src/library/mod.rs index 6be3747d6..f20283f08 100644 --- a/src-tauri/src/library/mod.rs +++ b/src-tauri/src/library/mod.rs @@ -32,6 +32,16 @@ pub fn get_db_path() -> PathBuf { data_dir.join("library.db") } +/// Get artwork cache directory +pub fn get_artwork_cache_dir() -> PathBuf { + let cache_dir = dirs::cache_dir() + .unwrap_or_else(|| PathBuf::from(".")) + .join("qbz") + .join("artwork"); + std::fs::create_dir_all(&cache_dir).ok(); + cache_dir +} + /// Initialize library state pub fn init_library_state() -> Result { let db_path = get_db_path();