Compare commits
6 commits
2fed2c8223
...
95fe74e395
Author | SHA1 | Date | |
---|---|---|---|
95fe74e395 | |||
ef339297c3 | |||
2bacc48e17 | |||
6ffdb55479 | |||
6b9f9bd71c | |||
e1279517a9 |
2 changed files with 39 additions and 20 deletions
15
src/lib.rs
15
src/lib.rs
|
@ -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)?;
|
||||||
|
|
||||||
|
|
44
src/main.rs
44
src/main.rs
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue