From fcf044db0618c1901bc3c46b238353c95491cbfc Mon Sep 17 00:00:00 2001 From: Jakub Trzeciak Date: Tue, 12 Sep 2023 09:24:19 +0200 Subject: Init --- src/main.rs | 169 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 src/main.rs (limited to 'src') diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..2bf1274 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,169 @@ +use std::{fs::{self, File}, path::Path, io::{Error, BufReader, Read}, fmt::format, os::fd::IntoRawFd}; + +use lofty::{Probe, TaggedFileExt, LoftyError, TagExt, Tag, Picture, Accessor, PictureType}; + +/* + Title + Artist - Title + Artist - Album - Title + Artist - Album - Nr - Title + Artist - Album - Nr - Max Nr - Title + */ + +struct InnerTag { + title: String, + artist: Option, + album: Option, + track: Option, +} + +impl InnerTag { + pub fn empty() -> InnerTag { + InnerTag {title: "".into(), artist: None, album: None, track: None} + } + + pub fn from(name: &str) -> Result{ + let mut inner_tag: InnerTag = InnerTag::empty(); + + let mut tags: Vec = Vec::new(); + + { // TODO make it faster and cleaner + let mut text: String = "".into(); + let mut connected = false; + + for s in name.split("-") { + if text == "" { + text = s.into(); + } else { + if s == "" { + connected = true; + text += "-"; + } else if connected { + text += s; + connected = false; + } else { + tags.push(text); + text = s.into(); + } + } + } + + tags.push(text); + } + + match tags.len() { + 1 => { + inner_tag.title = tags.remove(0); + }, + 2 => { + inner_tag.artist = Some(tags.remove(0)); + inner_tag.title = tags.remove(0); + }, + 3 => { + inner_tag.artist = Some(tags.remove(0)); + inner_tag.album = Some(tags.remove(0)); + inner_tag.title = tags.remove(0); + }, + 4 => { + inner_tag.artist = Some(tags.remove(0)); + inner_tag.album = Some(tags.remove(0)); + inner_tag.track = Some(tags.remove(0).parse().unwrap()); + inner_tag.title = tags.remove(0); + }, + 5 => { + inner_tag.artist = Some(tags.remove(0)); + inner_tag.album = Some(tags.remove(0)); + inner_tag.track = Some(tags.remove(0).parse().unwrap()); + inner_tag.title = tags.remove(1); + }, + _ => panic!("FUCK to many tags {}", tags.len()) + } + + return Ok(inner_tag); + } +} + +fn truncate(s: &str, min_chars: usize, max_chars: usize) -> &str { + let e = match s.char_indices().nth(min_chars) { + None => s, + Some((idx, _)) => &s[idx..], + }; + + if max_chars < min_chars { + return ""; + } + + return match e.char_indices().nth(max_chars - min_chars) { + None => e, + Some((idx, _)) => &e[..idx], + } +} + +fn tag_ogg_file(path: &Path) -> Result<(), LoftyError> { + let mut tagged_file = Probe::open(path) + .expect("ERROR: Bad path provided!") + .read()?; + + let tag = match tagged_file.primary_tag_mut() { + Some(primary_tag) => primary_tag, + None => { + if let Some(first_tag) = tagged_file.first_tag_mut() { + first_tag + } else { + let tag_type = tagged_file.primary_tag_type(); + + eprintln!("WARN: No tags found, creating a new tag of type `{tag_type:?}`"); + tagged_file.insert_tag(Tag::new(tag_type)); + + tagged_file.primary_tag_mut().unwrap() + } + }, + }; + + let path_without_ext = path.with_extension(""); + let name = path_without_ext.file_name().unwrap().to_str().unwrap(); + let inner_tag = InnerTag::from(name).unwrap(); + + tag.clear(); + tag.set_title(inner_tag.title); + tag.set_artist(inner_tag.artist.unwrap_or("".into())); + tag.set_album(inner_tag.album.unwrap_or("".into())); + if let Some(track) = inner_tag.track { + tag.set_track(track); + } + + if let Some(album) = tag.album() { + if album != "" { + let image_path = path.parent().unwrap().join(format!(".cover/{}/{}.jpg", tag.artist().unwrap(), album)); + + if image_path.exists() { + let image_file = &mut File::open(image_path.clone()).unwrap(); + + let mut picture = Picture::from_reader(image_file).unwrap(); + picture.set_pic_type(PictureType::CoverFront); + + tag.set_picture(0, picture) + } else { + println!("⚠️ Can't found image {}", image_path.to_str().unwrap()); + } + } + } + + + tag.save_to_path(path).expect("ERROR: Can't save ogg file"); + + println!("✅ {}", name); + + return Ok(()); +} + +fn main() { + let music_dir = fs::read_dir("/home/jp3/Music").unwrap(); + + for path in music_dir { + // println!("Name: {}", path.unwrap().file_name().to_str().unwrap()) + if path.as_ref().unwrap().file_type().unwrap().is_file() { + tag_ogg_file(path.unwrap().path().as_path()); + } + } +} \ No newline at end of file -- cgit v1.2.3