feat: recursiveness

This commit is contained in:
Vladimir Rubin 2024-12-30 17:05:56 +02:00
parent cf0aa33314
commit 1e811d61ed
Signed by: vavakado
GPG key ID: CAB744727F36B524

View file

@ -1,7 +1,7 @@
use std::{ use std::{
env, fs, env, fs,
io::{self, Write}, io::{self, Write},
path::PathBuf, path::{Path, PathBuf},
process, process,
sync::OnceLock, sync::OnceLock,
thread, thread,
@ -86,12 +86,33 @@ fn main() {
break; break;
} }
let recursive: bool;
loop {
print!("Recursive (yes/no): ");
io::stdout().flush().unwrap();
let mut selected = String::new();
io::stdin()
.read_line(&mut selected)
.expect("Failed to read line");
if selected.trim().starts_with('y') {
recursive = true;
break;
} else if selected.trim().starts_with('n') {
recursive = false;
break;
}
println!("Invalid answer");
}
println!("Selected: {}", actual_selection.join(", ")); println!("Selected: {}", actual_selection.join(", "));
let mut thread_pool: Vec<thread::JoinHandle<()>> = Vec::new(); let mut thread_pool: Vec<thread::JoinHandle<()>> = Vec::new();
for selection in actual_selection { for selection in actual_selection {
let thread = thread::spawn(move || match sort_files(selection, false) { let thread = thread::spawn(move || match sort_files(selection, recursive) {
Ok(_) => {} Ok(_) => {}
Err(err) => eprintln!("{}", err), Err(err) => eprintln!("{}", err),
}); });
@ -104,16 +125,13 @@ fn main() {
} }
} }
// TODO: implement recuriveness fn sort_files(selection: String, recursive: bool) -> Result<(), Box<dyn std::error::Error>> {
fn sort_files(selection: String, _recursive: bool) -> Result<(), Box<dyn std::error::Error>> {
let search_path = CONFIG let search_path = CONFIG
.get() .get()
.and_then(|config| config.sources.get(&selection)) .and_then(|config| config.sources.get(&selection))
.cloned() .cloned()
.unwrap(); .unwrap();
let dir = fs::read_dir(search_path)?;
let file_types = [ let file_types = [
( (
"Picture", "Picture",
@ -137,26 +155,58 @@ fn sort_files(selection: String, _recursive: bool) -> Result<(), Box<dyn std::er
), ),
]; ];
for entry in dir.flatten().filter(|e| e.metadata().unwrap().is_file()) { fn process_directory(
if let Some(extension) = entry.path().extension().and_then(|e| e.to_str()) { path: &std::path::Path,
let path = entry.path(); file_types: &[(&str, Vec<&str>, Option<std::path::PathBuf>)],
recursive: bool,
) -> Result<(), Box<dyn std::error::Error>> {
for entry in fs::read_dir(path)?.flatten() {
let metadata = entry.metadata()?;
for (label, valid_extensions, target_dir_option) in &file_types { if metadata.is_file() {
if let Some(target_dir) = target_dir_option { if let Some(extension) = entry.path().extension().and_then(|e| e.to_str()) {
if valid_extensions.contains(&extension) { let file_path = entry.path();
println!("{}: {}", label, path.display());
move_file_to_directory(&path, target_dir); for (_label, valid_extensions, target_dir_option) in file_types {
if let Some(target_dir) = target_dir_option {
if valid_extensions.contains(&extension) {
move_file_to_directory(&file_path, target_dir);
}
}
} }
} }
} else if metadata.is_dir() && recursive {
// Recurse into the directory
process_directory(&entry.path(), file_types, recursive)?;
} }
} }
Ok(())
} }
Ok(()) process_directory(&search_path, &file_types, recursive)
} }
fn move_file_to_directory(path: &std::path::Path, dir: &std::path::Path) { fn move_file_to_directory(path: &Path, dir: &Path) {
let _ = fs::rename(path, dir.join(path.file_name().unwrap())); if !path.exists() {
eprintln!("Source file does not exist");
return;
}
if !dir.exists() {
match fs::create_dir(dir) {
Ok(_) => {},
Err(err) => eprintln!("Error creating destination directory: {}", err)
}
return;
}
let destination = dir.join(path.file_name().unwrap_or_default());
match fs::rename(path, &destination) {
Ok(()) => {},
Err(err) => eprintln!("Error moving file: {}", err),
}
} }
fn get_config_path() -> PathBuf { fn get_config_path() -> PathBuf {