Compare commits

...

6 commits

Author SHA1 Message Date
95fe74e395
feat: show amount of sorted files
All checks were successful
Build and Upload filesorters Binaries / Build for Linux (push) Successful in 2m25s
2024-12-30 19:04:01 +02:00
ef339297c3
fix: general impovements + recursive creation 2024-12-30 19:03:42 +02:00
2bacc48e17
fix: change config dir on windows 2024-12-30 19:03:10 +02:00
6ffdb55479
fix: handle windows \r 2024-12-30 19:02:54 +02:00
6b9f9bd71c
fix: change default config 2024-12-30 19:02:15 +02:00
e1279517a9
feat: handle comments on end of line 2024-12-30 19:01:56 +02:00
2 changed files with 39 additions and 20 deletions

View file

@ -48,8 +48,8 @@ impl Config {
.filter(|l| !l.is_empty()) .filter(|l| !l.is_empty())
.filter(|l| !l.starts_with('#')) .filter(|l| !l.starts_with('#'))
{ {
if line.starts_with('[') && line.ends_with(']') { if line.starts_with('[') && line.contains(']') {
current_section = line[1..line.len() - 1].to_string(); current_section = line[1..line.find(']').unwrap()].to_string();
} else if let Some((key, value)) = line.split_once('=') { } else if let Some((key, value)) = line.split_once('=') {
let key_trimmed_string = key.trim().replace('"', ""); let key_trimmed_string = key.trim().replace('"', "");
let key_trimmed = key_trimmed_string.as_str(); let key_trimmed = key_trimmed_string.as_str();
@ -84,13 +84,14 @@ impl Config {
pub fn create(path: &PathBuf) -> Result<(), Box<dyn std::error::Error>> { pub fn create(path: &PathBuf) -> Result<(), Box<dyn std::error::Error>> {
let config_str = r#" let config_str = r#"
[destinations] [destinations]
pictures_dir = "/home/vavakado/Pictures" pictures_dir = ""
videos_dir = "/home/vavakado/Videos" videos_dir = ""
music_dir = "/home/vavakado/Music" music_dir = ""
books_dir = "/home/vavakado/Books" books_dir = ""
[sources] [sources]
"Pictures" = "/home/vavakado/Pictures" # Put your own sources there like so:
# "Source Name" = "path"
"#; "#;
std::fs::write(path, config_str)?; std::fs::write(path, config_str)?;

View file

@ -3,7 +3,7 @@ use std::{
io::{self, Write}, io::{self, Write},
path::{Path, PathBuf}, path::{Path, PathBuf},
process, process,
sync::OnceLock, sync::{Arc, Mutex, OnceLock},
thread, thread,
}; };
@ -25,7 +25,6 @@ fn main() {
return; return;
} }
if args.len() > 1 if args.len() > 1
&& (args.contains(&"-c".to_string()) || args.contains(&"--config".to_string())) && (args.contains(&"-c".to_string()) || args.contains(&"--config".to_string()))
{ {
@ -82,6 +81,7 @@ fn main() {
.split(" ") .split(" ")
.filter(|y| !y.is_empty()) .filter(|y| !y.is_empty())
.map(|y| y.replace("\n", "")) .map(|y| y.replace("\n", ""))
.map(|y| y.replace("\r", ""))
.flat_map(|x| x.parse::<usize>()) .flat_map(|x| x.parse::<usize>())
.collect(); .collect();
@ -117,6 +117,8 @@ fn main() {
break; break;
} }
println!("Selected: {}", actual_selection.join(", "));
let recursive: bool; let recursive: bool;
loop { loop {
@ -138,14 +140,18 @@ fn main() {
println!("Invalid answer"); println!("Invalid answer");
} }
println!("Selected: {}", actual_selection.join(", "));
let mut thread_pool: Vec<thread::JoinHandle<()>> = Vec::new(); let mut thread_pool: Vec<thread::JoinHandle<()>> = Vec::new();
let total_files_sorted: Arc<Mutex<usize>> = Arc::new(Mutex::new(0));
for selection in actual_selection { for selection in actual_selection {
let tfs = Arc::clone(&total_files_sorted);
let thread = thread::spawn(move || match sort_files(selection, recursive) { let thread = thread::spawn(move || match sort_files(selection, recursive) {
Ok(_) => {} Ok(files_sorted) => {
Err(err) => eprintln!("{}", err), let mut num = tfs.lock().unwrap();
*num += files_sorted
}
Err(err) => eprintln!("Error sorting files: {}", err),
}); });
thread_pool.push(thread); thread_pool.push(thread);
@ -154,9 +160,15 @@ fn main() {
for thread in thread_pool { for thread in thread_pool {
thread.join().unwrap(); thread.join().unwrap();
} }
if *total_files_sorted.lock().unwrap() == 0 {
println!("No sortable files found!");
} else {
println!("Sorted files: {}", total_files_sorted.lock().unwrap());
}
} }
fn sort_files(selection: String, recursive: bool) -> Result<(), Box<dyn std::error::Error>> { fn sort_files(selection: String, recursive: bool) -> Result<usize, 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))
@ -190,7 +202,8 @@ fn sort_files(selection: String, recursive: bool) -> Result<(), Box<dyn std::err
path: &std::path::Path, path: &std::path::Path,
file_types: &[(&str, Vec<&str>, Option<std::path::PathBuf>)], file_types: &[(&str, Vec<&str>, Option<std::path::PathBuf>)],
recursive: bool, recursive: bool,
) -> Result<(), Box<dyn std::error::Error>> { ) -> Result<usize, Box<dyn std::error::Error>> {
let mut files_sorted: usize = 0;
for entry in fs::read_dir(path)?.flatten() { for entry in fs::read_dir(path)?.flatten() {
let metadata = entry.metadata()?; let metadata = entry.metadata()?;
@ -202,17 +215,18 @@ fn sort_files(selection: String, recursive: bool) -> Result<(), Box<dyn std::err
if let Some(target_dir) = target_dir_option { if let Some(target_dir) = target_dir_option {
if valid_extensions.contains(&extension) { if valid_extensions.contains(&extension) {
move_file_to_directory(&file_path, target_dir); move_file_to_directory(&file_path, target_dir);
files_sorted += 1;
} }
} }
} }
} }
} else if metadata.is_dir() && recursive { } else if metadata.is_dir() && recursive {
// Recurse into the directory // Recurse into the directory
process_directory(&entry.path(), file_types, recursive)?; files_sorted += process_directory(&entry.path(), file_types, recursive)?;
} }
} }
Ok(()) Ok(files_sorted)
} }
process_directory(&search_path, &file_types, recursive) process_directory(&search_path, &file_types, recursive)
@ -225,9 +239,13 @@ fn move_file_to_directory(path: &Path, dir: &Path) {
} }
if !dir.exists() { if !dir.exists() {
match fs::create_dir(dir) { match fs::create_dir_all(dir) {
Ok(_) => {} Ok(_) => {}
Err(err) => eprintln!("Error creating destination directory: {}", err), Err(err) => eprintln!(
"Error creating destination directory({}): {}",
dir.display(),
err
),
} }
return; return;
} }
@ -245,7 +263,7 @@ fn get_config_path() -> PathBuf {
if cfg!(target_os = "windows") { if cfg!(target_os = "windows") {
let username = env::var("USERNAME").unwrap_or_else(|_| "Default".to_string()); let username = env::var("USERNAME").unwrap_or_else(|_| "Default".to_string());
PathBuf::from(format!( PathBuf::from(format!(
"C:\\Users\\{}\\AppData\\Local\\filesorters\\filesorters.toml", "C:\\Users\\{}\\AppData\\Local\\filesorters.toml",
username username
)) ))
} else { } else {