commit f15d0e0f764e76977f0e3698f0b69aa8088d39ff Author: Max Bradbury Date: Thu Nov 25 22:39:16 2021 +0000 initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..9ef90a3 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,120 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "download-organiser" +version = "0.1.0" +dependencies = [ + "dirs", + "fs_extra", + "mp3-metadata", +] + +[[package]] +name = "fs_extra" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "libc" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119" + +[[package]] +name = "mp3-metadata" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb969bc3573726b0bf60238d5d70f1aa6cc0f9e87f8db3e047b8309317319699" + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +dependencies = [ + "getrandom", + "redox_syscall", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..320effb --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "download-organiser" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +dirs = "^4.0.0" +fs_extra = "^1.2.0" +mp3-metadata = "^0.3.3" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..18ec961 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,91 @@ +use std::io; +use std::path::PathBuf; + +fn home_dir() -> PathBuf { + return dirs::home_dir().unwrap(); +} + +fn downloads_dir() -> PathBuf { + let mut downloads = home_dir(); + + downloads.push("Downloads"); + + downloads +} + +fn strip_null_bytes(str: &str) -> String { + str.replace('\0', "") +} + +/// e.g. for ~/Music/ABBA/ABBA Gold: +/// `create_dir_if_not_exists(vec!["Music", "ABBA", "ABBA Gold"])` +fn create_dir_if_not_exists(path: Vec<&str>) -> PathBuf { + let mut dir = home_dir(); + + for item in path { + dir.push(item); + } + + std::fs::create_dir_all(&dir).unwrap_or(()); + + dir +} + +fn move_file(file: PathBuf, mut destination: PathBuf) { + println!("Moving to {:?}", destination); + + destination.push(file.file_name().unwrap().to_str().unwrap()); + + fs_extra::file::move_file(file, destination, &Default::default()) + .expect("Couldn't move file"); +} + +fn main() { + let downloads = std::fs::read_dir(downloads_dir()).unwrap(); + + // todo break this out into a "handle_dir" function, and recursively call it for child dirs + for file in downloads { + let file = file.unwrap(); + + match file.path().extension().unwrap_or("none".as_ref()).to_str() { + Some("gif") => { /*println!("Here's where we would move things to ~/Pictures");*/ } + Some("jpg") => { /*println!("Here's where we would move things to ~/Pictures");*/ } + Some("jpeg") => { /*println!("Here's where we would move things to ~/Pictures");*/ } + Some("png") => { /*println!("Here's where we would move things to ~/Pictures");*/ } + Some("mp3") => { + let meta = mp3_metadata::read_from_file(file.path()).unwrap(); + + for tag in meta.tag { + println!("----------------------"); + println!("artist: {}", tag.artist.trim()); + println!("album: {}", tag.album.trim()); + println!("title: {}", tag.title.trim()); + + println!("move to: ~/Music/{}/{}/?", tag.artist.trim(), tag.album.trim()); + + let mut answer = String::new(); + + io::stdin().read_line(&mut answer) + .expect("Failed to read input"); + + if answer.to_lowercase().starts_with("y") { + move_file( + file.path(), + create_dir_if_not_exists( + vec![ + "Music", + strip_null_bytes(&tag.artist).trim(), + strip_null_bytes(&tag.album).trim() + ] + ) + ); + } else { + println!("skipping..."); + } + } + } + // todo m4a, flac, etc? + _ => { /*println!("Here's where we would do nothing.");*/ } + }; + } +}