diff --git a/Cargo.lock b/Cargo.lock index 29fae9f..489c287 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3290,6 +3290,7 @@ dependencies = [ "log", "onetagger-platforms", "onetagger-player", + "onetagger-renamer", "onetagger-shared", "onetagger-tag", "onetagger-tagger", diff --git a/client/src/components/AutotaggerAdvanced.vue b/client/src/components/AutotaggerAdvanced.vue index 901635c..f6bb653 100644 --- a/client/src/components/AutotaggerAdvanced.vue +++ b/client/src/components/AutotaggerAdvanced.vue @@ -295,6 +295,14 @@ class='input' > + + +
warn!("Invalid album art!") } @@ -327,7 +321,24 @@ impl TrackImpl for Track { } // Save - tag.save_file(path.as_ref())?; + tag.save_file(&path.as_ref())?; + + // Cover file + if let Some(cover_data) = cover_data { + match AudioFileInfo::load_file(&path, None, None) { + Ok(info) => { + let cover_path = get_cover_path(&info, path.as_ref().parent().unwrap(), config); + match std::fs::write(&cover_path, cover_data) { + Ok(_) => debug!("Cover written to: {}", cover_path.display()), + Err(e) => error!("Failed to write cover file: {e}"), + } + }, + Err(e) => { + error!("Failed generating cover path: {e}"); + } + } + } + Ok(()) } @@ -379,6 +390,23 @@ impl TrackImpl for Track { } +/// Get path to cover file +fn get_cover_path(info: &AudioFileInfo, folder: impl AsRef, config: &TaggerConfig) -> PathBuf { + let mut path = folder.as_ref().join("cover.jpg"); + + if let Some(template) = config.cover_filename.as_ref() { + if !template.trim().is_empty() { + // Generate new filename + let renamer_config = RenamerConfig::default_with_paths(&folder, template); + let mut renamer = Renamer::new(TemplateParser::parse(template)); + let new_path = renamer.generate_name(folder.as_ref(), info, &renamer_config); + path = new_path.with_extension("jpg"); + } + } + + path +} + pub trait AudioFileInfoImpl { /// Load audio file info from path fn load_file(path: impl AsRef, filename_template: Option, title_regex: Option) -> Result; diff --git a/crates/onetagger-renamer/src/lib.rs b/crates/onetagger-renamer/src/lib.rs index d5d5281..98b34d5 100644 --- a/crates/onetagger-renamer/src/lib.rs +++ b/crates/onetagger-renamer/src/lib.rs @@ -170,6 +170,22 @@ pub struct RenamerConfig { pub keep_subfolders: bool, } +impl RenamerConfig { + /// Create new instance with default properties and paths + pub fn default_with_paths(path: impl AsRef, template: &str) -> RenamerConfig { + RenamerConfig { + path: path.as_ref().to_path_buf(), + out_dir: None, + template: template.to_string(), + copy: false, + overwrite: false, + keep_subfolders: false, + separator: ", ".to_owned(), + subfolders: true, + } + } +} + /// HTML generation test #[test] fn generate_html() { diff --git a/crates/onetagger-tagger/src/custom.rs b/crates/onetagger-tagger/src/custom.rs index e70f1e0..e211a22 100644 --- a/crates/onetagger-tagger/src/custom.rs +++ b/crates/onetagger-tagger/src/custom.rs @@ -4,7 +4,7 @@ use log::{Record, Level, RecordBuilder}; use crate::TrackMatch; /// Version of supported custom platform -pub const CUSTOM_PLATFORM_COMPATIBILITY: i32 = 44; +pub const CUSTOM_PLATFORM_COMPATIBILITY: i32 = 45; /// Logging from plugins #[no_mangle] diff --git a/crates/onetagger-tagger/src/lib.rs b/crates/onetagger-tagger/src/lib.rs index 32756c0..a689046 100644 --- a/crates/onetagger-tagger/src/lib.rs +++ b/crates/onetagger-tagger/src/lib.rs @@ -85,6 +85,8 @@ pub struct TaggerConfig { pub album_tagging: bool, /// % of tracks that have to be from one album to be considered as the correct pub album_tagging_ratio: f32, + /// Renamer template + pub cover_filename: Option, /// Platform specific. Format: `{ platform: { custom_option: value }}` pub custom: PlatformTaggerConfig, @@ -166,7 +168,8 @@ impl Default for TaggerConfig { id3_comm_lang: None, fetch_all_results: false, album_tagging: false, - album_tagging_ratio: 0.5 + album_tagging_ratio: 0.5, + cover_filename: None } } }