diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ef4a9c5..414b7ec 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,6 +33,7 @@ jobs: name: bliss-analyser-linux path: releases/ + macOS: runs-on: macos-11.0 @@ -47,7 +48,7 @@ jobs: - name: Install deps run: | - brew install ffmpeg@5 + brew install ffmpeg@5 - name: Build run: | @@ -65,6 +66,7 @@ jobs: name: bliss-analyser-mac path: releases/ + Windows: runs-on: windows-2019 diff --git a/Cargo.lock b/Cargo.lock index d8c0065..6bf9647 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -732,8 +732,7 @@ dependencies = [ [[package]] name = "lofty" version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc751ba10f732cf5c522b9bc887027c9eee277512a38a3a0c4f1806bdcd730d" +source = "git+https://github.com/Serial-ATA/lofty-rs?rev=45182b6#45182b6e3d71f9b9cc022aca9e3e192abb82ad10" dependencies = [ "base64", "byteorder", diff --git a/Cargo.toml b/Cargo.toml index 8b19890..2adac3d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ rusqlite = { version = "0.25.0", features = ["bundled"] } log = "0.4.14" env_logger = "0.8.4" indicatif = "0.16.2" -lofty = "0.5.3" +lofty = { git = "https://github.com/Serial-ATA/lofty-rs", rev = "45182b6" } dirs = "1" chrono = "0.4.19" regex = "1" diff --git a/ChangeLog b/ChangeLog index cc19df5..a3cd217 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,11 @@ 0.1.0 ----- 1. Add support for analysing CUE files. -2. Support up to 5 music folders (music, music_1, music_2, music_3, and +2. Output list of (up to 100) tracks that failed to analyse. +3. When performing a dry-run analysis (--dry-run) print paths of all tracks to + be analysed and to be removed. +4. Use git version of tag reader library. +5. Support up to 5 music folders (music, music_1, music_2, music_3, and music_4). 0.0.2 diff --git a/src/analyse.rs b/src/analyse.rs index b06043b..2937d89 100644 --- a/src/analyse.rs +++ b/src/analyse.rs @@ -27,7 +27,8 @@ use crate::db; use crate::tags; const DONT_ANALYSE:&str = ".notmusic"; -const MAX_TAG_ERRORS_TO_SHOW:usize = 25; +const MAX_ERRORS_TO_SHOW:usize = 100; +const MAX_TAG_ERRORS_TO_SHOW:usize = 50; fn get_file_list(db:&mut db::Db, mpath:&PathBuf, path:&PathBuf, track_paths:&mut Vec, cue_tracks:&mut Vec) { if path.is_dir() { @@ -112,7 +113,7 @@ pub fn analyse_new_files(db:&db::Db, mpath: &PathBuf, track_paths:Vec) - let results = analyze_paths_streaming(track_paths)?; let mut analysed = 0; - let mut failed = 0; + let mut failed:Vec = Vec::new(); let mut tag_error:Vec = Vec::new(); log::info!("Analysing new tracks"); @@ -133,13 +134,25 @@ pub fn analyse_new_files(db:&db::Db, mpath: &PathBuf, track_paths:Vec) - db.add_track(&sname, &meta, &track.analysis); analysed += 1; }, - Err(_) => { - failed += 1; + Err(e) => { + failed.push(format!("{} - {}", sname, e)); } }; pb.inc(1); } - pb.finish_with_message(format!("{} Analysed. {} Failure(s).", analysed, failed)); + pb.finish_with_message(format!("{} Analysed. {} Failure(s).", analysed, failed.len())); + if !failed.is_empty() { + let total = failed.len(); + failed.truncate(MAX_ERRORS_TO_SHOW); + + log::error!("Failed to analyse the folling track(s):"); + for err in failed { + log::error!(" {}", err); + } + if total>MAX_ERRORS_TO_SHOW { + log::error!(" + {} other(s)", total - MAX_ERRORS_TO_SHOW); + } + } if !tag_error.is_empty() { let total = tag_error.len(); tag_error.truncate(MAX_TAG_ERRORS_TO_SHOW); @@ -255,7 +268,7 @@ pub fn analyse_new_cue_tracks(db:&db::Db, mpath: &PathBuf, cue_tracks:Vec = Vec::new(); log::info!("Analysing new cue tracks"); for (track, result) in results { @@ -277,13 +290,25 @@ pub fn analyse_new_cue_tracks(db:&db::Db, mpath: &PathBuf, cue_tracks:Vec { - failed += 1; + Err(e) => { + failed.push(format!("{} - {}", sname, e)); } }; pb.inc(1); } - pb.finish_with_message(format!("{} Analysed. {} Failure(s).", analysed, failed)); + pb.finish_with_message(format!("{} Analysed. {} Failure(s).", analysed, failed.len())); + if !failed.is_empty() { + let total = failed.len(); + failed.truncate(MAX_ERRORS_TO_SHOW); + + log::error!("Failed to analyse the folling track(s):"); + for err in failed { + log::error!(" {}", err); + } + if total>MAX_ERRORS_TO_SHOW { + log::error!(" + {} other(s)", total - MAX_ERRORS_TO_SHOW); + } + } Ok(()) } @@ -292,6 +317,10 @@ pub fn analyse_files(db_path: &str, mpaths: &Vec, dry_run:bool, keep_ol db.init(); + if !keep_old { + db.remove_old(mpaths, dry_run); + } + for path in mpaths { let mpath = path.clone(); let cur = path.clone(); @@ -300,6 +329,7 @@ pub fn analyse_files(db_path: &str, mpaths: &Vec, dry_run:bool, keep_ol log::info!("Looking for new tracks in {}", mpath.to_string_lossy()); get_file_list(&mut db, &mpath, &cur, &mut track_paths, &mut cue_tracks); + track_paths.sort(); log::info!("Num new tracks: {}", track_paths.len()); if !cue_tracks.is_empty() { log::info!("Num new cue tracks: {}", cue_tracks.len()); @@ -312,9 +342,18 @@ pub fn analyse_files(db_path: &str, mpaths: &Vec, dry_run:bool, keep_ol log::info!("Only analysing {} cue tracks", max_num_tracks); cue_tracks.truncate(max_num_tracks); } - - if !dry_run { - if track_paths.len()>0 { + if dry_run { + if !track_paths.is_empty() || !cue_tracks.is_empty() { + log::info!("The following need to be analysed:"); + for track in track_paths { + log::info!(" {}", track); + } + for track in cue_tracks { + log::info!(" {}", track.track_path.to_string_lossy()); + } + } + } else { + if !track_paths.is_empty() { match analyse_new_files(&db, &mpath, track_paths) { Ok(_) => { }, Err(e) => { log::error!("Analysis returned error: {}", e); } @@ -322,6 +361,7 @@ pub fn analyse_files(db_path: &str, mpaths: &Vec, dry_run:bool, keep_ol } else { log::info!("No new tracks to analyse"); } + if !cue_tracks.is_empty() { match analyse_new_cue_tracks(&db, &mpath, cue_tracks) { Ok(_) => { }, @@ -331,10 +371,6 @@ pub fn analyse_files(db_path: &str, mpaths: &Vec, dry_run:bool, keep_ol } } - if !keep_old { - db.remove_old(mpaths, dry_run); - } - db.close(); } diff --git a/src/db.rs b/src/db.rs index ac641d8..90bd3a4 100644 --- a/src/db.rs +++ b/src/db.rs @@ -188,18 +188,25 @@ impl Db { let num_to_remove = to_remove.len(); log::info!("Num non-existant tracks: {}", num_to_remove); - if !dry_run && num_to_remove>0 { - let count_before = self.get_track_count(); - for t in to_remove { - //log::debug!("Remove '{}'", t); - match self.conn.execute("DELETE FROM Tracks WHERE File = ?;", params![t]) { - Ok(_) => { }, - Err(e) => { log::error!("Failed to remove '{}' - {}", t, e) } + if num_to_remove>0 { + if dry_run { + log::info!("The following need to be removed from database:"); + for t in to_remove { + log::info!(" {}", t); + } + } else { + let count_before = self.get_track_count(); + for t in to_remove { + //log::debug!("Remove '{}'", t); + match self.conn.execute("DELETE FROM Tracks WHERE File = ?;", params![t]) { + Ok(_) => { }, + Err(e) => { log::error!("Failed to remove '{}' - {}", t, e) } + } + } + let count_now = self.get_track_count(); + if (count_now + num_to_remove) != count_before { + log::error!("Failed to remove all tracks. Count before: {}, wanted to remove: {}, count now: {}", count_before, num_to_remove, count_now); } - } - let count_now = self.get_track_count(); - if (count_now + num_to_remove) != count_before { - log::error!("Failed to remove all tracks. Count before: {}, wanted to remove: {}, count now: {}", count_before, num_to_remove, count_now); } } }