diff --git a/czkawka_cli/src/main.rs b/czkawka_cli/src/main.rs index ab32d45..f9a86fa 100644 --- a/czkawka_cli/src/main.rs +++ b/czkawka_cli/src/main.rs @@ -46,7 +46,7 @@ fn main() { // a.command, // match &a.argument { // Some(t) => t.clone(), - // None => "MISSING_ARGUMENT".to_string(), + // None => "NO_ARGUMENT".to_string(), // } // ); // } @@ -58,7 +58,6 @@ fn main() { match commands_arguments[0].as_ref() { "--d" => { let mut df = duplicate::DuplicateFinder::new(); - let mut check_method: duplicate::CheckingMethod = duplicate::CheckingMethod::HASH; if ArgumentsPair::has_command(&arguments, "-i") { df.set_include_directory(ArgumentsPair::get_argument(&arguments, "-i", false)); @@ -100,32 +99,33 @@ fn main() { if ArgumentsPair::has_command(&arguments, "-o") { df.set_recursive_search(false); } + df.set_check_method(duplicate::CheckingMethod::HASH); // Default if ArgumentsPair::has_command(&arguments, "-l") { let argument_name = ArgumentsPair::get_argument(&arguments, "-l", false).to_lowercase(); if argument_name == "size" { - check_method = duplicate::CheckingMethod::SIZE; + df.set_check_method(duplicate::CheckingMethod::SIZE); } else if argument_name == "hash" { - check_method = duplicate::CheckingMethod::HASH; + df.set_check_method(duplicate::CheckingMethod::HASH); } else { println!("-l can only have values hash or size"); process::exit(1); } } - let mut delete_method: duplicate::DeleteMethod = duplicate::DeleteMethod::None; + df.set_delete_method(duplicate::DeleteMethod::None); if ArgumentsPair::has_command(&arguments, "-delete") { - delete_method = duplicate::DeleteMethod::AllExceptOldest; let argument_name = ArgumentsPair::get_argument(&arguments, "-delete", true).to_lowercase(); if argument_name == "aen" { - delete_method = duplicate::DeleteMethod::AllExceptNewest; + df.set_delete_method(duplicate::DeleteMethod::AllExceptNewest); } else if argument_name == "aeo" { - delete_method = duplicate::DeleteMethod::AllExceptOldest; + df.set_delete_method(duplicate::DeleteMethod::AllExceptOldest); } else if argument_name == "on" { - delete_method = duplicate::DeleteMethod::OneNewest; + df.set_delete_method(duplicate::DeleteMethod::OneNewest); } else if argument_name == "oo" { - delete_method = duplicate::DeleteMethod::OneOldest; + df.set_delete_method(duplicate::DeleteMethod::OneOldest); } else if argument_name == "" { - // Nothing to do choosing default one + // Default + df.set_delete_method(duplicate::DeleteMethod::AllExceptOldest); } else { println!( "Invalid argument {} for command -delete, available arguments - aen(All except newest one), aeo(All except oldest one), on(Only one newest), oo(Only one oldest)", @@ -135,7 +135,7 @@ fn main() { } } - df.find_duplicates(&check_method, &delete_method); + df.find_duplicates(); if ArgumentsPair::has_command(&arguments, "-f") { df.save_results_to_file(&ArgumentsPair::get_argument(&arguments, "-f", false)); diff --git a/czkawka_core/src/common.rs b/czkawka_core/src/common.rs index 495a194..b692b92 100644 --- a/czkawka_core/src/common.rs +++ b/czkawka_core/src/common.rs @@ -7,11 +7,9 @@ use std::time::SystemTime; pub struct Common(); impl Common { /// Printing time which took between start and stop point and prints also function name - pub fn print_time(start_time: SystemTime, end_time: SystemTime, function_name: String) { - if false { - return; - } - println!("Execution of function \"{}\" took {:?}", function_name, end_time.duration_since(start_time).expect("Time cannot go reverse.")); + pub fn print_time(_start_time: SystemTime, _end_time: SystemTime, _function_name: String) { + #[cfg(debug_assertions)] + println!("Execution of function \"{}\" took {:?}", _function_name, _end_time.duration_since(_start_time).expect("Time cannot go reverse.")); } pub fn delete_multiple_entries(entries: &[String]) -> Vec { diff --git a/czkawka_core/src/duplicate.rs b/czkawka_core/src/duplicate.rs index 2452723..5794f61 100644 --- a/czkawka_core/src/duplicate.rs +++ b/czkawka_core/src/duplicate.rs @@ -10,6 +10,7 @@ use crate::common::Common; #[derive(PartialEq)] pub enum CheckingMethod { + NONE, SIZE, HASH, } @@ -31,19 +32,6 @@ struct FileEntry { pub modified_date: SystemTime, } -/// Struct with required information's to work -pub struct DuplicateFinder { - infos: Info, - files_with_identical_size: BTreeMap>, - files_with_identical_hashes: BTreeMap>>, - allowed_extensions: Vec, - excluded_items: Vec, - excluded_directories: Vec, - included_directories: Vec, - recursive_search: bool, - min_file_size: u64, -} - /// Info struck with helpful information's about results pub struct Info { pub errors: Vec, @@ -92,6 +80,21 @@ impl Default for Info { } } +/// Struct with required information's to work +pub struct DuplicateFinder { + infos: Info, + files_with_identical_size: BTreeMap>, + files_with_identical_hashes: BTreeMap>>, + allowed_extensions: Vec, + excluded_items: Vec, + excluded_directories: Vec, + included_directories: Vec, + recursive_search: bool, + min_file_size: u64, + check_method: CheckingMethod, + delete_method: DeleteMethod, +} + impl DuplicateFinder { pub fn new() -> DuplicateFinder { DuplicateFinder { @@ -104,23 +107,33 @@ impl DuplicateFinder { recursive_search: true, min_file_size: 1024, allowed_extensions: vec![], + check_method: CheckingMethod::NONE, + delete_method: DeleteMethod::None, } } pub fn get_infos(&self) -> &Info { &self.infos } - pub fn find_duplicates(&mut self, check_method: &CheckingMethod, delete_method: &DeleteMethod) { + pub fn find_duplicates(&mut self) { self.optimize_directories(); self.check_files_size(); self.remove_files_with_unique_size(); - if *check_method == CheckingMethod::HASH { + if self.check_method == CheckingMethod::HASH { self.check_files_hash(); } - self.delete_files(check_method, delete_method); + self.delete_files(); self.debug_print(); } + pub fn set_check_method(&mut self, check_method: CheckingMethod) { + self.check_method = check_method; + } + + pub fn set_delete_method(&mut self, delete_method: DeleteMethod) { + self.delete_method = delete_method; + } + pub fn set_min_file_size(&mut self, min_size: u64) { self.min_file_size = min_size; } @@ -129,7 +142,7 @@ impl DuplicateFinder { self.recursive_search = recursive_search; } pub fn set_excluded_items(&mut self, mut excluded_items: String) { - // let start_time: SystemTime = SystemTime::now(); + let start_time: SystemTime = SystemTime::now(); if excluded_items.is_empty() { return; @@ -157,10 +170,11 @@ impl DuplicateFinder { checked_expressions.push(expression); } - self.excluded_items = checked_expressions; + Common::print_time(start_time, SystemTime::now(), "set_excluded_items".to_string()); } pub fn set_allowed_extensions(&mut self, mut allowed_extensions: String) { + let start_time: SystemTime = SystemTime::now(); if allowed_extensions.is_empty() { self.infos.messages.push("No allowed extension was provided, so all are allowed".to_string()); return; @@ -172,17 +186,19 @@ impl DuplicateFinder { let extensions: Vec = allowed_extensions.split(',').map(String::from).collect(); for mut extension in extensions { - if extension == "" { + if extension == "" || extension.replace('.', "").trim() == "" { continue; } - if extension.contains('.') { - if !extension.starts_with('.') { - self.infos.warnings.push(extension + " is not valid extension(valid extension doesn't have dot inside)"); - continue; - } - extension = extension.replace('.', ""); + if extension.starts_with('.') { + extension = extension[1..].to_string(); } + + if extension[1..].contains('.') { + self.infos.warnings.push(".".to_string() + extension.as_str() + " is not valid extension(valid extension doesn't have dot inside)"); + continue; + } + if !self.allowed_extensions.contains(&extension.trim().to_string()) { self.allowed_extensions.push(extension.trim().to_string()); } @@ -191,9 +207,10 @@ impl DuplicateFinder { if self.allowed_extensions.is_empty() { self.infos.messages.push("No valid extensions were provided, so allowing all extensions by default.".to_string()); } + Common::print_time(start_time, SystemTime::now(), "set_allowed_extensions".to_string()); } pub fn set_include_directory(&mut self, mut include_directory: String) -> bool { - // let start_time: SystemTime = SystemTime::now(); + let start_time: SystemTime = SystemTime::now(); if include_directory.is_empty() { self.infos.errors.push("At least one directory must be provided".to_string()); @@ -242,12 +259,12 @@ impl DuplicateFinder { self.included_directories = checked_directories; - //Common::print_time(start_time, SystemTime::now(), "set_include_directory".to_string()); + Common::print_time(start_time, SystemTime::now(), "set_include_directory".to_string()); true } pub fn set_exclude_directory(&mut self, mut exclude_directory: String) { - //let start_time: SystemTime = SystemTime::now(); + let start_time: SystemTime = SystemTime::now(); if exclude_directory.is_empty() { return; } @@ -292,7 +309,7 @@ impl DuplicateFinder { } self.excluded_directories = checked_directories; - //Common::print_time(start_time, SystemTime::now(), "set_exclude_directory".to_string()); + Common::print_time(start_time, SystemTime::now(), "set_exclude_directory".to_string()); } fn check_files_size(&mut self) { @@ -433,9 +450,9 @@ impl DuplicateFinder { } } Common::print_time(start_time, SystemTime::now(), "check_files_size".to_string()); - //println!("Duration of finding duplicates {:?}", end_time.duration_since(start_time).expect("a")); } pub fn save_results_to_file(&mut self, file_name: &str) { + let start_time: SystemTime = SystemTime::now(); let file_name: String = match file_name { "" => "results.txt".to_string(), k => k.to_string(), @@ -488,6 +505,7 @@ impl DuplicateFinder { } } } + Common::print_time(start_time, SystemTime::now(), "save_results_to_file".to_string()); } /// Remove files which have unique size @@ -572,8 +590,13 @@ impl DuplicateFinder { } #[allow(dead_code)] + #[allow(unreachable_code)] /// Setting include directories, panics when there is not directories available fn debug_print(&self) { + #[cfg(not(debug_assertions))] + { + return; + } println!("---------------DEBUG PRINT---------------"); println!("### Infos"); @@ -654,6 +677,9 @@ impl DuplicateFinder { println!(); } } + CheckingMethod::NONE => { + panic!("Checking Method shouldn't be ever set to NONE"); + } } Common::print_time(start_time, SystemTime::now(), "print_duplicated_entries".to_string()); } @@ -781,17 +807,14 @@ impl DuplicateFinder { true } - fn delete_files(&mut self, check_method: &CheckingMethod, delete_method: &DeleteMethod) { - if *delete_method == DeleteMethod::None { - return; - } + fn delete_files(&mut self) { let start_time: SystemTime = SystemTime::now(); - match check_method { + match self.check_method { CheckingMethod::HASH => { for entry in &self.files_with_identical_hashes { for vector in entry.1 { - let tuple: (u64, usize, usize) = delete_files(&vector, &delete_method, &mut self.infos.warnings); + let tuple: (u64, usize, usize) = delete_files(&vector, &self.delete_method, &mut self.infos.warnings); self.infos.gained_space += tuple.0; self.infos.number_of_removed_files += tuple.1; self.infos.number_of_failed_to_remove_files += tuple.2; @@ -800,12 +823,16 @@ impl DuplicateFinder { } CheckingMethod::SIZE => { for entry in &self.files_with_identical_size { - let tuple: (u64, usize, usize) = delete_files(&entry.1, &delete_method, &mut self.infos.warnings); + let tuple: (u64, usize, usize) = delete_files(&entry.1, &self.delete_method, &mut self.infos.warnings); self.infos.gained_space += tuple.0; self.infos.number_of_removed_files += tuple.1; self.infos.number_of_failed_to_remove_files += tuple.2; } } + CheckingMethod::NONE => { + //Just do nothing + panic!("Checking method should never be none."); + } } Common::print_time(start_time, SystemTime::now(), "delete_files".to_string()); @@ -912,9 +939,8 @@ fn delete_files(vector: &[FileEntry], delete_method: &DeleteMethod, warnings: &m } } DeleteMethod::None => { - panic!(); + // Just don't remove files } }; - println!("{} {} {}", gained_space, removed_files, failed_to_remove_files); (gained_space, removed_files, failed_to_remove_files) } diff --git a/czkawka_core/src/empty_folder.rs b/czkawka_core/src/empty_folder.rs index bfe8d83..96fa3b7 100644 --- a/czkawka_core/src/empty_folder.rs +++ b/czkawka_core/src/empty_folder.rs @@ -358,7 +358,7 @@ impl EmptyFolder { /// Set include dir which needs to be relative, exists, pub fn set_include_directory(&mut self, mut include_directory: String) { - // let start_time: SystemTime = SystemTime::now(); + let start_time: SystemTime = SystemTime::now(); if include_directory.is_empty() { println!("At least one directory must be provided"); @@ -413,11 +413,11 @@ impl EmptyFolder { self.included_directories = checked_directories; - //Common::print_time(start_time, SystemTime::now(), "set_include_directory".to_string()); + Common::print_time(start_time, SystemTime::now(), "set_include_directory".to_string()); } pub fn set_exclude_directory(&mut self, mut exclude_directory: String) { - //let start_time: SystemTime = SystemTime::now(); + let start_time: SystemTime = SystemTime::now(); if exclude_directory.is_empty() { return; } @@ -466,7 +466,7 @@ impl EmptyFolder { } self.excluded_directories = checked_directories; - //Common::print_time(start_time, SystemTime::now(), "set_exclude_directory".to_string()); + Common::print_time(start_time, SystemTime::now(), "set_exclude_directory".to_string()); } } impl Default for EmptyFolder { diff --git a/czkawka_gui/src/main.rs b/czkawka_gui/src/main.rs index 9e36b40..835bd83 100644 --- a/czkawka_gui/src/main.rs +++ b/czkawka_gui/src/main.rs @@ -2,7 +2,6 @@ use czkawka_core::{duplicate, empty_folder}; extern crate gtk; -use czkawka_core::duplicate::{CheckingMethod, DeleteMethod}; use duplicate::DuplicateFinder; use gtk::prelude::*; use gtk::{Builder, TreeView, TreeViewColumn}; @@ -115,13 +114,15 @@ fn main() { assert!(notebook_chooser_tool_children_names.contains(&"notebook_empty_folders_label".to_string())); match notebook_chooser_tool_children_names.get(notebook_chooser_tool.get_current_page().unwrap() as usize).unwrap().as_str() { "notebook_duplicate_finder_label" => { + // TODO Change to proper value let mut df = DuplicateFinder::new(); df.set_include_directory("/home/rafal/Pulpit".to_owned()); df.set_exclude_directory("/rafa/".to_owned()); df.set_excluded_items("".to_owned()); df.set_allowed_extensions("".to_owned()); - df.set_min_file_size(1000); // TODO Change to proper value - df.find_duplicates(&CheckingMethod::HASH, &DeleteMethod::None); + df.set_min_file_size(1000); + df.set_delete_method(duplicate::DeleteMethod::AllExceptNewest); + df.find_duplicates(); let _infos = df.get_infos(); info_entry.set_text("Found TODO duplicates files in TODO groups which took TODO GB/MB/KB/B");