From 2b9c0d61df14f7df0edbbec49d37a100ccabbdeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mikrut?= Date: Fri, 18 Sep 2020 10:23:49 +0200 Subject: [PATCH] Add saving to empty folders finder, remove exclude directories from it and put warnings to another function --- czkawka_cli/src/main.rs | 18 ++- czkawka_core/src/duplicate.rs | 141 +++++++++++---------- czkawka_core/src/empty_folder.rs | 209 +++++++++---------------------- 3 files changed, 149 insertions(+), 219 deletions(-) diff --git a/czkawka_cli/src/main.rs b/czkawka_cli/src/main.rs index 16a60ea..fe8bb3f 100644 --- a/czkawka_cli/src/main.rs +++ b/czkawka_cli/src/main.rs @@ -139,11 +139,15 @@ fn main() { df.print_duplicated_entries(); + #[allow(clippy::collapsible_if)] if ArgumentsPair::has_command(&arguments, "-f") { - df.save_results_to_file(&ArgumentsPair::get_argument(&arguments, "-f", false)); + if !df.save_results_to_file(&ArgumentsPair::get_argument(&arguments, "-f", false)) { + df.get_text_messages().print_messages(); + process::exit(1); + } } - df.get_messages().print_messages(); + df.get_text_messages().print_messages(); //print_information(df.get_information()); } "--h" | "--help" => { @@ -158,8 +162,12 @@ fn main() { println!("FATAL ERROR: Parameter -i with set of included files is required."); process::exit(1); } - if ArgumentsPair::has_command(&arguments, "-e") { - ef.set_exclude_directory(ArgumentsPair::get_argument(&arguments, "-e", false)); + #[allow(clippy::collapsible_if)] + if ArgumentsPair::has_command(&arguments, "-f") { + if !ef.save_results_to_file(&ArgumentsPair::get_argument(&arguments, "-f", false)) { + ef.get_text_messages().print_messages(); + process::exit(1); + } } if ArgumentsPair::has_command(&arguments, "-delete") { @@ -206,9 +214,7 @@ Usage of Czkawka: --e <-i directory_to_search> [-e exclude_directories = ""] [-o] [-f file_to_save] [-delete] - option to find and delete empty folders -i directory_to_search - list of directories which should will be searched like /home/rafal - -o - this options prevents from recursive check of folders -e exclude_directories - list of directories which will be excluded from search. - -k excluded_items - list of excluded items which contains * wildcard(may be slow) -f file_to_save - saves results to file -delete - delete found empty folders czkawka --e -i "/home/rafal/rr, /home/gateway" -e "/home/rafal/rr/2" -delete diff --git a/czkawka_core/src/duplicate.rs b/czkawka_core/src/duplicate.rs index a5fbaf4..4ac11a7 100644 --- a/czkawka_core/src/duplicate.rs +++ b/czkawka_core/src/duplicate.rs @@ -76,7 +76,7 @@ impl Default for Info { /// Struct with required information's to work pub struct DuplicateFinder { - messages: Messages, + text_messages: Messages, information: Info, files_with_identical_size: BTreeMap>, files_with_identical_hashes: BTreeMap>>, @@ -93,7 +93,7 @@ pub struct DuplicateFinder { impl DuplicateFinder { pub fn new() -> DuplicateFinder { DuplicateFinder { - messages: Default::default(), + text_messages: Default::default(), information: Info::new(), files_with_identical_size: Default::default(), files_with_identical_hashes: Default::default(), @@ -108,8 +108,8 @@ impl DuplicateFinder { } } - pub fn get_messages(&self) -> &Messages { - &self.messages + pub fn get_text_messages(&self) -> &Messages { + &self.text_messages } pub fn get_information(&self) -> &Info { &self.information @@ -163,7 +163,7 @@ impl DuplicateFinder { continue; } if !expression.contains('*') { - self.messages.warnings.push("Excluded Items Warning: Wildcard * is required in expression, ignoring ".to_string() + expression.as_str()); + self.text_messages.warnings.push("Excluded Items Warning: Wildcard * is required in expression, ignoring ".to_string() + expression.as_str()); continue; } @@ -175,7 +175,7 @@ impl DuplicateFinder { pub fn set_allowed_extensions(&mut self, mut allowed_extensions: String) { let start_time: SystemTime = SystemTime::now(); if allowed_extensions.is_empty() { - self.messages.messages.push("No allowed extension was provided, so all are allowed".to_string()); + self.text_messages.messages.push("No allowed extension was provided, so all are allowed".to_string()); return; } allowed_extensions = allowed_extensions.replace("IMAGE", "jpg,kra,gif,png,bmp,tiff,webp,hdr,svg"); @@ -194,7 +194,7 @@ impl DuplicateFinder { } if extension[1..].contains('.') { - self.messages.warnings.push(".".to_string() + extension.as_str() + " is not valid extension(valid extension doesn't have dot inside)"); + self.text_messages.warnings.push(".".to_string() + extension.as_str() + " is not valid extension(valid extension doesn't have dot inside)"); continue; } @@ -204,7 +204,7 @@ impl DuplicateFinder { } if self.allowed_extensions.is_empty() { - self.messages.messages.push("No valid extensions were provided, so allowing all extensions by default.".to_string()); + self.text_messages.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()); } @@ -212,7 +212,7 @@ impl DuplicateFinder { let start_time: SystemTime = SystemTime::now(); if include_directory.is_empty() { - self.messages.errors.push("At least one directory must be provided".to_string()); + self.text_messages.errors.push("At least one directory must be provided".to_string()); return false; } @@ -227,19 +227,19 @@ impl DuplicateFinder { continue; } if directory.contains('*') { - self.messages.warnings.push("Include Directory Warning: Wildcards in path are not supported, ignoring ".to_string() + directory.as_str()); + self.text_messages.warnings.push("Include Directory Warning: Wildcards in path are not supported, ignoring ".to_string() + directory.as_str()); continue; } if !directory.starts_with('/') { - self.messages.warnings.push("Include Directory Warning: Relative path are not supported, ignoring ".to_string() + directory.as_str()); + self.text_messages.warnings.push("Include Directory Warning: Relative path are not supported, ignoring ".to_string() + directory.as_str()); continue; } if !Path::new(&directory).exists() { - self.messages.warnings.push("Include Directory Warning: Provided folder path must exits, ignoring ".to_string() + directory.as_str()); + self.text_messages.warnings.push("Include Directory Warning: Provided folder path must exits, ignoring ".to_string() + directory.as_str()); continue; } if !Path::new(&directory).is_dir() { - self.messages.warnings.push("Include Directory Warning: Provided path must point at the directory, ignoring ".to_string() + directory.as_str()); + self.text_messages.warnings.push("Include Directory Warning: Provided path must point at the directory, ignoring ".to_string() + directory.as_str()); continue; } @@ -252,7 +252,7 @@ impl DuplicateFinder { } if checked_directories.is_empty() { - self.messages.errors.push("Include Directory ERROR: Not found even one correct path to include which is required.".to_string()); + self.text_messages.errors.push("Include Directory ERROR: Not found even one correct path to include which is required.".to_string()); return false; } @@ -279,23 +279,23 @@ impl DuplicateFinder { continue; } if directory == "/" { - self.messages.errors.push("Exclude Directory ERROR: Excluding / is pointless, because it means that no files will be scanned.".to_string()); + self.text_messages.errors.push("Exclude Directory ERROR: Excluding / is pointless, because it means that no files will be scanned.".to_string()); break; } if directory.contains('*') { - self.messages.warnings.push("Exclude Directory Warning: Wildcards in path are not supported, ignoring ".to_string() + directory.as_str()); + self.text_messages.warnings.push("Exclude Directory Warning: Wildcards in path are not supported, ignoring ".to_string() + directory.as_str()); continue; } if !directory.starts_with('/') { - self.messages.warnings.push("Exclude Directory Warning: Relative path are not supported, ignoring ".to_string() + directory.as_str()); + self.text_messages.warnings.push("Exclude Directory Warning: Relative path are not supported, ignoring ".to_string() + directory.as_str()); continue; } if !Path::new(&directory).exists() { - self.messages.warnings.push("Exclude Directory Warning: Provided folder path must exits, ignoring ".to_string() + directory.as_str()); + self.text_messages.warnings.push("Exclude Directory Warning: Provided folder path must exits, ignoring ".to_string() + directory.as_str()); continue; } if !Path::new(&directory).is_dir() { - self.messages.warnings.push("Exclude Directory Warning: Provided path must point at the directory, ignoring ".to_string() + directory.as_str()); + self.text_messages.warnings.push("Exclude Directory Warning: Provided path must point at the directory, ignoring ".to_string() + directory.as_str()); continue; } @@ -330,7 +330,7 @@ impl DuplicateFinder { let read_dir = match fs::read_dir(¤t_folder) { Ok(t) => t, Err(_) => { - self.messages.warnings.push("Cannot open dir ".to_string() + current_folder.as_str()); + self.text_messages.warnings.push("Cannot open dir ".to_string() + current_folder.as_str()); continue; } // Permissions denied }; @@ -338,21 +338,21 @@ impl DuplicateFinder { let entry_data = match entry { Ok(t) => t, Err(_) => { - self.messages.warnings.push("Cannot read entry in dir ".to_string() + current_folder.as_str()); + self.text_messages.warnings.push("Cannot read entry in dir ".to_string() + current_folder.as_str()); continue; } //Permissions denied }; let metadata: Metadata = match entry_data.metadata() { Ok(t) => t, Err(_) => { - self.messages.warnings.push("Cannot read metadata in dir ".to_string() + current_folder.as_str()); + self.text_messages.warnings.push("Cannot read metadata in dir ".to_string() + current_folder.as_str()); continue; } //Permissions denied }; if metadata.is_dir() { self.information.number_of_checked_folders += 1; // if entry_data.file_name().into_string().is_err() { // Probably this can be removed, if crash still will be happens, then uncomment this line - // self.messages.warnings.push("Cannot read folder name in dir ".to_string() + current_folder.as_str()); + // self.text_messages.warnings.push("Cannot read folder name in dir ".to_string() + current_folder.as_str()); // continue; // Permissions denied // } @@ -422,14 +422,14 @@ impl DuplicateFinder { created_date: match metadata.created() { Ok(t) => t, Err(_) => { - self.messages.warnings.push("Unable to get creation date from file ".to_string() + current_file_name.as_str()); + self.text_messages.warnings.push("Unable to get creation date from file ".to_string() + current_file_name.as_str()); SystemTime::now() } // Permissions Denied }, modified_date: match metadata.modified() { Ok(t) => t, Err(_) => { - self.messages.warnings.push("Unable to get modification date from file ".to_string() + current_file_name.as_str()); + self.text_messages.warnings.push("Unable to get modification date from file ".to_string() + current_file_name.as_str()); SystemTime::now() } // Permissions Denied }, @@ -466,7 +466,7 @@ impl DuplicateFinder { Common::print_time(start_time, SystemTime::now(), "check_files_size".to_string()); } - pub fn save_results_to_file(&mut self, file_name: &str) { + pub fn save_results_to_file(&mut self, file_name: &str) -> bool { let start_time: SystemTime = SystemTime::now(); let file_name: String = match file_name { "" => "results.txt".to_string(), @@ -476,16 +476,16 @@ impl DuplicateFinder { let mut file = match File::create(&file_name) { Ok(t) => t, Err(_) => { - self.messages.errors.push("Failed to create file ".to_string() + file_name.as_str()); - return; + self.text_messages.errors.push("Failed to create file ".to_string() + file_name.as_str()); + return false; } }; match file.write_all(b"Results of searching\n\n") { Ok(_) => (), Err(_) => { - self.messages.errors.push("Failed to save results to file ".to_string() + file_name.as_str()); - return; + self.text_messages.errors.push("Failed to save results to file ".to_string() + file_name.as_str()); + return false; } } @@ -512,35 +512,38 @@ impl DuplicateFinder { file.write_all((file_entry.path.clone() + "\n").as_bytes()).unwrap(); } } - } - if !self.files_with_identical_hashes.is_empty() { - file.write_all(b"-------------------------------------------------Files with same hashes-------------------------------------------------\n").unwrap(); - file.write_all( - ("Found ".to_string() - + self.information.number_of_duplicated_files_by_hash.to_string().as_str() - + " duplicated files which in " - + self.information.number_of_groups_by_hash.to_string().as_str() - + " groups which takes " - + self.information.lost_space_by_hash.file_size(options::BINARY).unwrap().as_str() - + ".\n") - .as_bytes(), - ) - .unwrap(); - for (size, files) in self.files_with_identical_hashes.iter().rev() { - for vector in files { - file.write_all(b"\n---- Size ").unwrap(); - file.write_all(size.file_size(options::BINARY).unwrap().as_bytes()).unwrap(); - file.write_all((" (".to_string() + size.to_string().as_str() + ")").as_bytes()).unwrap(); - file.write_all((" - ".to_string() + vector.len().to_string().as_str() + " files").as_bytes()).unwrap(); - file.write_all(b"\n").unwrap(); - for file_entry in vector { - file.write_all((file_entry.path.clone() + "\n").as_bytes()).unwrap(); + if !self.files_with_identical_hashes.is_empty() { + file.write_all(b"-------------------------------------------------Files with same hashes-------------------------------------------------\n").unwrap(); + file.write_all( + ("Found ".to_string() + + self.information.number_of_duplicated_files_by_hash.to_string().as_str() + + " duplicated files which in " + + self.information.number_of_groups_by_hash.to_string().as_str() + + " groups which takes " + + self.information.lost_space_by_hash.file_size(options::BINARY).unwrap().as_str() + + ".\n") + .as_bytes(), + ) + .unwrap(); + for (size, files) in self.files_with_identical_hashes.iter().rev() { + for vector in files { + file.write_all(b"\n---- Size ").unwrap(); + file.write_all(size.file_size(options::BINARY).unwrap().as_bytes()).unwrap(); + file.write_all((" (".to_string() + size.to_string().as_str() + ")").as_bytes()).unwrap(); + file.write_all((" - ".to_string() + vector.len().to_string().as_str() + " files").as_bytes()).unwrap(); + file.write_all(b"\n").unwrap(); + for file_entry in vector { + file.write_all((file_entry.path.clone() + "\n").as_bytes()).unwrap(); + } } } } + } else { + file.write_all(b"Not found any empty folders.").unwrap(); } Common::print_time(start_time, SystemTime::now(), "save_results_to_file".to_string()); + true } /// Should be slower than checking in different ways, but still needs to be checked @@ -556,7 +559,7 @@ impl DuplicateFinder { file_handler = match File::open(&file_entry.1.path) { Ok(t) => t, Err(_) => { - self.messages.warnings.push("Unable to check hash of file ".to_string() + file_entry.1.path.as_str()); + self.text_messages.warnings.push("Unable to check hash of file ".to_string() + file_entry.1.path.as_str()); continue; } }; @@ -569,7 +572,7 @@ impl DuplicateFinder { let n = match file_handler.read(&mut buffer) { Ok(t) => t, Err(_) => { - self.messages.warnings.push("Error happened when checking hash of file ".to_string() + file_entry.1.path.as_str()); + self.text_messages.warnings.push("Error happened when checking hash of file ".to_string() + file_entry.1.path.as_str()); error_reading_file = true; break; } @@ -615,18 +618,28 @@ impl DuplicateFinder { println!("---------------DEBUG PRINT---------------"); println!("### Information's"); - println!("Errors size - {}", self.messages.errors.len()); - println!("Warnings size - {}", self.messages.warnings.len()); - println!("Messages size - {}", self.messages.messages.len()); + println!("Errors size - {}", self.text_messages.errors.len()); + println!("Warnings size - {}", self.text_messages.warnings.len()); + println!("Messages size - {}", self.text_messages.messages.len()); println!("Number of checked files - {}", self.information.number_of_checked_files); println!("Number of checked folders - {}", self.information.number_of_checked_folders); println!("Number of ignored files - {}", self.information.number_of_ignored_files); println!("Number of ignored things(like symbolic links) - {}", self.information.number_of_ignored_things); - println!("Number of duplicated files by size(in groups) - {} ({})", self.information.number_of_duplicated_files_by_size, self.information.number_of_groups_by_size); - println!("Number of duplicated files by hash(in groups) - {} ({})", self.information.number_of_duplicated_files_by_hash, self.information.number_of_groups_by_hash); + println!( + "Number of duplicated files by size(in groups) - {} ({})", + self.information.number_of_duplicated_files_by_size, self.information.number_of_groups_by_size + ); + println!( + "Number of duplicated files by hash(in groups) - {} ({})", + self.information.number_of_duplicated_files_by_hash, self.information.number_of_groups_by_hash + ); println!("Lost space by size - {} ({} bytes)", self.information.lost_space_by_size.file_size(options::BINARY).unwrap(), self.information.lost_space_by_size); println!("Lost space by hash - {} ({} bytes)", self.information.lost_space_by_hash.file_size(options::BINARY).unwrap(), self.information.lost_space_by_hash); - println!("Gained space by removing duplicated entries - {} ({} bytes)", self.information.gained_space.file_size(options::BINARY).unwrap(), self.information.gained_space); + println!( + "Gained space by removing duplicated entries - {} ({} bytes)", + self.information.gained_space.file_size(options::BINARY).unwrap(), + self.information.gained_space + ); println!("Number of removed files - {}", self.information.number_of_removed_files); println!("Number of failed to remove files - {}", self.information.number_of_failed_to_remove_files); @@ -811,7 +824,7 @@ impl DuplicateFinder { // optimized_excluded = Vec::::new(); if self.included_directories.is_empty() { - self.messages.errors.push("Optimize Directories ERROR: Excluded directories overlaps all included directories.".to_string()); + self.text_messages.errors.push("Optimize Directories ERROR: Excluded directories overlaps all included directories.".to_string()); return false; } @@ -829,7 +842,7 @@ impl DuplicateFinder { CheckingMethod::HASH => { for entry in &self.files_with_identical_hashes { for vector in entry.1 { - let tuple: (u64, usize, usize) = delete_files(&vector, &self.delete_method, &mut self.messages.warnings); + let tuple: (u64, usize, usize) = delete_files(&vector, &self.delete_method, &mut self.text_messages.warnings); self.information.gained_space += tuple.0; self.information.number_of_removed_files += tuple.1; self.information.number_of_failed_to_remove_files += tuple.2; @@ -838,7 +851,7 @@ impl DuplicateFinder { } CheckingMethod::SIZE => { for entry in &self.files_with_identical_size { - let tuple: (u64, usize, usize) = delete_files(&entry.1, &self.delete_method, &mut self.messages.warnings); + let tuple: (u64, usize, usize) = delete_files(&entry.1, &self.delete_method, &mut self.text_messages.warnings); self.information.gained_space += tuple.0; self.information.number_of_removed_files += tuple.1; self.information.number_of_failed_to_remove_files += tuple.2; diff --git a/czkawka_core/src/empty_folder.rs b/czkawka_core/src/empty_folder.rs index 14f7c25..c8a20dd 100644 --- a/czkawka_core/src/empty_folder.rs +++ b/czkawka_core/src/empty_folder.rs @@ -1,6 +1,7 @@ use crate::common::{Common, Messages}; use std::collections::HashMap; -use std::fs::Metadata; +use std::fs::{File, Metadata}; +use std::io::Write; use std::path::Path; use std::time::SystemTime; use std::{fs, process}; @@ -22,22 +23,23 @@ struct FolderEntry { /// Struct to store most basics info about all folder pub struct EmptyFolder { - informations: Info, + information: Info, delete_folders: bool, - messages: Messages, - empty_folder_list: HashMap, - excluded_directories: Vec, + text_messages: Messages, + empty_folder_list: HashMap, // Path, FolderEntry included_directories: Vec, } /// Info struck with helpful information's about results pub struct Info { + #[cfg(debug_assertions)] number_of_checked_folders: usize, number_of_empty_folders: usize, } impl Info { pub fn new() -> Info { Info { + #[cfg(debug_assertions)] number_of_checked_folders: 0, number_of_empty_folders: 0, } @@ -54,17 +56,16 @@ impl EmptyFolder { /// New function providing basics values pub fn new() -> EmptyFolder { EmptyFolder { - informations: Default::default(), + information: Default::default(), delete_folders: false, - messages: Default::default(), + text_messages: Default::default(), empty_folder_list: Default::default(), - excluded_directories: vec![], included_directories: vec![], } } - pub fn get_messages(&self) -> &Messages { - &self.messages + pub fn get_text_messages(&self) -> &Messages { + &self.text_messages } /// Public function used by CLI to search for empty folders @@ -83,6 +84,43 @@ impl EmptyFolder { self.delete_folders = delete_folder; } + pub fn save_results_to_file(&mut self, file_name: &str) -> bool { + let start_time: SystemTime = SystemTime::now(); + let file_name: String = match file_name { + "" => "results.txt".to_string(), + k => k.to_string(), + }; + + let mut file = match File::create(&file_name) { + Ok(t) => t, + Err(_) => { + self.text_messages.errors.push("Failed to create file ".to_string() + file_name.as_str()); + return false; + } + }; + + match file.write_all(b"Results of searching\n") { + Ok(_) => (), + Err(_) => { + self.text_messages.errors.push("Failed to save results to file ".to_string() + file_name.as_str()); + return false; + } + } + + if !self.empty_folder_list.is_empty() { + file.write_all(b"-------------------------------------------------Empty folder list-------------------------------------------------\n").unwrap(); + file.write_all(("Found ".to_string() + self.information.number_of_empty_folders.to_string().as_str() + " empty folders which in " + ".\n").as_bytes()) + .unwrap(); + for name in self.empty_folder_list.keys() { + file.write_all((name.clone() + "\n").as_bytes()).unwrap(); + } + } else { + file.write_all(b"Not found any empty folders.").unwrap(); + } + Common::print_time(start_time, SystemTime::now(), "save_results_to_file".to_string()); + true + } + /// Clean directory tree /// If directory contains only 2 empty folders, then this directory should be removed instead two empty folders inside because it will produce another empty folder. fn optimize_folders(&mut self) { @@ -160,25 +198,16 @@ impl EmptyFolder { }; // If child is dir, still folder may be considered as empty if all children are only directories. if metadata.is_dir() { - let mut is_excluded_dir = false; next_folder = "".to_owned() + ¤t_folder + &entry_data.file_name().into_string().unwrap() + "/"; - for ed in &self.excluded_directories { - if next_folder == *ed { - is_excluded_dir = true; - break; - } - } - if !is_excluded_dir { - folders_to_check.push(next_folder.clone()); + folders_to_check.push(next_folder.clone()); - folders_checked.insert( - next_folder.clone(), - FolderEntry { - parent_path: Option::from(current_folder.clone()), - is_empty: FolderEmptiness::Maybe, - }, - ); - } + folders_checked.insert( + next_folder.clone(), + FolderEntry { + parent_path: Option::from(current_folder.clone()), + is_empty: FolderEmptiness::Maybe, + }, + ); } else { // Not folder so it may be a file or symbolic link so it isn't empty folders_checked.get_mut(¤t_folder).unwrap().is_empty = FolderEmptiness::No; @@ -254,9 +283,8 @@ impl EmptyFolder { #[cfg(debug_assertions)] { println!("---------------DEBUG PRINT---------------"); - println!("Number of all checked folders - {}", self.informations.number_of_checked_folders); - println!("Number of empty folders - {}", self.informations.number_of_empty_folders); - println!("Excluded directories - {:?}", self.excluded_directories); + println!("Number of all checked folders - {}", self.information.number_of_checked_folders); + println!("Number of empty folders - {}", self.information.number_of_empty_folders); println!("Included directories - {:?}", self.included_directories); println!("-----------------------------------------"); } @@ -268,34 +296,15 @@ impl EmptyFolder { let start_time: SystemTime = SystemTime::now(); let mut optimized_included: Vec = Vec::::new(); - let mut optimized_excluded: Vec = Vec::::new(); // Remove duplicated entries like: "/", "/" - self.excluded_directories.sort(); self.included_directories.sort(); - self.excluded_directories.dedup(); self.included_directories.dedup(); // Optimize for duplicated included directories - "/", "/home". "/home/Pulpit" to "/" - let mut is_inside: bool; - for ed_checked in &self.excluded_directories { - is_inside = false; - for ed_help in &self.excluded_directories { - if ed_checked == ed_help { - // We checking same element - continue; - } - if ed_checked.starts_with(ed_help) { - is_inside = true; - break; - } - } - if !is_inside { - optimized_excluded.push(ed_checked.to_string()); - } - } + let mut is_inside: bool; for id_checked in &self.included_directories { is_inside = false; for id_help in &self.included_directories { @@ -313,24 +322,6 @@ impl EmptyFolder { } } - self.included_directories = optimized_included; - optimized_included = Vec::::new(); - self.excluded_directories = optimized_excluded; - optimized_excluded = Vec::::new(); - - // Remove include directories which are inside any exclude directory - for id in &self.included_directories { - let mut is_inside: bool = false; - for ed in &self.excluded_directories { - if id.starts_with(ed) { - is_inside = true; - break; - } - } - if !is_inside { - optimized_included.push(id.to_string()); - } - } self.included_directories = optimized_included; optimized_included = Vec::::new(); @@ -342,34 +333,8 @@ impl EmptyFolder { } } - for ed in &self.excluded_directories { - let path = Path::new(ed); - if path.exists() { - optimized_excluded.push(ed.to_string()); - } - } - self.included_directories = optimized_included; - // optimized_included = Vec::::new(); - self.excluded_directories = optimized_excluded; - optimized_excluded = Vec::::new(); - - // Excluded paths must are inside include path, because - for ed in &self.excluded_directories { - let mut is_inside: bool = false; - for id in &self.included_directories { - if ed.starts_with(id) { - is_inside = true; - break; - } - } - if is_inside { - optimized_excluded.push(ed.to_string()); - } - } - - self.excluded_directories = optimized_excluded; - // optimized_excluded = Vec::::new(); + //optimized_included = Vec::::new(); if self.included_directories.is_empty() { println!("Optimize Directories ERROR: Excluded directories overlaps all included directories."); @@ -377,7 +342,6 @@ impl EmptyFolder { } // Not needed, but better is to have sorted everything - self.excluded_directories.sort(); self.included_directories.sort(); Common::print_time(start_time, SystemTime::now(), "optimize_directories".to_string()); } @@ -441,59 +405,6 @@ impl EmptyFolder { 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(); - if exclude_directory.is_empty() { - return; - } - - exclude_directory = exclude_directory.replace("\"", ""); - let directories: Vec = exclude_directory.split(',').map(String::from).collect(); - let mut checked_directories: Vec = Vec::new(); - - for directory in directories { - let directory: String = directory.trim().to_string(); - - if directory == "" { - continue; - } - if directory == "/" { - println!("Exclude Directory ERROR: Excluding / is pointless, because it means that no files will be scanned."); - break; - } - if directory.contains('*') { - println!("Exclude Directory ERROR: Wildcards are not supported, ignoring path {}.", directory); - continue; - } - if directory.starts_with('~') { - println!("Exclude Directory ERROR: ~ in path isn't supported, ignoring path {}.", directory); - continue; - } - if !directory.starts_with('/') { - println!("Exclude Directory ERROR: Relative path are not supported, ignoring path {}.", directory); - continue; - } - if !Path::new(&directory).exists() { - println!("Exclude Directory ERROR: Path {} doesn't exists.", directory); - continue; - } - if !Path::new(&directory).is_dir() { - println!("Exclude Directory ERROR: {} isn't folder.", directory); - continue; - } - - // directory must end with /, due to possiblity of incorrect assumption, that e.g. /home/rafal is top folder to /home/rafalinho - if !directory.ends_with('/') { - checked_directories.push(directory.trim().to_string() + "/"); - } else { - checked_directories.push(directory.trim().to_string()); - } - } - self.excluded_directories = checked_directories; - - Common::print_time(start_time, SystemTime::now(), "set_exclude_directory".to_string()); - } } impl Default for EmptyFolder { fn default() -> Self {