2020-08-27 06:49:43 +12:00
use std ::{ env , process } ;
mod duplicate ;
2020-08-26 21:17:16 +12:00
fn main ( ) {
2020-08-27 06:49:43 +12:00
// Parse argument
2020-08-30 05:11:55 +12:00
let mut all_arguments : Vec < String > = env ::args ( ) . collect ( ) ;
let mut commands_arguments : Vec < String > = Vec ::new ( ) ;
all_arguments . remove ( 0 ) ; // Removing program name from arguments
2020-08-27 06:49:43 +12:00
2020-08-31 00:00:22 +12:00
// No arguments, so we print help to allow user to learn more about program
if all_arguments . is_empty ( ) {
print_help ( ) ;
process ::exit ( 0 ) ;
}
// Assigning commands with arguments
let mut arguments : Vec < ArgumentsPair > = Vec ::new ( ) ;
let mut can_pass_argument : bool = false ;
for argument in 0 .. all_arguments . len ( ) {
if all_arguments [ argument ] . starts_with ( " -- " ) {
commands_arguments . push ( all_arguments [ argument ] . clone ( ) ) ;
} else if all_arguments [ argument ] . starts_with ( '-' ) {
if argument + 1 < all_arguments . len ( ) {
if all_arguments [ argument + 1 ] . starts_with ( " -- " ) | | all_arguments [ argument + 1 ] . starts_with ( '-' ) {
println! ( " FATAL ERROR: Missing argument for {} " , all_arguments [ argument ] ) ;
process ::exit ( 1 ) ;
} else {
let a : ArgumentsPair = ArgumentsPair {
command : all_arguments [ argument ] . clone ( ) ,
argument : all_arguments [ argument + 1 ] . clone ( ) ,
} ;
arguments . push ( a ) ;
can_pass_argument = true ;
}
} else {
println! ( " FATAL ERROR: Missing argument for {} " , all_arguments [ argument ] ) ;
process ::exit ( 1 ) ;
}
2020-08-30 05:11:55 +12:00
} else {
2020-08-31 00:00:22 +12:00
if ! can_pass_argument {
println! ( " FATAL ERROR: Argument \" {} \" is not linked to any command " , all_arguments [ argument ] ) ;
process ::exit ( 1 ) ;
} else {
can_pass_argument = false ;
}
2020-08-30 05:11:55 +12:00
}
}
2020-08-31 00:00:22 +12:00
for a in & arguments {
println! ( " Argument number {} - {} " , a . command , a . argument ) ;
2020-08-27 06:49:43 +12:00
}
2020-08-31 00:00:22 +12:00
2020-08-30 05:11:55 +12:00
if commands_arguments . is_empty ( ) {
2020-08-31 00:00:22 +12:00
println! { " FATAL ERROR: Missing type of app which you want to run, please read help for more info. " } ;
2020-08-30 05:11:55 +12:00
process ::exit ( 0 ) ;
}
match commands_arguments [ 0 ] . as_ref ( ) {
2020-08-31 00:00:22 +12:00
" --d " = > {
let mut df = duplicate ::DuplicateFinder ::new ( ) ;
2020-08-30 05:11:55 +12:00
2020-08-31 00:00:22 +12:00
if ArgumentsPair ::has_command ( & arguments , " -i " ) {
df . set_include_directory ( ArgumentsPair ::get_argument ( & arguments , " -i " ) ) ;
} else {
println! ( " FATAL ERROR: Parameter -i with set of included files is required. " ) ;
2020-08-27 06:49:43 +12:00
process ::exit ( 1 ) ;
}
2020-08-31 00:00:22 +12:00
if ArgumentsPair ::has_command ( & arguments , " -e " ) {
df . set_exclude_directory ( ArgumentsPair ::get_argument ( & arguments , " -e " ) ) ;
2020-08-30 02:12:20 +12:00
}
2020-08-31 00:00:22 +12:00
if ArgumentsPair ::has_command ( & arguments , " -s " ) {
let min_size = match ArgumentsPair ::get_argument ( & arguments , " -s " ) . parse ::< u64 > ( ) {
2020-08-30 02:12:20 +12:00
Ok ( t ) = > t ,
Err ( _ ) = > {
2020-08-31 00:00:22 +12:00
println! ( " FATAL ERROR: \" {} \" is not valid file size(allowed range <0,u64::max>) " , ArgumentsPair ::get_argument ( & arguments , " -s " ) ) ;
2020-08-30 02:12:20 +12:00
process ::exit ( 1 ) ;
}
} ;
df . set_min_file_size ( min_size ) ;
}
2020-08-31 00:00:22 +12:00
if ArgumentsPair ::has_command ( & arguments , " -x " ) {
df . set_allowed_extensions ( ArgumentsPair ::get_argument ( & arguments , " -x " ) ) ;
2020-08-30 02:12:20 +12:00
}
2020-08-31 00:00:22 +12:00
if ArgumentsPair ::has_command ( & arguments , " -k " ) {
df . set_excluded_items ( ArgumentsPair ::get_argument ( & arguments , " -k " ) ) ;
}
if ArgumentsPair ::has_command ( & arguments , " -l " ) {
let check_method : duplicate ::CheckingMethod ;
if ArgumentsPair ::get_argument ( & arguments , " -l " ) . to_lowercase ( ) = = " size " {
check_method = duplicate ::CheckingMethod ::SIZE ;
} else if ArgumentsPair ::get_argument ( & arguments , " -l " ) . to_lowercase ( ) = = " hash " {
check_method = duplicate ::CheckingMethod ::HASH ;
} else {
println! ( " -l can only have values hash or size " ) ;
process ::exit ( 1 ) ;
}
df . find_duplicates ( check_method , ArgumentsPair ::has_command ( & arguments , " --delete " ) ) ;
2020-08-30 02:12:20 +12:00
}
2020-08-30 05:11:55 +12:00
}
2020-08-31 00:00:22 +12:00
" --h " | " --help " = > {
2020-08-30 05:11:55 +12:00
print_help ( ) ;
2020-08-27 06:49:43 +12:00
}
2020-08-31 00:00:22 +12:00
argum = > {
println! ( " FATAL ERROR: \" {} \" argument is not supported, check help for more info. " , argum ) ;
process ::exit ( 1 ) ;
}
2020-08-27 06:49:43 +12:00
} ;
}
fn print_help ( ) {
println! ( ) ;
println! ( " Usage of Czkawka: " ) ;
2020-08-30 05:11:55 +12:00
println! ( " czkawka <option> <> " ) ;
println! ( " # Main arguments: " ) ;
2020-08-31 00:00:22 +12:00
println! ( " --h / --help - prints help, also works without any arguments " ) ;
println! ( " Usage example: " ) ;
println! ( " czkawka --help " ) ;
println! ( " czkawka " ) ;
println! ( " --d - <-i directory_to_search> [-e exclude_directories = \" \" ] [-s min_size = 1024] [-x allowed_extension = \" \" ] [-l type_of_search = \" hash \" ] [--delete] - search for duplicates files " ) ;
println! ( " -i directory_to_search - list of directories which should will be searched like /home/rafal " ) ;
println! ( " -e exclude_directories - list of directories which will be excluded from search. " ) ;
println! ( " -s min_size - minimum size of checked files in bytes, assigning bigger value may speed up searching. " ) ;
println! ( " -x allowed_extension - list of checked extension, e.g. \" jpg,mp4 \" will allow to check \" book.jpg \" and \" car.mp4 \" but not roman.png.There are also helpful macros which allow to easy use a typcal extension like IMAGE( \" jpg,kra,gif,png,bmp,tiff,webp,hdr,svg \" ) or TEXT( \" txt,doc,docx,odt,rtf \" ) " ) ;
println! ( " -k type_of_search - allows to use fastest which takes into account only size, and more accurate which check if file contnet is same(hashes). " ) ;
println! ( " --delete - removing file except one. " ) ;
println! ( " Usage example: " ) ;
println! ( " czkawka --d -i \" /home/rafal/,/home/szczekacz \" -e \" /home/rafal/Pulpit,/home/rafal/Obrazy \" -s 25 -x \" 7z,rar,IMAGE \" -k \" size \" --delete " ) ;
println! ( " czkawka --d -i \" /etc/,/mnt/Miecz \" -s 1000 -x \" VIDEO \" -k \" hash \" " ) ;
println! ( " czkawka --d -i \" /etc/ \" --delete " ) ;
println! ( " --e " ) ;
2020-08-27 06:49:43 +12:00
println! ( ) ;
2020-08-26 21:17:16 +12:00
}
2020-08-31 00:00:22 +12:00
struct ArgumentsPair {
command : String ,
argument : String ,
}
impl ArgumentsPair {
pub fn has_command ( ar : & [ ArgumentsPair ] , command : & str ) -> bool {
for a in ar {
if a . command = = command {
return true ;
}
}
false
}
pub fn get_argument ( ar : & [ ArgumentsPair ] , command : & str ) -> String {
for a in ar {
if a . command = = command {
return a . argument . clone ( ) ;
}
}
panic! ( " FATAL ERROR: Get argument should always return value " ) ;
}
}