summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs169
1 files changed, 169 insertions, 0 deletions
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<String>,
+ album: Option<String>,
+ track: Option<u32>,
+}
+
+impl InnerTag {
+ pub fn empty() -> InnerTag {
+ InnerTag {title: "".into(), artist: None, album: None, track: None}
+ }
+
+ pub fn from(name: &str) -> Result<InnerTag, Error>{
+ let mut inner_tag: InnerTag = InnerTag::empty();
+
+ let mut tags: Vec<String> = 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
Software created with 💖