Added removing files
This commit is contained in:
parent
10642548f9
commit
0c1550d55e
135
src/duplicate.rs
135
src/duplicate.rs
|
@ -9,7 +9,7 @@ use std::{fs, process};
|
|||
const MIN_FILE_SIZE: u64 = 1000;
|
||||
|
||||
#[derive(PartialEq)]
|
||||
#[allow(dead_code)]
|
||||
#[allow(dead_code)] // For now I only use Hash method
|
||||
pub enum CheckingMethod {
|
||||
SIZE,
|
||||
HASH,
|
||||
|
@ -48,7 +48,7 @@ impl DuplicateFinder {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn find_duplicates(mut self, check_method: CheckingMethod) {
|
||||
pub fn find_duplicates(mut self, check_method: CheckingMethod, delete_files: bool) {
|
||||
self.optimize_directories();
|
||||
self.debug_print();
|
||||
self.check_files_size();
|
||||
|
@ -56,7 +56,10 @@ impl DuplicateFinder {
|
|||
if check_method == CheckingMethod::HASH {
|
||||
self.check_files_hash();
|
||||
}
|
||||
// self.print_duplicated_entries(check_method);
|
||||
self.print_duplicated_entries(&check_method);
|
||||
if delete_files {
|
||||
self.delete_files(&check_method);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_min_file_size(&mut self, min_size: u64) {
|
||||
|
@ -71,33 +74,34 @@ impl DuplicateFinder {
|
|||
if allowed_extensions.is_empty() {
|
||||
println!("No allowed extension was provided, so all are allowed");
|
||||
}
|
||||
allowed_extensions = allowed_extensions.replace("IMAGE","jpg,kra,gif,png,bmp,tiff,webp,hdr,svg");
|
||||
allowed_extensions = allowed_extensions.replace("VIDEO","mp4,flv,mkv,webm,vob,ogv,gifv,avi,mov,wmv,mpg,m4v,m4p,mpeg,3gp");
|
||||
allowed_extensions = allowed_extensions.replace("IMAGE", "jpg,kra,gif,png,bmp,tiff,webp,hdr,svg");
|
||||
allowed_extensions = allowed_extensions.replace("VIDEO", "mp4,flv,mkv,webm,vob,ogv,gifv,avi,mov,wmv,mpg,m4v,m4p,mpeg,3gp");
|
||||
allowed_extensions = allowed_extensions.replace("MUSIC", "mp3,flac,ogg,tta,wma,webm");
|
||||
|
||||
let extensions: Vec<String> = allowed_extensions.split(',').map(String::from).collect();
|
||||
for mut extension in extensions{
|
||||
if extension.contains('.'){
|
||||
if !extension.starts_with('.'){
|
||||
println!("{} is not valid extension(valid extension doesn't have dot inside)",extension);
|
||||
for mut extension in extensions {
|
||||
if extension.contains('.') {
|
||||
if !extension.starts_with('.') {
|
||||
println!("{} is not valid extension(valid extension doesn't have dot inside)", extension);
|
||||
continue;
|
||||
}
|
||||
extension = extension.replace('.',"");
|
||||
extension = extension.replace('.', "");
|
||||
}
|
||||
if !self.allowed_extensions.contains(&extension.trim().to_string()) {
|
||||
self.allowed_extensions.push(extension.trim().to_string());
|
||||
}
|
||||
|
||||
|
||||
self.allowed_extensions.push(extension.trim().to_string());
|
||||
}
|
||||
|
||||
if self.allowed_extensions.len() == 0{
|
||||
println!("{:?}", &self.allowed_extensions);
|
||||
if self.allowed_extensions.is_empty() {
|
||||
println!("No valid extensions were provided, so allowing all extensions by default.");
|
||||
}
|
||||
|
||||
}
|
||||
pub fn set_include_directory(&mut self, mut include_directory: String) {
|
||||
// let start_time: SystemTime = SystemTime::now();
|
||||
|
||||
if include_directory.is_empty() {
|
||||
println!("At least one directory must be provided")
|
||||
println!("At least one directory must be provided");
|
||||
}
|
||||
|
||||
include_directory = include_directory.replace("\"", "");
|
||||
|
@ -247,7 +251,22 @@ impl DuplicateFinder {
|
|||
|
||||
//println!("Directory\t - {:?}", next_folder); // DEBUG
|
||||
} else if metadata.is_file() {
|
||||
if metadata.len() >= MIN_FILE_SIZE {
|
||||
let mut have_valid_extension: bool;
|
||||
let file_name_lowercase: String = entry_data.file_name().into_string().unwrap().to_lowercase();
|
||||
|
||||
if !self.allowed_extensions.is_empty() {
|
||||
have_valid_extension = false;
|
||||
for i in &self.allowed_extensions {
|
||||
if file_name_lowercase.ends_with(&i.to_lowercase()) {
|
||||
have_valid_extension = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
have_valid_extension = true;
|
||||
}
|
||||
|
||||
if metadata.len() >= MIN_FILE_SIZE && have_valid_extension {
|
||||
let current_file_name = "".to_owned() + ¤t_folder + &entry_data.file_name().into_string().unwrap();
|
||||
// println!("File\t\t - {:?}", current_file_name); // DEBUG
|
||||
//file_to_check
|
||||
|
@ -363,33 +382,32 @@ impl DuplicateFinder {
|
|||
|
||||
/// Setting include directories, panics when there is not directories available
|
||||
|
||||
|
||||
fn debug_print(&self) {
|
||||
// println!("---------------DEBUG PRINT---------------");
|
||||
// println!("Number of all checked files - {}", self.number_of_checked_files);
|
||||
// println!("Number of all ignored files - {}", self.number_of_ignored_files);
|
||||
// println!("Number of all checked folders - {}", self.number_of_checked_folders);
|
||||
// println!("Number of all ignored things - {}", self.number_of_ignored_things);
|
||||
// println!("Number of duplicated files - {}", self.number_of_duplicated_files);
|
||||
// let mut file_size : u64 = 0;
|
||||
// for i in &self.files_with_identical_size{
|
||||
// file_size += i.1.len() as u64;
|
||||
// }
|
||||
// println!("Files list size - {} ({})", self.files_with_identical_size.len(), file_size);
|
||||
// let mut hashed_file_size : u64 = 0;
|
||||
// for i in &self.files_with_identical_hashes{
|
||||
// for j in i.1{
|
||||
// hashed_file_size += j.len() as u64;
|
||||
// }
|
||||
// }
|
||||
// println!("Hashed Files list size - {} ({})", self.files_with_identical_hashes.len(), hashed_file_size);
|
||||
// println!("Excluded directories - {:?}", self.excluded_directories);
|
||||
// println!("Included directories - {:?}", self.included_directories);
|
||||
// println!("-----------------------------------------");
|
||||
println!("---------------DEBUG PRINT---------------");
|
||||
println!("Number of all checked files - {}", self.number_of_checked_files);
|
||||
println!("Number of all ignored files - {}", self.number_of_ignored_files);
|
||||
println!("Number of all checked folders - {}", self.number_of_checked_folders);
|
||||
println!("Number of all ignored things - {}", self.number_of_ignored_things);
|
||||
println!("Number of duplicated files - {}", self.number_of_duplicated_files);
|
||||
let mut file_size: u64 = 0;
|
||||
for i in &self.files_with_identical_size {
|
||||
file_size += i.1.len() as u64;
|
||||
}
|
||||
println!("Files list size - {} ({})", self.files_with_identical_size.len(), file_size);
|
||||
let mut hashed_file_size: u64 = 0;
|
||||
for i in &self.files_with_identical_hashes {
|
||||
for j in i.1 {
|
||||
hashed_file_size += j.len() as u64;
|
||||
}
|
||||
}
|
||||
println!("Hashed Files list size - {} ({})", self.files_with_identical_hashes.len(), hashed_file_size);
|
||||
println!("Excluded directories - {:?}", self.excluded_directories);
|
||||
println!("Included directories - {:?}", self.included_directories);
|
||||
println!("-----------------------------------------");
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn print_duplicated_entries(&self, check_method: CheckingMethod) {
|
||||
fn print_duplicated_entries(&self, check_method: &CheckingMethod) {
|
||||
let start_time: SystemTime = SystemTime::now();
|
||||
let mut number_of_files: u64 = 0;
|
||||
let mut number_of_groups: u64 = 0;
|
||||
|
@ -552,6 +570,43 @@ impl DuplicateFinder {
|
|||
self.included_directories.sort();
|
||||
DuplicateFinder::print_time(start_time, SystemTime::now(), "optimize_directories".to_string());
|
||||
}
|
||||
|
||||
fn delete_files(&mut self, check_method: &CheckingMethod) {
|
||||
let start_time: SystemTime = SystemTime::now();
|
||||
let mut errors: Vec<String> = Vec::new();
|
||||
match check_method {
|
||||
CheckingMethod::HASH => {
|
||||
for entry in &self.files_with_identical_hashes {
|
||||
for vector in entry.1 {
|
||||
for files in vector.iter().enumerate() {
|
||||
if files.0 != 0 {
|
||||
match fs::remove_file(&files.1.path) {
|
||||
Ok(_) => (),
|
||||
Err(_) => errors.push(files.1.path.clone()),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CheckingMethod::SIZE => {
|
||||
for entry in &self.files_with_identical_size {
|
||||
for files in entry.1.iter().enumerate() {
|
||||
if files.0 != 0 {
|
||||
match fs::remove_file(&files.1.path) {
|
||||
Ok(_) => (),
|
||||
Err(_) => errors.push(files.1.path.clone()),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for i in errors {
|
||||
println!("Failed to delete {}", i);
|
||||
}
|
||||
DuplicateFinder::print_time(start_time, SystemTime::now(), "delete_files".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
|
|
63
src/main.rs
63
src/main.rs
|
@ -5,47 +5,69 @@ mod duplicate;
|
|||
fn main() {
|
||||
// Parse argument
|
||||
//
|
||||
let arguments: Vec<String> = env::args().collect();
|
||||
println!("Number of arguments - {}", arguments.len());
|
||||
let mut all_arguments: Vec<String> = env::args().collect();
|
||||
let number_of_arguments: usize = all_arguments.len() - 1;
|
||||
let mut arguments: Vec<String> = Vec::new();
|
||||
let mut commands_arguments: Vec<String> = Vec::new();
|
||||
|
||||
all_arguments.remove(0); // Removing program name from arguments
|
||||
|
||||
for argument in all_arguments {
|
||||
if argument.starts_with('-') {
|
||||
commands_arguments.push(argument);
|
||||
} else {
|
||||
arguments.push(argument);
|
||||
}
|
||||
}
|
||||
|
||||
println!("Number of arguments - {}", arguments.len());
|
||||
for (index, argument) in arguments.iter().enumerate() {
|
||||
println!("Argument number {} - {}", index, argument);
|
||||
}
|
||||
if arguments.len() == 1 {
|
||||
if number_of_arguments == 0 {
|
||||
print_help();
|
||||
process::exit(0);
|
||||
}
|
||||
match arguments[1].as_ref() {
|
||||
if commands_arguments.is_empty() {
|
||||
println! {"Missing command, please read help for more info."};
|
||||
process::exit(0);
|
||||
}
|
||||
match commands_arguments[0].as_ref() {
|
||||
"-d" | "-duplicate_finder" => {
|
||||
if arguments.len() != 4 {
|
||||
println!("FATAL ERROR: Duplicate Finder must be executed with exactly 3 arguments");
|
||||
let delete_files: bool = commands_arguments.contains(&"-delete".to_owned());
|
||||
|
||||
if arguments.len() < 2 {
|
||||
println!("FATAL ERROR: Duplicate Finder must be executed with at least 1 argument");
|
||||
process::exit(1);
|
||||
}
|
||||
|
||||
let mut df = duplicate::DuplicateFinder::new();
|
||||
df.set_include_directory(arguments[2].clone());
|
||||
df.set_include_directory(arguments[0].clone());
|
||||
|
||||
if arguments.len() > 3 {
|
||||
df.set_exclude_directory(arguments[3].clone());
|
||||
if arguments.len() > 1 {
|
||||
df.set_exclude_directory(arguments[1].clone());
|
||||
}
|
||||
if arguments.len() > 4 {
|
||||
let min_size = match arguments[4].parse::<u64>() {
|
||||
if arguments.len() > 2 {
|
||||
let min_size = match arguments[2].parse::<u64>() {
|
||||
Ok(t) => t,
|
||||
Err(_) => {
|
||||
println!("FATAL ERROR: Cannot parse \"{}\" to u64", arguments[4]);
|
||||
println!("FATAL ERROR: \"{}\" is not valid file size(allowed range <0,u64::max>)", arguments[2]);
|
||||
process::exit(1);
|
||||
}
|
||||
};
|
||||
df.set_min_file_size(min_size);
|
||||
}
|
||||
if arguments.len() > 5 {
|
||||
df.set_allowed_extensions(arguments[5].clone());
|
||||
if arguments.len() > 3 {
|
||||
df.set_allowed_extensions(arguments[3].clone());
|
||||
}
|
||||
if arguments.len() > 6 {
|
||||
df.set_excluded_items(arguments[6].clone());
|
||||
if arguments.len() > 4 {
|
||||
df.set_excluded_items(arguments[4].clone());
|
||||
}
|
||||
|
||||
df.find_duplicates(duplicate::CheckingMethod::SIZE);
|
||||
df.find_duplicates(duplicate::CheckingMethod::SIZE, delete_files);
|
||||
}
|
||||
"-h" | "-help" => {
|
||||
print_help();
|
||||
}
|
||||
argum => println!("\"{}\" argument is not supported, check help for more info.", argum),
|
||||
};
|
||||
|
@ -54,10 +76,13 @@ fn main() {
|
|||
fn print_help() {
|
||||
println!();
|
||||
println!("Usage of Czkawka:");
|
||||
println!("# Arguments:");
|
||||
println!("czkawka <option> <>");
|
||||
println!("# Main arguments:");
|
||||
println!(" -h - prints help, also works without any arguments");
|
||||
println!(" -help");
|
||||
println!(" -d \"include,include2\" \"exclude,exclude2\" [--delete] - search for duplicate files in `include` directories separated by comma inside qutes and exclue selected files from search");
|
||||
println!(" -d <directory_to_search> [exclude_directories = \"\"] [min_size = 10] [allowed_extension = \"\"] [-delete] - search for duplicate files in choosen directories, minimum size(in bytes) and allowed extensions and avaibility to delete duplicates.");
|
||||
println!(" -duplicate_finder");
|
||||
println!(" e.g.");
|
||||
println!(" czkawka -d \"/home/rafal/,/home/szczekacz\" \"/home/rafal/Pulpit,/home/rafal/Obrazy\" 25 \"7z,rar,IMAGE\" -delete");
|
||||
println!();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue