Add missing options in some modes (#90)
This commit is contained in:
parent
4429df2861
commit
8ba780ded6
|
@ -29,6 +29,10 @@ pub enum Commands {
|
|||
EmptyFolders {
|
||||
#[structopt(flatten)]
|
||||
directories: Directories,
|
||||
#[structopt(flatten)]
|
||||
excluded_directories: ExcludedDirectories,
|
||||
#[structopt(flatten)]
|
||||
excluded_items: ExcludedItems,
|
||||
#[structopt(short = "D", long, help = "Delete found folders")]
|
||||
delete_folders: bool,
|
||||
#[structopt(flatten)]
|
||||
|
@ -46,6 +50,8 @@ pub enum Commands {
|
|||
allowed_extensions: AllowedExtensions,
|
||||
#[structopt(short, long, default_value = "50", help = "Number of files to be shown")]
|
||||
number_of_files: usize,
|
||||
#[structopt(short = "D", long, help = "Delete found files")]
|
||||
delete_files: bool,
|
||||
#[structopt(flatten)]
|
||||
file_to_save: FileToSave,
|
||||
#[structopt(flatten)]
|
||||
|
|
|
@ -6,7 +6,7 @@ use commands::Commands;
|
|||
use czkawka_core::common_traits::*;
|
||||
|
||||
use czkawka_core::{
|
||||
big_file::BigFile,
|
||||
big_file::{self, BigFile},
|
||||
duplicate::DuplicateFinder,
|
||||
empty_files::{self, EmptyFiles},
|
||||
empty_folder::EmptyFolder,
|
||||
|
@ -64,10 +64,18 @@ fn main() {
|
|||
df.print_results();
|
||||
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();
|
||||
|
||||
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.find_empty_folders(None);
|
||||
|
@ -91,6 +99,7 @@ fn main() {
|
|||
number_of_files,
|
||||
file_to_save,
|
||||
not_recursive,
|
||||
delete_files,
|
||||
} => {
|
||||
let mut bf = BigFile::new();
|
||||
|
||||
|
@ -100,6 +109,9 @@ fn main() {
|
|||
bf.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
|
||||
bf.set_number_of_files_to_check(number_of_files);
|
||||
bf.set_recursive_search(!not_recursive.not_recursive);
|
||||
if delete_files {
|
||||
bf.set_delete_method(big_file::DeleteMethod::Delete);
|
||||
}
|
||||
|
||||
bf.find_big_files(None);
|
||||
|
||||
|
|
|
@ -21,6 +21,11 @@ pub struct FileEntry {
|
|||
pub modified_date: u64,
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Clone, Debug)]
|
||||
pub enum DeleteMethod {
|
||||
None,
|
||||
Delete,
|
||||
}
|
||||
/// Info struck with helpful information's about results
|
||||
#[derive(Default)]
|
||||
pub struct Info {
|
||||
|
@ -48,6 +53,7 @@ pub struct BigFile {
|
|||
allowed_extensions: Extensions,
|
||||
recursive_search: bool,
|
||||
number_of_files_to_check: usize,
|
||||
delete_method: DeleteMethod,
|
||||
stopped_search: bool,
|
||||
}
|
||||
|
||||
|
@ -62,6 +68,7 @@ impl BigFile {
|
|||
allowed_extensions: Extensions::new(),
|
||||
recursive_search: true,
|
||||
number_of_files_to_check: 50,
|
||||
delete_method: DeleteMethod::None,
|
||||
stopped_search: false,
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +79,7 @@ impl BigFile {
|
|||
self.stopped_search = true;
|
||||
return;
|
||||
}
|
||||
self.delete_files();
|
||||
self.debug_print();
|
||||
}
|
||||
pub fn get_stopped_search(&self) -> bool {
|
||||
|
@ -90,6 +98,10 @@ impl BigFile {
|
|||
&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) {
|
||||
self.recursive_search = recursive_search;
|
||||
}
|
||||
|
@ -248,6 +260,28 @@ impl BigFile {
|
|||
pub fn set_excluded_directory(&mut self, excluded_directory: String) {
|
||||
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 {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::common::Common;
|
||||
use crate::common_directory::Directories;
|
||||
use crate::common_items::ExcludedItems;
|
||||
use crate::common_messages::Messages;
|
||||
use crate::common_traits::{DebugPrint, PrintResults, SaveResults};
|
||||
use crossbeam_channel::Receiver;
|
||||
|
@ -31,6 +32,7 @@ pub struct EmptyFolder {
|
|||
information: Info,
|
||||
delete_folders: bool,
|
||||
text_messages: Messages,
|
||||
excluded_items: ExcludedItems,
|
||||
empty_folder_list: BTreeMap<PathBuf, FolderEntry>, // Path, FolderEntry
|
||||
directories: Directories,
|
||||
stopped_search: bool,
|
||||
|
@ -56,6 +58,7 @@ impl EmptyFolder {
|
|||
information: Default::default(),
|
||||
delete_folders: false,
|
||||
text_messages: Messages::new(),
|
||||
excluded_items: Default::default(),
|
||||
empty_folder_list: Default::default(),
|
||||
directories: Directories::new(),
|
||||
stopped_search: false,
|
||||
|
@ -77,6 +80,13 @@ impl EmptyFolder {
|
|||
&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
|
||||
pub fn find_empty_folders(&mut self, rx: Option<&Receiver<()>>) {
|
||||
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 {
|
||||
Ok(t) => t,
|
||||
Err(_) => continue, //Permissions denied
|
||||
Err(_) => {
|
||||
set_as_not_empty_folder(&mut folders_checked, ¤t_folder);
|
||||
continue 'dir;
|
||||
} //Permissions denied
|
||||
};
|
||||
let metadata: Metadata = match entry_data.metadata() {
|
||||
Ok(t) => t,
|
||||
Err(_) => continue, //Permissions denied
|
||||
Err(_) => {
|
||||
set_as_not_empty_folder(&mut folders_checked, ¤t_folder);
|
||||
continue 'dir;
|
||||
} //Permissions denied
|
||||
};
|
||||
// If child is dir, still folder may be considered as empty if all children are only directories.
|
||||
if metadata.is_dir() {
|
||||
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, ¤t_folder);
|
||||
continue 'dir;
|
||||
}
|
||||
folders_to_check.push(next_folder.clone());
|
||||
folders_checked.insert(
|
||||
next_folder.clone(),
|
||||
|
@ -179,25 +199,15 @@ impl EmptyFolder {
|
|||
},
|
||||
Err(_) => {
|
||||
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, ¤t_folder);
|
||||
continue 'dir;
|
||||
}
|
||||
},
|
||||
},
|
||||
);
|
||||
} 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;
|
||||
let mut d = folders_checked.get_mut(¤t_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;
|
||||
}
|
||||
}
|
||||
set_as_not_empty_folder(&mut folders_checked, ¤t_folder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -233,6 +243,23 @@ impl EmptyFolder {
|
|||
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 {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
|
|
Loading…
Reference in a new issue