1
0
Fork 0
mirror of synced 2024-05-06 21:42:42 +12:00

Add missing options in some modes (#90)

This commit is contained in:
Rafał Mikrut 2020-10-31 14:19:33 -04:00 committed by GitHub
parent 4429df2861
commit 8ba780ded6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 98 additions and 19 deletions

View file

@ -29,6 +29,10 @@ pub enum Commands {
EmptyFolders { EmptyFolders {
#[structopt(flatten)] #[structopt(flatten)]
directories: Directories, directories: Directories,
#[structopt(flatten)]
excluded_directories: ExcludedDirectories,
#[structopt(flatten)]
excluded_items: ExcludedItems,
#[structopt(short = "D", long, help = "Delete found folders")] #[structopt(short = "D", long, help = "Delete found folders")]
delete_folders: bool, delete_folders: bool,
#[structopt(flatten)] #[structopt(flatten)]
@ -46,6 +50,8 @@ pub enum Commands {
allowed_extensions: AllowedExtensions, allowed_extensions: AllowedExtensions,
#[structopt(short, long, default_value = "50", help = "Number of files to be shown")] #[structopt(short, long, default_value = "50", help = "Number of files to be shown")]
number_of_files: usize, number_of_files: usize,
#[structopt(short = "D", long, help = "Delete found files")]
delete_files: bool,
#[structopt(flatten)] #[structopt(flatten)]
file_to_save: FileToSave, file_to_save: FileToSave,
#[structopt(flatten)] #[structopt(flatten)]

View file

@ -6,7 +6,7 @@ use commands::Commands;
use czkawka_core::common_traits::*; use czkawka_core::common_traits::*;
use czkawka_core::{ use czkawka_core::{
big_file::BigFile, big_file::{self, BigFile},
duplicate::DuplicateFinder, duplicate::DuplicateFinder,
empty_files::{self, EmptyFiles}, empty_files::{self, EmptyFiles},
empty_folder::EmptyFolder, empty_folder::EmptyFolder,
@ -64,10 +64,18 @@ fn main() {
df.print_results(); df.print_results();
df.get_text_messages().print_messages(); df.get_text_messages().print_messages();
} }
Commands::EmptyFolders { directories, delete_folders, file_to_save } => { Commands::EmptyFolders {
directories,
delete_folders,
file_to_save,
excluded_directories,
excluded_items,
} => {
let mut ef = EmptyFolder::new(); let mut ef = EmptyFolder::new();
ef.set_included_directory(path_list_to_str(directories.directories)); ef.set_included_directory(path_list_to_str(directories.directories));
ef.set_excluded_directory(path_list_to_str(excluded_directories.excluded_directories));
ef.set_excluded_items(path_list_to_str(excluded_items.excluded_items));
ef.set_delete_folder(delete_folders); ef.set_delete_folder(delete_folders);
ef.find_empty_folders(None); ef.find_empty_folders(None);
@ -91,6 +99,7 @@ fn main() {
number_of_files, number_of_files,
file_to_save, file_to_save,
not_recursive, not_recursive,
delete_files,
} => { } => {
let mut bf = BigFile::new(); let mut bf = BigFile::new();
@ -100,6 +109,9 @@ fn main() {
bf.set_allowed_extensions(allowed_extensions.allowed_extensions.join(",")); bf.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
bf.set_number_of_files_to_check(number_of_files); bf.set_number_of_files_to_check(number_of_files);
bf.set_recursive_search(!not_recursive.not_recursive); bf.set_recursive_search(!not_recursive.not_recursive);
if delete_files {
bf.set_delete_method(big_file::DeleteMethod::Delete);
}
bf.find_big_files(None); bf.find_big_files(None);

View file

@ -21,6 +21,11 @@ pub struct FileEntry {
pub modified_date: u64, pub modified_date: u64,
} }
#[derive(Eq, PartialEq, Clone, Debug)]
pub enum DeleteMethod {
None,
Delete,
}
/// Info struck with helpful information's about results /// Info struck with helpful information's about results
#[derive(Default)] #[derive(Default)]
pub struct Info { pub struct Info {
@ -48,6 +53,7 @@ pub struct BigFile {
allowed_extensions: Extensions, allowed_extensions: Extensions,
recursive_search: bool, recursive_search: bool,
number_of_files_to_check: usize, number_of_files_to_check: usize,
delete_method: DeleteMethod,
stopped_search: bool, stopped_search: bool,
} }
@ -62,6 +68,7 @@ impl BigFile {
allowed_extensions: Extensions::new(), allowed_extensions: Extensions::new(),
recursive_search: true, recursive_search: true,
number_of_files_to_check: 50, number_of_files_to_check: 50,
delete_method: DeleteMethod::None,
stopped_search: false, stopped_search: false,
} }
} }
@ -72,6 +79,7 @@ impl BigFile {
self.stopped_search = true; self.stopped_search = true;
return; return;
} }
self.delete_files();
self.debug_print(); self.debug_print();
} }
pub fn get_stopped_search(&self) -> bool { pub fn get_stopped_search(&self) -> bool {
@ -90,6 +98,10 @@ impl BigFile {
&self.information &self.information
} }
pub fn set_delete_method(&mut self, delete_method: DeleteMethod) {
self.delete_method = delete_method;
}
pub fn set_recursive_search(&mut self, recursive_search: bool) { pub fn set_recursive_search(&mut self, recursive_search: bool) {
self.recursive_search = recursive_search; self.recursive_search = recursive_search;
} }
@ -248,6 +260,28 @@ impl BigFile {
pub fn set_excluded_directory(&mut self, excluded_directory: String) { pub fn set_excluded_directory(&mut self, excluded_directory: String) {
self.directories.set_excluded_directory(excluded_directory, &mut self.text_messages); self.directories.set_excluded_directory(excluded_directory, &mut self.text_messages);
} }
/// Function to delete files, from filed Vector
fn delete_files(&mut self) {
let start_time: SystemTime = SystemTime::now();
match self.delete_method {
DeleteMethod::Delete => {
for vec_file_entry in self.big_files.values() {
for file_entry in vec_file_entry {
if fs::remove_file(file_entry.path.clone()).is_err() {
self.text_messages.warnings.push(file_entry.path.display().to_string());
}
}
}
}
DeleteMethod::None => {
//Just do nothing
}
}
Common::print_time(start_time, SystemTime::now(), "delete_files".to_string());
}
} }
impl Default for BigFile { impl Default for BigFile {

View file

@ -1,5 +1,6 @@
use crate::common::Common; use crate::common::Common;
use crate::common_directory::Directories; use crate::common_directory::Directories;
use crate::common_items::ExcludedItems;
use crate::common_messages::Messages; use crate::common_messages::Messages;
use crate::common_traits::{DebugPrint, PrintResults, SaveResults}; use crate::common_traits::{DebugPrint, PrintResults, SaveResults};
use crossbeam_channel::Receiver; use crossbeam_channel::Receiver;
@ -31,6 +32,7 @@ pub struct EmptyFolder {
information: Info, information: Info,
delete_folders: bool, delete_folders: bool,
text_messages: Messages, text_messages: Messages,
excluded_items: ExcludedItems,
empty_folder_list: BTreeMap<PathBuf, FolderEntry>, // Path, FolderEntry empty_folder_list: BTreeMap<PathBuf, FolderEntry>, // Path, FolderEntry
directories: Directories, directories: Directories,
stopped_search: bool, stopped_search: bool,
@ -56,6 +58,7 @@ impl EmptyFolder {
information: Default::default(), information: Default::default(),
delete_folders: false, delete_folders: false,
text_messages: Messages::new(), text_messages: Messages::new(),
excluded_items: Default::default(),
empty_folder_list: Default::default(), empty_folder_list: Default::default(),
directories: Directories::new(), directories: Directories::new(),
stopped_search: false, stopped_search: false,
@ -77,6 +80,13 @@ impl EmptyFolder {
&self.information &self.information
} }
pub fn set_excluded_items(&mut self, excluded_items: String) {
self.excluded_items.set_excluded_items(excluded_items, &mut self.text_messages);
}
pub fn set_excluded_directory(&mut self, excluded_directory: String) {
self.directories.set_excluded_directory(excluded_directory, &mut self.text_messages);
}
/// Public function used by CLI to search for empty folders /// Public function used by CLI to search for empty folders
pub fn find_empty_folders(&mut self, rx: Option<&Receiver<()>>) { pub fn find_empty_folders(&mut self, rx: Option<&Receiver<()>>) {
self.directories.optimize_directories(true, &mut self.text_messages); self.directories.optimize_directories(true, &mut self.text_messages);
@ -151,18 +161,28 @@ impl EmptyFolder {
} }
}; };
for entry in read_dir { 'dir: for entry in read_dir {
let entry_data = match entry { let entry_data = match entry {
Ok(t) => t, Ok(t) => t,
Err(_) => continue, //Permissions denied Err(_) => {
set_as_not_empty_folder(&mut folders_checked, &current_folder);
continue 'dir;
} //Permissions denied
}; };
let metadata: Metadata = match entry_data.metadata() { let metadata: Metadata = match entry_data.metadata() {
Ok(t) => t, Ok(t) => t,
Err(_) => continue, //Permissions denied Err(_) => {
set_as_not_empty_folder(&mut folders_checked, &current_folder);
continue 'dir;
} //Permissions denied
}; };
// If child is dir, still folder may be considered as empty if all children are only directories. // If child is dir, still folder may be considered as empty if all children are only directories.
if metadata.is_dir() { if metadata.is_dir() {
let next_folder = current_folder.join(entry_data.file_name()); let next_folder = current_folder.join(entry_data.file_name());
if self.excluded_items.is_excluded(&next_folder) || self.directories.is_excluded(&next_folder) {
set_as_not_empty_folder(&mut folders_checked, &current_folder);
continue 'dir;
}
folders_to_check.push(next_folder.clone()); folders_to_check.push(next_folder.clone());
folders_checked.insert( folders_checked.insert(
next_folder.clone(), next_folder.clone(),
@ -179,25 +199,15 @@ impl EmptyFolder {
}, },
Err(_) => { Err(_) => {
self.text_messages.warnings.push(format!("Failed to read modification date of folder {}", current_folder.display())); self.text_messages.warnings.push(format!("Failed to read modification date of folder {}", current_folder.display()));
continue; // Can't read data, so assuming that is not empty
set_as_not_empty_folder(&mut folders_checked, &current_folder);
continue 'dir;
} }
}, },
}, },
); );
} else { } else {
// Not folder so it may be a file or symbolic link so it isn't empty set_as_not_empty_folder(&mut folders_checked, &current_folder)
folders_checked.get_mut(&current_folder).unwrap().is_empty = FolderEmptiness::No;
let mut d = folders_checked.get_mut(&current_folder).unwrap();
// Loop to recursively set as non empty this and all his parent folders
loop {
d.is_empty = FolderEmptiness::No;
if d.parent_path != None {
let cf = d.parent_path.clone().unwrap();
d = folders_checked.get_mut(&cf).unwrap();
} else {
break;
}
}
} }
} }
} }
@ -233,6 +243,23 @@ impl EmptyFolder {
self.directories.set_included_directory(included_directory, &mut self.text_messages); self.directories.set_included_directory(included_directory, &mut self.text_messages);
} }
} }
fn set_as_not_empty_folder(folders_checked: &mut BTreeMap<PathBuf, FolderEntry>, current_folder: &PathBuf) {
// Not folder so it may be a file or symbolic link so it isn't empty
folders_checked.get_mut(current_folder).unwrap().is_empty = FolderEmptiness::No;
let mut d = folders_checked.get_mut(current_folder).unwrap();
// Loop to recursively set as non empty this and all his parent folders
loop {
d.is_empty = FolderEmptiness::No;
if d.parent_path != None {
let cf = d.parent_path.clone().unwrap();
d = folders_checked.get_mut(&cf).unwrap();
} else {
break;
}
}
}
impl Default for EmptyFolder { impl Default for EmptyFolder {
fn default() -> Self { fn default() -> Self {
Self::new() Self::new()