diff --git a/Cargo.lock b/Cargo.lock index 8dd6e07..28e58ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anyhow" @@ -29,6 +29,26 @@ version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +[[package]] +name = "audiotags" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44e797ce0164cf599c71f2c3849b56301d96a3dc033544588e875686b050ed39" +dependencies = [ + "audiotags-macro", + "id3", + "metaflac", + "mp4ameta", + "readme-rustdocifier", + "thiserror", +] + +[[package]] +name = "audiotags-macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa9b2312fc01f7291f3b7b0f52ed08b1c0177c96a2e696ab55695cc4d06889" + [[package]] name = "autocfg" version = "1.3.0" @@ -37,9 +57,9 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "byteorder" @@ -55,9 +75,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.4" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +checksum = "35723e6a11662c2afb578bcf0b88bf6ea8e21282a953428f240574fcc3a2b5b3" dependencies = [ "clap_builder", "clap_derive", @@ -65,9 +85,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.2" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +checksum = "49eb96cbfa7cfa35017b7cd548c75b14c3118c98b423041d70562665e07fb0fa" dependencies = [ "anstyle", "clap_lex", @@ -75,9 +95,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.4" +version = "4.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +checksum = "5d029b67f89d30bbb547c89fd5161293c0aec155fc691d7924b64550662db93e" dependencies = [ "heck", "proc-macro2", @@ -87,9 +107,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "cow-utils" @@ -164,9 +184,9 @@ checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "either" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "flate2" @@ -202,11 +222,17 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "id3" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79f41f7e5ad125c63d55b112a98afb753742fa7f97692bfbbc52544b89e1ff1f" +checksum = "55f4e785f2c700217ee82a1c727c720449421742abd5fcb2f1df04e1244760e9" dependencies = [ "bitflags", "byteorder", @@ -223,6 +249,12 @@ dependencies = [ "rayon", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.155" @@ -234,6 +266,7 @@ name = "mack" version = "1.4.1" dependencies = [ "anyhow", + "audiotags", "clap", "cow-utils", "funcfmt", @@ -248,19 +281,45 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "metaflac" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f083edae4a21f5acb1fda8220d1c14fa31f725bfd4e21005a14c2d8944db9b" +dependencies = [ + "byteorder", + "hex", +] [[package]] name = "miniz_oxide" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] +[[package]] +name = "mp4ameta" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb23d62e8eb5299a3f79657c70ea9269eac8f6239a76952689bcd06a74057e81" +dependencies = [ + "lazy_static", + "mp4ameta_proc", +] + +[[package]] +name = "mp4ameta_proc" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07dcca13d1740c0a665f77104803360da0bdb3323ecce2e93fa2c959a6d52806" + [[package]] name = "once_cell" version = "1.19.0" @@ -269,9 +328,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "proc-macro2" -version = "1.0.83" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -305,11 +364,17 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "readme-rustdocifier" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ad765b21a08b1a8e5cdce052719188a23772bcbefb3c439f0baaf62c56ceac" + [[package]] name = "regex" -version = "1.10.4" +version = "1.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" dependencies = [ "aho-corasick", "memchr", @@ -319,9 +384,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -330,9 +395,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "smallvec" @@ -359,9 +424,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "syn" -version = "2.0.66" +version = "2.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" dependencies = [ "proc-macro2", "quote", @@ -370,18 +435,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.61" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 9235e19..a800e7a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,11 @@ license = "MIT" rust-version = "1.65.0" [dependencies] -clap = { version = "4.3.24", features = ["std", "derive", "help"], default-features = false } +clap = { version = "4.3.24", features = [ + "std", + "derive", + "help", +], default-features = false } regex = "1.10.4" anyhow = "1.0.86" id3 = { version = "1.13.1", default-features = false } @@ -21,6 +25,7 @@ once_cell = { default-features = false, features = ["std"], version = "1.19.0" } cow-utils = "0.1.3" rayon = "1.10.0" jwalk = "0.8.1" +audiotags = "0.5.0" [target.'cfg(target_family = "unix")'.dependencies] libc = "0.2.155" diff --git a/src/fixers.rs b/src/fixers.rs index a95406e..d2f998b 100644 --- a/src/fixers.rs +++ b/src/fixers.rs @@ -2,20 +2,19 @@ use crate::extract::extract_feat; use crate::types::{Track, TrackFeat}; use anyhow::{bail, Result}; use cow_utils::CowUtils; -use id3::{Tag, TagLike, Version}; use once_cell::sync::Lazy; use regex::Regex; static MULTI_WS_RE: Lazy = Lazy::new(|| Regex::new(r"[ \t]+").expect("BUG: Invalid regex")); pub fn run_fixers(track: &mut Track, dry_run: bool) -> Result { - let tags = &mut track.tag; + fixer_is_blacklisted(track)?; - fixer_is_blacklisted(tags)?; + let tags = &mut track.tag; let new_title = fix_title(tags.title(), tags.artist()); let new_artist = fix_artist(tags.artist()); - let new_album = fix_album(tags.album()); + let new_album = fix_album(tags.album_title()); let mut changed = false; if let Some(new_artist) = new_artist { @@ -28,11 +27,11 @@ pub fn run_fixers(track: &mut Track, dry_run: bool) -> Result { } if let Some(new_album) = new_album { changed = true; - tags.set_album(&new_album); + tags.set_album_title(&new_album); } if !dry_run && changed { - tags.write_to_path(&track.path, Version::Id3v24)?; + tags.write_to_path(track.path.to_str().unwrap())?; } Ok(changed) @@ -127,12 +126,13 @@ fn make_feat_string(featured_artists: &[String]) -> String { output } -fn fixer_is_blacklisted(tags: &Tag) -> Result<()> { - for comment in tags.comments() { - if comment.text.contains("_NO_MACK") { +fn fixer_is_blacklisted(track: &mut Track) -> Result<()> { + if let Some(comment) = track.tag.comment() { + if comment.contains("_NO_MACK") { bail!("Comment contains _NO_MACK"); } } + Ok(()) } diff --git a/src/main.rs b/src/main.rs index 6b4eb73..f87fdca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,6 @@ mod types; use anyhow::Result; use clap::Parser; use funcfmt::{fm, FormatMap, FormatPieces, ToFormatPieces}; -use id3::TagLike; use jwalk::WalkDir; use rayon::prelude::*; use std::ffi::OsStr; @@ -34,7 +33,7 @@ fn print_updated_tags(track: &types::Track) { "{}: updated tags: artist: '{}', album: '{}', title: '{}'", track.path.display(), track.tag.artist().unwrap_or_default(), - track.tag.album().unwrap_or_default(), + track.tag.album_title().unwrap_or_default(), track.tag.title().unwrap_or_default() ); } @@ -82,14 +81,14 @@ fn get_format_pieces(tmpl: &str) -> Result> t.tag.artist().unwrap_or("Unknown Artist") )), "album" => |t: &types::Track| Some(clean_part( - t.tag.album().unwrap_or("Unknown Album") + t.tag.album_title().unwrap_or("Unknown Album") )), "title" => |t: &types::Track| Some(clean_part( t.tag.title().unwrap_or("Unknown Title") )), "track" => |t: &types::Track| Some(format!( "{:02}", - t.tag.track().unwrap_or_default() + t.tag.track_number().unwrap_or_default() )), ); diff --git a/src/track.rs b/src/track.rs index d936465..b30ae31 100644 --- a/src/track.rs +++ b/src/track.rs @@ -1,9 +1,9 @@ use crate::types::Track; use anyhow::Result; -use id3::Tag; +use audiotags::Tag; use std::path::PathBuf; pub fn get_track(path: PathBuf) -> Result { - let tag = Tag::read_from_path(&path)?; + let tag = Tag::new().read_from_path(&path)?; Ok(Track { path, tag }) } diff --git a/src/types.rs b/src/types.rs index 411e804..e31a1f0 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,10 +1,10 @@ +use audiotags::AudioTag; use clap::Parser; -use id3::Tag; use std::path::PathBuf; pub struct Track { pub path: PathBuf, - pub tag: Tag, + pub tag: Box, } #[derive(Debug, PartialEq, Eq)]