use std::fs::DirEntry; use std::io; use std::path::PathBuf; fn home_dir() -> PathBuf { dirs::home_dir().expect("Couldn't find home dir") } fn downloads_dir() -> PathBuf { dirs::download_dir().expect("Couldn't find download dir") } 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 yes() -> bool { let mut answer = String::new(); io::stdin().read_line(&mut answer) .expect("Failed to read input"); answer.to_lowercase().starts_with("y") } fn handle_mp3(file: DirEntry) { let meta = mp3_metadata::read_from_file(file.path()).unwrap(); if let Some(tag) = 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()); if yes() { 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..."); } } } fn handle_dir(path: PathBuf) { let dir = std::fs::read_dir(path).expect("Couldn't read dir"); for inode in dir { let inode = inode.unwrap(); if inode.metadata().unwrap().is_dir() { handle_dir(inode.path()); } match inode.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") => { handle_mp3(inode) } // todo m4a, flac, etc? _ => { /*println!("Here's where we would do nothing.");*/ } } } } fn main() { handle_dir(downloads_dir()); }