1
0
Fork 0
mirror of synced 2024-04-28 09:33:30 +12:00

Update to clap 4 (#878)

This commit is contained in:
Alex 2022-12-20 04:19:30 -05:00 committed by GitHub
parent b27a95e547
commit e6b19270a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 1028 additions and 730 deletions

107
Cargo.lock generated
View file

@ -93,17 +93,6 @@ version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "audio_checker"
version = "0.1.0"
@ -347,26 +336,24 @@ dependencies = [
[[package]]
name = "clap"
version = "3.2.23"
version = "4.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d"
dependencies = [
"atty",
"bitflags",
"clap_derive",
"clap_lex",
"indexmap",
"is-terminal",
"once_cell",
"strsim",
"termcolor",
"textwrap",
]
[[package]]
name = "clap_derive"
version = "3.2.18"
version = "4.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65"
checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014"
dependencies = [
"heck",
"proc-macro-error",
@ -377,9 +364,9 @@ dependencies = [
[[package]]
name = "clap_lex"
version = "0.2.4"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
dependencies = [
"os_str_bytes",
]
@ -721,6 +708,27 @@ dependencies = [
"syn",
]
[[package]]
name = "errno"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
dependencies = [
"errno-dragonfly",
"libc",
"winapi",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "exr"
version = "1.5.2"
@ -1324,6 +1332,15 @@ dependencies = [
"libc",
]
[[package]]
name = "hermit-abi"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
dependencies = [
"libc",
]
[[package]]
name = "hmac"
version = "0.12.1"
@ -1553,6 +1570,28 @@ dependencies = [
"unic-langid",
]
[[package]]
name = "io-lifetimes"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "is-terminal"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330"
dependencies = [
"hermit-abi 0.2.6",
"io-lifetimes",
"rustix",
"windows-sys",
]
[[package]]
name = "itertools"
version = "0.10.5"
@ -1650,6 +1689,12 @@ version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "linux-raw-sys"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
[[package]]
name = "locale_config"
version = "0.3.0"
@ -1880,7 +1925,7 @@ version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
dependencies = [
"hermit-abi",
"hermit-abi 0.1.19",
"libc",
]
@ -2447,6 +2492,20 @@ dependencies = [
"version_check",
]
[[package]]
name = "rustix"
version = "0.36.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588"
dependencies = [
"bitflags",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "rustversion"
version = "1.0.9"
@ -2910,12 +2969,6 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
[[package]]
name = "thiserror"
version = "1.0.37"

View file

@ -10,7 +10,7 @@ homepage = "https://github.com/qarmin/czkawka"
repository = "https://github.com/qarmin/czkawka"
[dependencies]
clap = { version = "3.2.23", features = ["derive"] }
clap = { version = "4.0.29", features = ["derive"] }
# For enum types
image_hasher = "1.1.2"

View file

@ -8,269 +8,469 @@ use czkawka_core::same_music::MusicSimilarity;
use czkawka_core::similar_images::SimilarityPreset;
use czkawka_core::CZKAWKA_VERSION;
#[derive(Debug, clap::StructOpt)]
#[clap(name = "czkawka", help_message = HELP_MESSAGE, template = HELP_TEMPLATE, version = CZKAWKA_VERSION)]
pub enum Commands {
#[clap(name = "dup", about = "Finds duplicate files", help_message = HELP_MESSAGE, after_help = "EXAMPLE:\n czkawka dup -d /home/rafal -e /home/rafal/Obrazy -m 25 -x 7z rar IMAGE -s hash -f results.txt -D aeo")]
Duplicates {
#[clap(flatten)]
directories: Directories,
#[clap(flatten)]
excluded_directories: ExcludedDirectories,
#[clap(flatten)]
excluded_items: ExcludedItems,
#[clap(short, long, parse(try_from_str = parse_minimal_file_size), default_value = "8192", help = "Minimum size in bytes", long_help = "Minimum size of checked files in bytes, assigning bigger value may speed up searching")]
minimal_file_size: u64,
#[clap(short = 'i', long, parse(try_from_str = parse_maximal_file_size), default_value = "18446744073709551615", help = "Maximum size in bytes", long_help = "Maximum size of checked files in bytes, assigning lower value may speed up searching")]
maximal_file_size: u64,
#[clap(short = 'c', long, parse(try_from_str = parse_minimal_file_size), default_value = "257144", help = "Minimum cached file size in bytes", long_help = "Minimum size of cached files in bytes, assigning bigger value may speed up the scan but loading the cache will be slower, assigning smaller value may slow down the scan and some files may need to be hashed again but loading the cache will be faster")]
minimal_cached_file_size: u64,
#[clap(flatten)]
allowed_extensions: AllowedExtensions,
#[clap(short, long, default_value = "HASH", parse(try_from_str = parse_checking_method), help = "Search method (NAME, SIZE, HASH)", long_help = "Methods to search files.\nNAME - Fast but but rarely usable,\nSIZE - Fast but not accurate, checking by the file's size,\nHASH - The slowest method, checking by the hash of the entire file")]
search_method: CheckingMethod,
#[clap(short = 'D', long, default_value = "NONE", parse(try_from_str = parse_delete_method), help = "Delete method (AEN, AEO, ON, OO, HARD)", long_help = "Methods to delete the files.\nAEN - All files except the newest,\nAEO - All files except the oldest,\nON - Only 1 file, the newest,\nOO - Only 1 file, the oldest\nHARD - create hard link\nNONE - not delete files")]
delete_method: DeleteMethod,
#[clap(short = 't', long, default_value = "BLAKE3", parse(try_from_str = parse_hash_type), help = "Hash type (BLAKE3, CRC32, XXH3)")]
hash_type: HashType,
#[clap(flatten)]
file_to_save: FileToSave,
#[clap(flatten)]
not_recursive: NotRecursive,
#[clap(flatten)]
case_sensitive_name_comparison: CaseSensitiveNameComparison,
#[cfg(target_family = "unix")]
#[clap(flatten)]
exclude_other_filesystems: ExcludeOtherFilesystems,
#[clap(flatten)]
allow_hard_links: AllowHardLinks,
#[clap(flatten)]
dryrun: DryRun,
},
#[clap(name = "empty-folders", about = "Finds empty folders", help_message = HELP_MESSAGE, after_help = "EXAMPLE:\n czkawka empty-folders -d /home/rafal/rr /home/gateway -f results.txt")]
EmptyFolders {
#[clap(flatten)]
directories: Directories,
#[clap(flatten)]
excluded_directories: ExcludedDirectories,
#[clap(flatten)]
excluded_items: ExcludedItems,
#[clap(short = 'D', long, help = "Delete found folders")]
delete_folders: bool,
#[clap(flatten)]
file_to_save: FileToSave,
#[cfg(target_family = "unix")]
#[clap(flatten)]
exclude_other_filesystems: ExcludeOtherFilesystems,
},
#[clap(name = "big", about = "Finds big files", help_message = HELP_MESSAGE, after_help = "EXAMPLE:\n czkawka big -d /home/rafal/ /home/piszczal -e /home/rafal/Roman -n 25 -J -x VIDEO -f results.txt")]
BiggestFiles {
#[clap(flatten)]
directories: Directories,
#[clap(flatten)]
excluded_directories: ExcludedDirectories,
#[clap(flatten)]
excluded_items: ExcludedItems,
#[clap(flatten)]
allowed_extensions: AllowedExtensions,
#[clap(short, long, default_value = "50", help = "Number of files to be shown")]
number_of_files: usize,
#[clap(short = 'D', long, help = "Delete found files")]
delete_files: bool,
#[clap(flatten)]
file_to_save: FileToSave,
#[clap(flatten)]
not_recursive: NotRecursive,
#[clap(short = 'J', long, help = "Finds the smallest files instead the biggest")]
smallest_mode: bool,
#[cfg(target_family = "unix")]
#[clap(flatten)]
exclude_other_filesystems: ExcludeOtherFilesystems,
},
#[clap(name = "empty-files", about = "Finds empty files", help_message = HELP_MESSAGE, after_help = "EXAMPLE:\n czkawka empty-files -d /home/rafal /home/szczekacz -e /home/rafal/Pulpit -R -f results.txt")]
EmptyFiles {
#[clap(flatten)]
directories: Directories,
#[clap(flatten)]
excluded_directories: ExcludedDirectories,
#[clap(flatten)]
excluded_items: ExcludedItems,
#[clap(flatten)]
allowed_extensions: AllowedExtensions,
#[clap(short = 'D', long, help = "Delete found files")]
delete_files: bool,
#[clap(flatten)]
file_to_save: FileToSave,
#[clap(flatten)]
not_recursive: NotRecursive,
#[cfg(target_family = "unix")]
#[clap(flatten)]
exclude_other_filesystems: ExcludeOtherFilesystems,
},
#[clap(name = "temp", about = "Finds temporary files", help_message = HELP_MESSAGE, after_help = "EXAMPLE:\n czkawka temp -d /home/rafal/ -E */.git */tmp* *Pulpit -f results.txt -D")]
Temporary {
#[clap(flatten)]
directories: Directories,
#[clap(flatten)]
excluded_directories: ExcludedDirectories,
#[clap(flatten)]
excluded_items: ExcludedItems,
#[clap(short = 'D', long, help = "Delete found files")]
delete_files: bool,
#[clap(flatten)]
file_to_save: FileToSave,
#[clap(flatten)]
not_recursive: NotRecursive,
#[cfg(target_family = "unix")]
#[clap(flatten)]
exclude_other_filesystems: ExcludeOtherFilesystems,
},
#[clap(name = "image", about = "Finds similar images", help_message = HELP_MESSAGE, after_help = "EXAMPLE:\n czkawka image -d /home/rafal/ -E */.git */tmp* *Pulpit -f results.txt")]
SimilarImages {
#[clap(flatten)]
directories: Directories,
#[clap(flatten)]
excluded_directories: ExcludedDirectories,
#[clap(short, long, parse(try_from_str = parse_minimal_file_size), default_value = "16384", help = "Minimum size in bytes", long_help = "Minimum size of checked files in bytes, assigning bigger value may speed up searching")]
minimal_file_size: u64,
#[clap(short = 'i', long, parse(try_from_str = parse_maximal_file_size), default_value = "18446744073709551615", help = "Maximum size in bytes", long_help = "Maximum size of checked files in bytes, assigning lower value may speed up searching")]
maximal_file_size: u64,
#[clap(short, long, default_value = "High", parse(try_from_str = parse_similar_images_similarity), help = "Similairty level (Minimal, VerySmall, Small, Medium, High, VeryHigh, Original)", long_help = "Methods to choose similarity level of images which will be considered as duplicated.")]
similarity_preset: SimilarityPreset,
#[clap(flatten)]
excluded_items: ExcludedItems,
#[clap(flatten)]
file_to_save: FileToSave,
#[clap(flatten)]
not_recursive: NotRecursive,
#[cfg(target_family = "unix")]
#[clap(flatten)]
exclude_other_filesystems: ExcludeOtherFilesystems,
#[clap(short = 'g', long, default_value = "Gradient", parse(try_from_str = parse_similar_hash_algorithm), help = "Hash algorithm (allowed: Mean, Gradient, Blockhash, VertGradient, DoubleGradient)")]
hash_alg: HashAlg,
#[clap(short = 'z', long, default_value = "Nearest", parse(try_from_str = parse_similar_image_filter), help = "Hash algorithm (allowed: Lanczos3, Nearest, Triangle, Faussian, Catmullrom)")]
image_filter: FilterType,
#[clap(short = 'c', long, default_value = "16", parse(try_from_str = parse_image_hash_size), help = "Hash size (allowed: 8, 16, 32, 64)")]
hash_size: u8,
},
#[clap(name = "music", about = "Finds same music by tags", help_message = HELP_MESSAGE, after_help = "EXAMPLE:\n czkawka music -d /home/rafal -f results.txt")]
SameMusic {
#[clap(flatten)]
directories: Directories,
#[clap(flatten)]
excluded_directories: ExcludedDirectories,
#[clap(flatten)]
excluded_items: ExcludedItems,
// #[clap(short = 'D', long, help = "Delete found files")]
// delete_files: bool, TODO
#[clap(short = 'z', long, default_value = "track_title,track_artist", parse(try_from_str = parse_music_duplicate_type), help = "Search method (track_title,track_artist,year,bitrate,genre,length))", long_help = "Sets which rows must be equal to set this files as duplicates(may be mixed, but must be divided by commas).")]
music_similarity: MusicSimilarity,
#[clap(flatten)]
file_to_save: FileToSave,
#[clap(flatten)]
not_recursive: NotRecursive,
#[cfg(target_family = "unix")]
#[clap(flatten)]
exclude_other_filesystems: ExcludeOtherFilesystems,
#[clap(short, long, parse(try_from_str = parse_minimal_file_size), default_value = "8192", help = "Minimum size in bytes", long_help = "Minimum size of checked files in bytes, assigning bigger value may speed up searching")]
minimal_file_size: u64,
#[clap(short = 'i', long, parse(try_from_str = parse_maximal_file_size), default_value = "18446744073709551615", help = "Maximum size in bytes", long_help = "Maximum size of checked files in bytes, assigning lower value may speed up searching")]
maximal_file_size: u64,
},
#[clap(name = "symlinks", about = "Finds invalid symlinks", help_message = HELP_MESSAGE, after_help = "EXAMPLE:\n czkawka symlinks -d /home/kicikici/ /home/szczek -e /home/kicikici/jestempsem -x jpg -f results.txt")]
InvalidSymlinks {
#[clap(flatten)]
directories: Directories,
#[clap(flatten)]
excluded_directories: ExcludedDirectories,
#[clap(flatten)]
excluded_items: ExcludedItems,
#[clap(flatten)]
allowed_extensions: AllowedExtensions,
#[clap(short = 'D', long, help = "Delete found files")]
delete_files: bool,
#[clap(flatten)]
file_to_save: FileToSave,
#[clap(flatten)]
not_recursive: NotRecursive,
#[cfg(target_family = "unix")]
#[clap(flatten)]
exclude_other_filesystems: ExcludeOtherFilesystems,
},
#[clap(name = "broken", about = "Finds broken files", help_message = HELP_MESSAGE, after_help = "EXAMPLE:\n czkawka broken -d /home/kicikici/ /home/szczek -e /home/kicikici/jestempsem -x jpg -f results.txt")]
BrokenFiles {
#[clap(flatten)]
directories: Directories,
#[clap(flatten)]
excluded_directories: ExcludedDirectories,
#[clap(flatten)]
excluded_items: ExcludedItems,
#[clap(flatten)]
allowed_extensions: AllowedExtensions,
#[clap(short = 'D', long, help = "Delete found files")]
delete_files: bool,
#[clap(flatten)]
file_to_save: FileToSave,
#[clap(flatten)]
not_recursive: NotRecursive,
#[cfg(target_family = "unix")]
#[clap(flatten)]
exclude_other_filesystems: ExcludeOtherFilesystems,
},
#[clap(name = "video", about = "Finds similar video files", help_message = HELP_MESSAGE, after_help = "EXAMPLE:\n czkawka videos -d /home/rafal -f results.txt")]
SimilarVideos {
#[clap(flatten)]
directories: Directories,
#[clap(flatten)]
excluded_directories: ExcludedDirectories,
#[clap(flatten)]
excluded_items: ExcludedItems,
// #[clap(short = 'D', long, help = "Delete found files")]
// delete_files: bool, TODO
#[clap(flatten)]
file_to_save: FileToSave,
#[clap(flatten)]
allowed_extensions: AllowedExtensions,
#[clap(flatten)]
not_recursive: NotRecursive,
#[cfg(target_family = "unix")]
#[clap(flatten)]
exclude_other_filesystems: ExcludeOtherFilesystems,
#[clap(short, long, parse(try_from_str = parse_minimal_file_size), default_value = "8192", help = "Minimum size in bytes", long_help = "Minimum size of checked files in bytes, assigning bigger value may speed up searching")]
minimal_file_size: u64,
#[clap(short = 'i', long, parse(try_from_str = parse_maximal_file_size), default_value = "18446744073709551615", help = "Maximum size in bytes", long_help = "Maximum size of checked files in bytes, assigning lower value may speed up searching")]
maximal_file_size: u64,
#[clap(short = 't', long, parse(try_from_str = parse_tolerance), default_value = "10", help = "Video maximum difference (allowed values <0,20>)", long_help = "Maximum difference between video frames, bigger value means that videos can looks more and more different (allowed values <0,20>)")]
tolerance: i32,
},
#[clap(name = "ext", about = "Finds files with invalid extensions", help_message = HELP_MESSAGE, after_help = "EXAMPLE:\n czkawka broken -d /home/czokolada/ -f results.txt")]
BadExtensions {
#[clap(flatten)]
directories: Directories,
#[clap(flatten)]
excluded_directories: ExcludedDirectories,
#[clap(flatten)]
excluded_items: ExcludedItems,
#[clap(flatten)]
allowed_extensions: AllowedExtensions,
#[clap(flatten)]
file_to_save: FileToSave,
#[clap(flatten)]
not_recursive: NotRecursive,
#[cfg(target_family = "unix")]
#[clap(flatten)]
exclude_other_filesystems: ExcludeOtherFilesystems,
},
#[clap(name = "tester", about = "Small utility to test supported speed of ", help_message = HELP_MESSAGE, after_help = "EXAMPLE:\n czkawka tester")]
Tester {},
#[derive(clap::Parser)]
#[clap(
name = "czkawka",
help_template = HELP_TEMPLATE,
version = CZKAWKA_VERSION
)]
pub struct Args {
#[command(subcommand)]
pub command: Commands,
}
#[derive(Debug, clap::StructOpt)]
#[derive(Debug, clap::Subcommand)]
pub enum Commands {
#[clap(
name = "dup",
about = "Finds duplicate files",
after_help = "EXAMPLE:\n czkawka dup -d /home/rafal -e /home/rafal/Obrazy -m 25 -x 7z rar IMAGE -s hash -f results.txt -D aeo"
)]
Duplicates(DuplicatesArgs),
#[clap(
name = "empty-folders",
about = "Finds empty folders",
after_help = "EXAMPLE:\n czkawka empty-folders -d /home/rafal/rr /home/gateway -f results.txt"
)]
EmptyFolders(EmptyFoldersArgs),
#[clap(
name = "big",
about = "Finds big files",
after_help = "EXAMPLE:\n czkawka big -d /home/rafal/ /home/piszczal -e /home/rafal/Roman -n 25 -J -x VIDEO -f results.txt"
)]
BiggestFiles(BiggestFilesArgs),
#[clap(
name = "empty-files",
about = "Finds empty files",
after_help = "EXAMPLE:\n czkawka empty-files -d /home/rafal /home/szczekacz -e /home/rafal/Pulpit -R -f results.txt"
)]
EmptyFiles(EmptyFilesArgs),
#[clap(
name = "temp",
about = "Finds temporary files",
after_help = "EXAMPLE:\n czkawka temp -d /home/rafal/ -E */.git */tmp* *Pulpit -f results.txt -D"
)]
Temporary(TemporaryArgs),
#[clap(
name = "image",
about = "Finds similar images",
after_help = "EXAMPLE:\n czkawka image -d /home/rafal/ -E */.git */tmp* *Pulpit -f results.txt"
)]
SimilarImages(SimilarImagesArgs),
#[clap(name = "music", about = "Finds same music by tags", after_help = "EXAMPLE:\n czkawka music -d /home/rafal -f results.txt")]
SameMusic(SameMusicArgs),
#[clap(
name = "symlinks",
about = "Finds invalid symlinks",
after_help = "EXAMPLE:\n czkawka symlinks -d /home/kicikici/ /home/szczek -e /home/kicikici/jestempsem -x jpg -f results.txt"
)]
InvalidSymlinks(InvalidSymlinksArgs),
#[clap(
name = "broken",
about = "Finds broken files",
after_help = "EXAMPLE:\n czkawka broken -d /home/kicikici/ /home/szczek -e /home/kicikici/jestempsem -x jpg -f results.txt"
)]
BrokenFiles(BrokenFilesArgs),
#[clap(name = "video", about = "Finds similar video files", after_help = "EXAMPLE:\n czkawka videos -d /home/rafal -f results.txt")]
SimilarVideos(SimilarVideosArgs),
#[clap(
name = "ext",
about = "Finds files with invalid extensions",
after_help = "EXAMPLE:\n czkawka broken -d /home/czokolada/ -f results.txt"
)]
BadExtensions(BadExtensionsArgs),
#[clap(name = "tester", about = "Small utility to test supported speed of ", after_help = "EXAMPLE:\n czkawka tester")]
Tester,
}
#[derive(Debug, clap::Args)]
pub struct DuplicatesArgs {
#[clap(flatten)]
pub directories: Directories,
#[clap(flatten)]
pub excluded_directories: ExcludedDirectories,
#[clap(flatten)]
pub excluded_items: ExcludedItems,
#[clap(
short,
long,
value_parser = parse_minimal_file_size,
default_value = "8192",
help = "Minimum size in bytes",
long_help = "Minimum size of checked files in bytes, assigning bigger value may speed up searching"
)]
pub minimal_file_size: u64,
#[clap(
short = 'i',
long,
value_parser = parse_maximal_file_size,
default_value = "18446744073709551615",
help = "Maximum size in bytes",
long_help = "Maximum size of checked files in bytes, assigning lower value may speed up searching"
)]
pub maximal_file_size: u64,
#[clap(
short = 'c',
long,
value_parser = parse_minimal_file_size,
default_value = "257144",
help = "Minimum cached file size in bytes",
long_help = "Minimum size of cached files in bytes, assigning bigger value may speed up the scan but loading the cache will be slower, assigning smaller value may slow down the scan and some files may need to be hashed again but loading the cache will be faster"
)]
pub minimal_cached_file_size: u64,
#[clap(flatten)]
pub allowed_extensions: AllowedExtensions,
#[clap(
short,
long,
default_value = "HASH",
value_parser = parse_checking_method,
help = "Search method (NAME, SIZE, HASH)",
long_help = "Methods to search files.\nNAME - Fast but but rarely usable,\nSIZE - Fast but not accurate, checking by the file's size,\nHASH - The slowest method, checking by the hash of the entire file"
)]
pub search_method: CheckingMethod,
#[clap(
short = 'D',
long,
default_value = "NONE",
value_parser = parse_delete_method,
help = "Delete method (AEN, AEO, ON, OO, HARD)",
long_help = "Methods to delete the files.\nAEN - All files except the newest,\nAEO - All files except the oldest,\nON - Only 1 file, the newest,\nOO - Only 1 file, the oldest\nHARD - create hard link\nNONE - not delete files"
)]
pub delete_method: DeleteMethod,
#[clap(
short = 't',
long,
default_value = "BLAKE3",
value_parser = parse_hash_type,
help = "Hash type (BLAKE3, CRC32, XXH3)"
)]
pub hash_type: HashType,
#[clap(flatten)]
pub file_to_save: FileToSave,
#[clap(flatten)]
pub not_recursive: NotRecursive,
#[clap(flatten)]
pub case_sensitive_name_comparison: CaseSensitiveNameComparison,
#[cfg(target_family = "unix")]
#[clap(flatten)]
pub exclude_other_filesystems: ExcludeOtherFilesystems,
#[clap(flatten)]
pub allow_hard_links: AllowHardLinks,
#[clap(flatten)]
pub dryrun: DryRun,
}
#[derive(Debug, clap::Args)]
pub struct EmptyFoldersArgs {
#[clap(flatten)]
pub directories: Directories,
#[clap(flatten)]
pub excluded_directories: ExcludedDirectories,
#[clap(flatten)]
pub excluded_items: ExcludedItems,
#[clap(short = 'D', long, help = "Delete found folders")]
pub delete_folders: bool,
#[clap(flatten)]
pub file_to_save: FileToSave,
#[cfg(target_family = "unix")]
#[clap(flatten)]
pub exclude_other_filesystems: ExcludeOtherFilesystems,
}
#[derive(Debug, clap::Args)]
pub struct BiggestFilesArgs {
#[clap(flatten)]
pub directories: Directories,
#[clap(flatten)]
pub excluded_directories: ExcludedDirectories,
#[clap(flatten)]
pub excluded_items: ExcludedItems,
#[clap(flatten)]
pub allowed_extensions: AllowedExtensions,
#[clap(short, long, default_value = "50", help = "Number of files to be shown")]
pub number_of_files: usize,
#[clap(short = 'D', long, help = "Delete found files")]
pub delete_files: bool,
#[clap(flatten)]
pub file_to_save: FileToSave,
#[clap(flatten)]
pub not_recursive: NotRecursive,
#[clap(short = 'J', long, help = "Finds the smallest files instead the biggest")]
pub smallest_mode: bool,
#[cfg(target_family = "unix")]
#[clap(flatten)]
pub exclude_other_filesystems: ExcludeOtherFilesystems,
}
#[derive(Debug, clap::Args)]
pub struct EmptyFilesArgs {
#[clap(flatten)]
pub directories: Directories,
#[clap(flatten)]
pub excluded_directories: ExcludedDirectories,
#[clap(flatten)]
pub excluded_items: ExcludedItems,
#[clap(flatten)]
pub allowed_extensions: AllowedExtensions,
#[clap(short = 'D', long, help = "Delete found files")]
pub delete_files: bool,
#[clap(flatten)]
pub file_to_save: FileToSave,
#[clap(flatten)]
pub not_recursive: NotRecursive,
#[cfg(target_family = "unix")]
#[clap(flatten)]
pub exclude_other_filesystems: ExcludeOtherFilesystems,
}
#[derive(Debug, clap::Args)]
pub struct TemporaryArgs {
#[clap(flatten)]
pub directories: Directories,
#[clap(flatten)]
pub excluded_directories: ExcludedDirectories,
#[clap(flatten)]
pub excluded_items: ExcludedItems,
#[clap(short = 'D', long, help = "Delete found files")]
pub delete_files: bool,
#[clap(flatten)]
pub file_to_save: FileToSave,
#[clap(flatten)]
pub not_recursive: NotRecursive,
#[cfg(target_family = "unix")]
#[clap(flatten)]
pub exclude_other_filesystems: ExcludeOtherFilesystems,
}
#[derive(Debug, clap::Args)]
pub struct SimilarImagesArgs {
#[clap(flatten)]
pub directories: Directories,
#[clap(flatten)]
pub excluded_directories: ExcludedDirectories,
#[clap(
short,
long,
value_parser = parse_minimal_file_size,
default_value = "16384",
help = "Minimum size in bytes",
long_help = "Minimum size of checked files in bytes, assigning bigger value may speed up searching"
)]
pub minimal_file_size: u64,
#[clap(
short = 'i',
long,
value_parser = parse_minimal_file_size,
default_value = "18446744073709551615",
help = "Maximum size in bytes",
long_help = "Maximum size of checked files in bytes, assigning lower value may speed up searching"
)]
pub maximal_file_size: u64,
#[clap(
short,
long,
default_value = "High",
value_parser = parse_similar_images_similarity,
help = "Similairty level (Minimal, VerySmall, Small, Medium, High, VeryHigh, Original)",
long_help = "Methods to choose similarity level of images which will be considered as duplicated."
)]
pub similarity_preset: SimilarityPreset,
#[clap(flatten)]
pub excluded_items: ExcludedItems,
#[clap(flatten)]
pub file_to_save: FileToSave,
#[clap(flatten)]
pub not_recursive: NotRecursive,
#[cfg(target_family = "unix")]
#[clap(flatten)]
pub exclude_other_filesystems: ExcludeOtherFilesystems,
#[clap(
short = 'g',
long,
default_value = "Gradient",
value_parser = parse_similar_hash_algorithm,
help = "Hash algorithm (allowed: Mean, Gradient, Blockhash, VertGradient, DoubleGradient)"
)]
pub hash_alg: HashAlg,
#[clap(
short = 'z',
long,
default_value = "Nearest",
value_parser = parse_similar_image_filter,
help = "Hash algorithm (allowed: Lanczos3, Nearest, Triangle, Faussian, Catmullrom)"
)]
pub image_filter: FilterType,
#[clap(
short = 'c',
long,
default_value = "16",
value_parser = parse_image_hash_size,
help = "Hash size (allowed: 8, 16, 32, 64)"
)]
pub hash_size: u8,
}
#[derive(Debug, clap::Args)]
pub struct SameMusicArgs {
#[clap(flatten)]
pub directories: Directories,
#[clap(flatten)]
pub excluded_directories: ExcludedDirectories,
#[clap(flatten)]
pub excluded_items: ExcludedItems,
// #[clap(short = 'D', long, help = "Delete found files")]
// delete_files: bool, TODO
#[clap(
short = 'z',
long,
default_value = "track_title,track_artist",
value_parser = parse_music_duplicate_type,
help = "Search method (track_title,track_artist,year,bitrate,genre,length))",
long_help = "Sets which rows must be equal to set this files as duplicates(may be mixed, but must be divided by commas)."
)]
pub music_similarity: MusicSimilarity,
#[clap(flatten)]
pub file_to_save: FileToSave,
#[clap(flatten)]
pub not_recursive: NotRecursive,
#[cfg(target_family = "unix")]
#[clap(flatten)]
pub exclude_other_filesystems: ExcludeOtherFilesystems,
#[clap(
short,
long,
value_parser = parse_minimal_file_size,
default_value = "8192",
help = "Minimum size in bytes",
long_help = "Minimum size of checked files in bytes, assigning bigger value may speed up searching"
)]
pub minimal_file_size: u64,
#[clap(
short = 'i',
long,
value_parser = parse_maximal_file_size,
default_value = "18446744073709551615",
help = "Maximum size in bytes",
long_help = "Maximum size of checked files in bytes, assigning lower value may speed up searching"
)]
pub maximal_file_size: u64,
}
#[derive(Debug, clap::Args)]
pub struct InvalidSymlinksArgs {
#[clap(flatten)]
pub directories: Directories,
#[clap(flatten)]
pub excluded_directories: ExcludedDirectories,
#[clap(flatten)]
pub excluded_items: ExcludedItems,
#[clap(flatten)]
pub allowed_extensions: AllowedExtensions,
#[clap(short = 'D', long, help = "Delete found files")]
pub delete_files: bool,
#[clap(flatten)]
pub file_to_save: FileToSave,
#[clap(flatten)]
pub not_recursive: NotRecursive,
#[cfg(target_family = "unix")]
#[clap(flatten)]
pub exclude_other_filesystems: ExcludeOtherFilesystems,
}
#[derive(Debug, clap::Args)]
pub struct BrokenFilesArgs {
#[clap(flatten)]
pub directories: Directories,
#[clap(flatten)]
pub excluded_directories: ExcludedDirectories,
#[clap(flatten)]
pub excluded_items: ExcludedItems,
#[clap(flatten)]
pub allowed_extensions: AllowedExtensions,
#[clap(short = 'D', long, help = "Delete found files")]
pub delete_files: bool,
#[clap(flatten)]
pub file_to_save: FileToSave,
#[clap(flatten)]
pub not_recursive: NotRecursive,
#[cfg(target_family = "unix")]
#[clap(flatten)]
pub exclude_other_filesystems: ExcludeOtherFilesystems,
}
#[derive(Debug, clap::Args)]
pub struct SimilarVideosArgs {
#[clap(flatten)]
pub directories: Directories,
#[clap(flatten)]
pub excluded_directories: ExcludedDirectories,
#[clap(flatten)]
pub excluded_items: ExcludedItems,
// #[clap(short = 'D', long, help = "Delete found files")]
// delete_files: bool, TODO
#[clap(flatten)]
pub file_to_save: FileToSave,
#[clap(flatten)]
pub allowed_extensions: AllowedExtensions,
#[clap(flatten)]
pub not_recursive: NotRecursive,
#[cfg(target_family = "unix")]
#[clap(flatten)]
pub exclude_other_filesystems: ExcludeOtherFilesystems,
#[clap(
short,
long,
value_parser = parse_minimal_file_size,
default_value = "8192",
help = "Minimum size in bytes",
long_help = "Minimum size of checked files in bytes, assigning bigger value may speed up searching"
)]
pub minimal_file_size: u64,
#[clap(
short = 'i',
long,
value_parser = parse_maximal_file_size,
default_value = "18446744073709551615",
help = "Maximum size in bytes",
long_help = "Maximum size of checked files in bytes, assigning lower value may speed up searching"
)]
pub maximal_file_size: u64,
#[clap(
short = 't',
long,
value_parser = parse_tolerance,
default_value = "10",
help = "Video maximum difference (allowed values <0,20>)",
long_help = "Maximum difference between video frames, bigger value means that videos can looks more and more different (allowed values <0,20>)"
)]
pub tolerance: i32,
}
#[derive(Debug, clap::Args)]
pub struct BadExtensionsArgs {
#[clap(flatten)]
pub directories: Directories,
#[clap(flatten)]
pub excluded_directories: ExcludedDirectories,
#[clap(flatten)]
pub excluded_items: ExcludedItems,
#[clap(flatten)]
pub allowed_extensions: AllowedExtensions,
#[clap(flatten)]
pub file_to_save: FileToSave,
#[clap(flatten)]
pub not_recursive: NotRecursive,
#[cfg(target_family = "unix")]
#[clap(flatten)]
pub exclude_other_filesystems: ExcludeOtherFilesystems,
}
#[derive(Debug, clap::Args)]
pub struct Directories {
#[clap(
short,
long,
parse(from_os_str),
required = true,
help = "Directorie(s) to search",
long_help = "List of directorie(s) which will be searched(absolute path)"
@ -278,19 +478,18 @@ pub struct Directories {
pub directories: Vec<PathBuf>,
}
#[derive(Debug, clap::StructOpt)]
#[derive(Debug, clap::Args)]
pub struct ExcludedDirectories {
#[clap(
short,
long,
parse(from_os_str),
help = "Excluded directorie(s)",
long_help = "List of directorie(s) which will be excluded from search(absolute path)"
)]
pub excluded_directories: Vec<PathBuf>,
}
#[derive(Debug, clap::StructOpt)]
#[derive(Debug, clap::Args)]
pub struct ExcludedItems {
#[clap(
short = 'E',
@ -301,7 +500,7 @@ pub struct ExcludedItems {
pub excluded_items: Vec<String>,
}
#[derive(Debug, clap::StructOpt)]
#[derive(Debug, clap::Args)]
pub struct AllowedExtensions {
#[clap(
short = 'x',
@ -312,38 +511,38 @@ pub struct AllowedExtensions {
pub allowed_extensions: Vec<String>,
}
#[derive(Debug, clap::StructOpt)]
#[derive(Debug, clap::Args)]
pub struct NotRecursive {
#[clap(short = 'R', long, help = "Prevents from recursive check of folders")]
pub not_recursive: bool,
}
#[cfg(target_family = "unix")]
#[derive(Debug, clap::StructOpt)]
#[derive(Debug, clap::Args)]
pub struct ExcludeOtherFilesystems {
#[clap(short = 'X', long, help = "Exclude files on other filesystems")]
pub exclude_other_filesystems: bool,
}
#[derive(Debug, clap::StructOpt)]
#[derive(Debug, clap::Args)]
pub struct FileToSave {
#[clap(short, long, value_name = "file-name", help = "Saves the results into the file")]
pub file_to_save: Option<PathBuf>,
}
#[derive(Debug, clap::StructOpt)]
#[derive(Debug, clap::Args)]
pub struct AllowHardLinks {
#[clap(short = 'L', long, help = "Do not ignore hard links")]
pub allow_hard_links: bool,
}
#[derive(Debug, clap::StructOpt)]
#[derive(Debug, clap::Args)]
pub struct CaseSensitiveNameComparison {
#[clap(short = 'l', long, help = "Use case sensitive name comparison")]
pub case_sensitive_name_comparison: bool,
}
#[derive(Debug, clap::StructOpt)]
#[derive(Debug, clap::Args)]
pub struct DryRun {
#[clap(long, help = "Do nothing and print the operation that would happen.")]
pub dryrun: bool,
@ -504,8 +703,6 @@ fn parse_music_duplicate_type(src: &str) -> Result<MusicSimilarity, String> {
Ok(similarity)
}
static HELP_MESSAGE: &str = "Prints help information (--help will give more information)";
const HELP_TEMPLATE: &str = r#"
{bin} {version}

View file

@ -4,6 +4,10 @@ use std::process;
use clap::Parser;
use crate::commands::{
Args, BadExtensionsArgs, BiggestFilesArgs, BrokenFilesArgs, DuplicatesArgs, EmptyFilesArgs, EmptyFoldersArgs, InvalidSymlinksArgs, SameMusicArgs, SimilarImagesArgs,
SimilarVideosArgs, TemporaryArgs,
};
use commands::Commands;
use czkawka_core::big_file::SearchMode;
use czkawka_core::common::{get_number_of_threads, set_default_number_of_threads};
@ -27,7 +31,7 @@ use czkawka_core::{
mod commands;
fn main() {
let command = Commands::from_args();
let command = Args::parse().command;
set_default_number_of_threads();
println!("Set thread number to {}", get_number_of_threads());
@ -35,440 +39,484 @@ fn main() {
println!("{:?}", command);
match command {
Commands::Duplicates {
directories,
excluded_directories,
excluded_items,
minimal_file_size,
maximal_file_size,
minimal_cached_file_size,
allowed_extensions,
search_method,
delete_method,
hash_type,
file_to_save,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
allow_hard_links,
dryrun,
case_sensitive_name_comparison,
} => {
let mut df = DuplicateFinder::new();
df.set_included_directory(directories.directories);
df.set_excluded_directory(excluded_directories.excluded_directories);
df.set_excluded_items(excluded_items.excluded_items);
df.set_minimal_file_size(minimal_file_size);
df.set_maximal_file_size(maximal_file_size);
df.set_minimal_cache_file_size(minimal_cached_file_size);
df.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
df.set_check_method(search_method);
df.set_delete_method(delete_method);
df.set_hash_type(hash_type);
df.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
df.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
df.set_ignore_hard_links(!allow_hard_links.allow_hard_links);
df.set_dryrun(dryrun.dryrun);
df.set_case_sensitive_name_comparison(case_sensitive_name_comparison.case_sensitive_name_comparison);
df.find_duplicates(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !df.save_results_to_file(file_name) {
df.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
df.print_results();
df.get_text_messages().print_messages();
}
Commands::EmptyFolders {
directories,
delete_folders,
file_to_save,
excluded_directories,
excluded_items,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
} => {
let mut ef = EmptyFolder::new();
ef.set_included_directory(directories.directories);
ef.set_excluded_directory(excluded_directories.excluded_directories);
ef.set_excluded_items(excluded_items.excluded_items);
ef.set_delete_folder(delete_folders);
#[cfg(target_family = "unix")]
ef.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
ef.find_empty_folders(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !ef.save_results_to_file(file_name) {
ef.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
ef.print_results();
ef.get_text_messages().print_messages();
}
Commands::BiggestFiles {
directories,
excluded_directories,
excluded_items,
allowed_extensions,
number_of_files,
file_to_save,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
delete_files,
smallest_mode,
} => {
let mut bf = BigFile::new();
bf.set_included_directory(directories.directories);
bf.set_excluded_directory(excluded_directories.excluded_directories);
bf.set_excluded_items(excluded_items.excluded_items);
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);
#[cfg(target_family = "unix")]
bf.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
if delete_files {
bf.set_delete_method(big_file::DeleteMethod::Delete);
}
if smallest_mode {
bf.set_search_mode(SearchMode::SmallestFiles);
}
bf.find_big_files(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !bf.save_results_to_file(file_name) {
bf.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
bf.print_results();
bf.get_text_messages().print_messages();
}
Commands::EmptyFiles {
directories,
excluded_directories,
excluded_items,
allowed_extensions,
delete_files,
file_to_save,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
} => {
let mut ef = EmptyFiles::new();
ef.set_included_directory(directories.directories);
ef.set_excluded_directory(excluded_directories.excluded_directories);
ef.set_excluded_items(excluded_items.excluded_items);
ef.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
ef.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
ef.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
if delete_files {
ef.set_delete_method(empty_files::DeleteMethod::Delete);
}
ef.find_empty_files(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !ef.save_results_to_file(file_name) {
ef.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
ef.print_results();
ef.get_text_messages().print_messages();
}
Commands::Temporary {
directories,
excluded_directories,
excluded_items,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
delete_files,
file_to_save,
not_recursive,
} => {
let mut tf = Temporary::new();
tf.set_included_directory(directories.directories);
tf.set_excluded_directory(excluded_directories.excluded_directories);
tf.set_excluded_items(excluded_items.excluded_items);
tf.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
tf.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
if delete_files {
tf.set_delete_method(temporary::DeleteMethod::Delete);
}
tf.find_temporary_files(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !tf.save_results_to_file(file_name) {
tf.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
tf.print_results();
tf.get_text_messages().print_messages();
}
Commands::SimilarImages {
directories,
excluded_directories,
excluded_items,
file_to_save,
minimal_file_size,
maximal_file_size,
similarity_preset,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
hash_alg,
image_filter,
hash_size,
} => {
let mut sf = SimilarImages::new();
sf.set_included_directory(directories.directories);
sf.set_excluded_directory(excluded_directories.excluded_directories);
sf.set_excluded_items(excluded_items.excluded_items);
sf.set_minimal_file_size(minimal_file_size);
sf.set_maximal_file_size(maximal_file_size);
sf.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
sf.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
sf.set_image_filter(image_filter);
sf.set_hash_alg(hash_alg);
sf.set_hash_size(hash_size);
sf.set_similarity(return_similarity_from_similarity_preset(&similarity_preset, hash_size));
sf.find_similar_images(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !sf.save_results_to_file(file_name) {
sf.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
sf.print_results();
sf.get_text_messages().print_messages();
}
Commands::SameMusic {
directories,
excluded_directories,
excluded_items,
// delete_files,
file_to_save,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
minimal_file_size,
maximal_file_size,
music_similarity,
} => {
let mut mf = SameMusic::new();
mf.set_included_directory(directories.directories);
mf.set_excluded_directory(excluded_directories.excluded_directories);
mf.set_excluded_items(excluded_items.excluded_items);
mf.set_minimal_file_size(minimal_file_size);
mf.set_maximal_file_size(maximal_file_size);
mf.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
mf.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
mf.set_music_similarity(music_similarity);
// if delete_files {
// // TODO mf.set_delete_method(same_music::DeleteMethod::Delete);
// }
mf.find_same_music(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !mf.save_results_to_file(file_name) {
mf.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
mf.print_results();
mf.get_text_messages().print_messages();
}
Commands::InvalidSymlinks {
directories,
excluded_directories,
excluded_items,
allowed_extensions,
file_to_save,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
delete_files,
} => {
let mut ifs = InvalidSymlinks::new();
ifs.set_included_directory(directories.directories);
ifs.set_excluded_directory(excluded_directories.excluded_directories);
ifs.set_excluded_items(excluded_items.excluded_items);
ifs.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
ifs.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
ifs.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
if delete_files {
ifs.set_delete_method(invalid_symlinks::DeleteMethod::Delete);
}
ifs.find_invalid_links(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !ifs.save_results_to_file(file_name) {
ifs.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
ifs.print_results();
ifs.get_text_messages().print_messages();
}
Commands::BrokenFiles {
directories,
excluded_directories,
excluded_items,
allowed_extensions,
delete_files,
file_to_save,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
} => {
let mut br = BrokenFiles::new();
br.set_included_directory(directories.directories);
br.set_excluded_directory(excluded_directories.excluded_directories);
br.set_excluded_items(excluded_items.excluded_items);
br.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
br.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
br.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
if delete_files {
br.set_delete_method(broken_files::DeleteMethod::Delete);
}
br.find_broken_files(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !br.save_results_to_file(file_name) {
br.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
br.print_results();
br.get_text_messages().print_messages();
}
Commands::SimilarVideos {
directories,
excluded_directories,
excluded_items,
file_to_save,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
tolerance,
minimal_file_size,
maximal_file_size,
allowed_extensions,
} => {
let mut vr = SimilarVideos::new();
vr.set_included_directory(directories.directories);
vr.set_excluded_directory(excluded_directories.excluded_directories);
vr.set_excluded_items(excluded_items.excluded_items);
vr.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
vr.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
vr.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
vr.set_minimal_file_size(minimal_file_size);
vr.set_maximal_file_size(maximal_file_size);
vr.set_tolerance(tolerance);
vr.find_similar_videos(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !vr.save_results_to_file(file_name) {
vr.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
vr.print_results();
vr.get_text_messages().print_messages();
}
Commands::BadExtensions {
directories,
excluded_directories,
excluded_items,
file_to_save,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
allowed_extensions,
} => {
let mut be = BadExtensions::new();
be.set_included_directory(directories.directories);
be.set_excluded_directory(excluded_directories.excluded_directories);
be.set_excluded_items(excluded_items.excluded_items);
be.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
be.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
be.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
if let Some(file_name) = file_to_save.file_name() {
if !be.save_results_to_file(file_name) {
be.get_text_messages().print_messages();
process::exit(1);
}
}
be.find_bad_extensions_files(None, None);
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
be.print_results();
be.get_text_messages().print_messages();
}
Commands::Duplicates(duplicates_args) => duplicates(duplicates_args),
Commands::EmptyFolders(empty_folders_args) => empty_folders(empty_folders_args),
Commands::BiggestFiles(biggest_files_args) => biggest_files(biggest_files_args),
Commands::EmptyFiles(empty_files_args) => empty_files(empty_files_args),
Commands::Temporary(temporary_args) => temporary(temporary_args),
Commands::SimilarImages(similar_images_args) => similar_images(similar_images_args),
Commands::SameMusic(same_music_args) => same_music(same_music_args),
Commands::InvalidSymlinks(invalid_symlinks_args) => invalid_symlinks(invalid_symlinks_args),
Commands::BrokenFiles(broken_files_args) => broken_files(broken_files_args),
Commands::SimilarVideos(similar_videos_args) => similar_videos(similar_videos_args),
Commands::BadExtensions(bad_extensions_args) => bad_extensions(bad_extensions_args),
Commands::Tester {} => {
test_image_conversion_speed();
}
}
}
fn duplicates(duplicates: DuplicatesArgs) {
let DuplicatesArgs {
directories,
excluded_directories,
excluded_items,
minimal_file_size,
maximal_file_size,
minimal_cached_file_size,
allowed_extensions,
search_method,
delete_method,
hash_type,
file_to_save,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
allow_hard_links,
dryrun,
case_sensitive_name_comparison,
} = duplicates;
let mut df = DuplicateFinder::new();
df.set_included_directory(directories.directories);
df.set_excluded_directory(excluded_directories.excluded_directories);
df.set_excluded_items(excluded_items.excluded_items);
df.set_minimal_file_size(minimal_file_size);
df.set_maximal_file_size(maximal_file_size);
df.set_minimal_cache_file_size(minimal_cached_file_size);
df.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
df.set_check_method(search_method);
df.set_delete_method(delete_method);
df.set_hash_type(hash_type);
df.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
df.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
df.set_ignore_hard_links(!allow_hard_links.allow_hard_links);
df.set_dryrun(dryrun.dryrun);
df.set_case_sensitive_name_comparison(case_sensitive_name_comparison.case_sensitive_name_comparison);
df.find_duplicates(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !df.save_results_to_file(file_name) {
df.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
df.print_results();
df.get_text_messages().print_messages();
}
fn empty_folders(empty_folders: EmptyFoldersArgs) {
let EmptyFoldersArgs {
directories,
delete_folders,
file_to_save,
excluded_directories,
excluded_items,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
} = empty_folders;
let mut ef = EmptyFolder::new();
ef.set_included_directory(directories.directories);
ef.set_excluded_directory(excluded_directories.excluded_directories);
ef.set_excluded_items(excluded_items.excluded_items);
ef.set_delete_folder(delete_folders);
#[cfg(target_family = "unix")]
ef.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
ef.find_empty_folders(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !ef.save_results_to_file(file_name) {
ef.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
ef.print_results();
ef.get_text_messages().print_messages();
}
fn biggest_files(biggest_files: BiggestFilesArgs) {
let BiggestFilesArgs {
directories,
excluded_directories,
excluded_items,
allowed_extensions,
number_of_files,
file_to_save,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
delete_files,
smallest_mode,
} = biggest_files;
let mut bf = BigFile::new();
bf.set_included_directory(directories.directories);
bf.set_excluded_directory(excluded_directories.excluded_directories);
bf.set_excluded_items(excluded_items.excluded_items);
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);
#[cfg(target_family = "unix")]
bf.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
if delete_files {
bf.set_delete_method(big_file::DeleteMethod::Delete);
}
if smallest_mode {
bf.set_search_mode(SearchMode::SmallestFiles);
}
bf.find_big_files(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !bf.save_results_to_file(file_name) {
bf.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
bf.print_results();
bf.get_text_messages().print_messages();
}
fn empty_files(empty_files: EmptyFilesArgs) {
let EmptyFilesArgs {
directories,
excluded_directories,
excluded_items,
allowed_extensions,
delete_files,
file_to_save,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
} = empty_files;
let mut ef = EmptyFiles::new();
ef.set_included_directory(directories.directories);
ef.set_excluded_directory(excluded_directories.excluded_directories);
ef.set_excluded_items(excluded_items.excluded_items);
ef.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
ef.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
ef.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
if delete_files {
ef.set_delete_method(empty_files::DeleteMethod::Delete);
}
ef.find_empty_files(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !ef.save_results_to_file(file_name) {
ef.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
ef.print_results();
ef.get_text_messages().print_messages();
}
fn temporary(temporary: TemporaryArgs) {
let TemporaryArgs {
directories,
excluded_directories,
excluded_items,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
delete_files,
file_to_save,
not_recursive,
} = temporary;
let mut tf = Temporary::new();
tf.set_included_directory(directories.directories);
tf.set_excluded_directory(excluded_directories.excluded_directories);
tf.set_excluded_items(excluded_items.excluded_items);
tf.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
tf.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
if delete_files {
tf.set_delete_method(temporary::DeleteMethod::Delete);
}
tf.find_temporary_files(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !tf.save_results_to_file(file_name) {
tf.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
tf.print_results();
tf.get_text_messages().print_messages();
}
fn similar_images(similar_images: SimilarImagesArgs) {
let SimilarImagesArgs {
directories,
excluded_directories,
excluded_items,
file_to_save,
minimal_file_size,
maximal_file_size,
similarity_preset,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
hash_alg,
image_filter,
hash_size,
} = similar_images;
let mut sf = SimilarImages::new();
sf.set_included_directory(directories.directories);
sf.set_excluded_directory(excluded_directories.excluded_directories);
sf.set_excluded_items(excluded_items.excluded_items);
sf.set_minimal_file_size(minimal_file_size);
sf.set_maximal_file_size(maximal_file_size);
sf.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
sf.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
sf.set_image_filter(image_filter);
sf.set_hash_alg(hash_alg);
sf.set_hash_size(hash_size);
sf.set_similarity(return_similarity_from_similarity_preset(&similarity_preset, hash_size));
sf.find_similar_images(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !sf.save_results_to_file(file_name) {
sf.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
sf.print_results();
sf.get_text_messages().print_messages();
}
fn same_music(same_music: SameMusicArgs) {
let SameMusicArgs {
directories,
excluded_directories,
excluded_items,
// delete_files,
file_to_save,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
minimal_file_size,
maximal_file_size,
music_similarity,
} = same_music;
let mut mf = SameMusic::new();
mf.set_included_directory(directories.directories);
mf.set_excluded_directory(excluded_directories.excluded_directories);
mf.set_excluded_items(excluded_items.excluded_items);
mf.set_minimal_file_size(minimal_file_size);
mf.set_maximal_file_size(maximal_file_size);
mf.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
mf.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
mf.set_music_similarity(music_similarity);
// if delete_files {
// // TODO mf.set_delete_method(same_music::DeleteMethod::Delete);
// }
mf.find_same_music(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !mf.save_results_to_file(file_name) {
mf.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
mf.print_results();
mf.get_text_messages().print_messages();
}
fn invalid_symlinks(invalid_symlinks: InvalidSymlinksArgs) {
let InvalidSymlinksArgs {
directories,
excluded_directories,
excluded_items,
allowed_extensions,
file_to_save,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
delete_files,
} = invalid_symlinks;
let mut ifs = InvalidSymlinks::new();
ifs.set_included_directory(directories.directories);
ifs.set_excluded_directory(excluded_directories.excluded_directories);
ifs.set_excluded_items(excluded_items.excluded_items);
ifs.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
ifs.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
ifs.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
if delete_files {
ifs.set_delete_method(invalid_symlinks::DeleteMethod::Delete);
}
ifs.find_invalid_links(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !ifs.save_results_to_file(file_name) {
ifs.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
ifs.print_results();
ifs.get_text_messages().print_messages();
}
fn broken_files(broken_files: BrokenFilesArgs) {
let BrokenFilesArgs {
directories,
excluded_directories,
excluded_items,
allowed_extensions,
delete_files,
file_to_save,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
} = broken_files;
let mut br = BrokenFiles::new();
br.set_included_directory(directories.directories);
br.set_excluded_directory(excluded_directories.excluded_directories);
br.set_excluded_items(excluded_items.excluded_items);
br.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
br.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
br.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
if delete_files {
br.set_delete_method(broken_files::DeleteMethod::Delete);
}
br.find_broken_files(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !br.save_results_to_file(file_name) {
br.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
br.print_results();
br.get_text_messages().print_messages();
}
fn similar_videos(similar_videos: SimilarVideosArgs) {
let SimilarVideosArgs {
directories,
excluded_directories,
excluded_items,
file_to_save,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
tolerance,
minimal_file_size,
maximal_file_size,
allowed_extensions,
} = similar_videos;
let mut vr = SimilarVideos::new();
vr.set_included_directory(directories.directories);
vr.set_excluded_directory(excluded_directories.excluded_directories);
vr.set_excluded_items(excluded_items.excluded_items);
vr.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
vr.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
vr.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
vr.set_minimal_file_size(minimal_file_size);
vr.set_maximal_file_size(maximal_file_size);
vr.set_tolerance(tolerance);
vr.find_similar_videos(None, None);
if let Some(file_name) = file_to_save.file_name() {
if !vr.save_results_to_file(file_name) {
vr.get_text_messages().print_messages();
process::exit(1);
}
}
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
vr.print_results();
vr.get_text_messages().print_messages();
}
fn bad_extensions(bad_extensions: BadExtensionsArgs) {
let BadExtensionsArgs {
directories,
excluded_directories,
excluded_items,
file_to_save,
not_recursive,
#[cfg(target_family = "unix")]
exclude_other_filesystems,
allowed_extensions,
} = bad_extensions;
let mut be = BadExtensions::new();
be.set_included_directory(directories.directories);
be.set_excluded_directory(excluded_directories.excluded_directories);
be.set_excluded_items(excluded_items.excluded_items);
be.set_allowed_extensions(allowed_extensions.allowed_extensions.join(","));
be.set_recursive_search(!not_recursive.not_recursive);
#[cfg(target_family = "unix")]
be.set_exclude_other_filesystems(exclude_other_filesystems.exclude_other_filesystems);
if let Some(file_name) = file_to_save.file_name() {
if !be.save_results_to_file(file_name) {
be.get_text_messages().print_messages();
process::exit(1);
}
}
be.find_bad_extensions_files(None, None);
#[cfg(not(debug_assertions))] // This will show too much probably unnecessary data to debug, comment line only if needed
be.print_results();
be.get_text_messages().print_messages();
}