diff --git a/.gitignore b/.gitignore index b8cce7d..296f16f 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ TestSuite* *.snap flatpak/ *.zip -*.zst \ No newline at end of file +*.zst +*.profraw \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 2c2d141..3d2d242 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,15 +66,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "ansi_term" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" -dependencies = [ - "winapi", -] - [[package]] name = "anyhow" version = "1.0.57" @@ -350,17 +341,41 @@ dependencies = [ [[package]] name = "clap" -version = "2.34.0" +version = "3.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "d53da17d37dba964b9b3ecb5c5a1f193a2762c700e6829201e645b9381c99dc7" dependencies = [ - "ansi_term", "atty", "bitflags", - "strsim 0.8.0", + "clap_derive", + "clap_lex", + "indexmap", + "once_cell", + "strsim", + "termcolor", "textwrap", - "unicode-width", - "vec_map", +] + +[[package]] +name = "clap_derive" +version = "3.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c11d40217d16aee8508cc8e5fde8b4ff24639758608e5374e731b53f85749fb9" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5538cd660450ebeb4234cfecf8f2284b844ffc4c50531e66d584ad5b91293613" +dependencies = [ + "os_str_bytes", ] [[package]] @@ -395,9 +410,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" +checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c" dependencies = [ "cfg-if", "crossbeam-utils", @@ -416,26 +431,26 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" +checksum = "07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "lazy_static", "memoffset", + "once_cell", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +checksum = "8ff1f980957787286a554052d03c7aee98d99cc32e09f6d45f0a814133c87978" dependencies = [ "cfg-if", - "lazy_static", + "once_cell", ] [[package]] @@ -452,9 +467,9 @@ dependencies = [ name = "czkawka_cli" version = "4.1.0" dependencies = [ + "clap", "czkawka_core", "image_hasher", - "structopt", ] [[package]] @@ -529,7 +544,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3495912c9c1ccf2e18976439f4443f3fee0fd61f424ff99fde6a66b15ecb448f" dependencies = [ "cfg-if", - "hashbrown 0.12.1", + "hashbrown", "lock_api", "parking_lot_core", ] @@ -769,9 +784,9 @@ dependencies = [ [[package]] name = "flume" -version = "0.10.12" +version = "0.10.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843c03199d0c0ca54bc1ea90ac0d507274c28abcc4f691ae8b4eaa375087c76a" +checksum = "1ceeb589a3157cac0ab8cc585feb749bd2cea5cb55a6ee802ad72d9fd38303da" dependencies = [ "futures-core", "futures-sink", @@ -962,14 +977,14 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -1040,7 +1055,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25a68131a662b04931e71891fb14aaf65ee4b44d08e8abc10f49e77418c86c64" dependencies = [ "anyhow", - "heck 0.4.0", + "heck", "proc-macro-crate", "proc-macro-error", "proc-macro2", @@ -1199,27 +1214,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65043da274378d68241eb9a8f8f8aa54e349136f7b8e12f63e3ef44043cc30e1" -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - [[package]] name = "hashbrown" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "heck" version = "0.4.0" @@ -1301,7 +1301,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "strsim 0.10.0", + "strsim", "syn", "unic-langid", ] @@ -1404,19 +1404,19 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6012d540c5baa3589337a98ce73408de9b5a25ec9fc2c6fd6be8f0d39e0ca5a" +checksum = "6c6392766afd7964e2531940894cffe4bd8d7d17dbc3c1c4857040fd4b33bdb3" dependencies = [ "autocfg", - "hashbrown 0.11.2", + "hashbrown", ] [[package]] name = "infer" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f98856089d7ef1e861afada561bc23897918cfdfda49fe4f90ae9152ac86c3" +checksum = "e035cede526e0b21d5adffc9fa0eb4ef5d6026fe9c5b0bfe8084b9472b587a55" dependencies = [ "cfb", ] @@ -1494,9 +1494,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.57" +version = "0.3.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" +checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" dependencies = [ "wasm-bindgen", ] @@ -1821,9 +1821,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "open" -version = "2.1.3" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2423ffbf445b82e58c3b1543655968923dd06f85432f10be2bb4f1b7122f98c" +checksum = "360bcc8316bf6363aa3954c3ccc4de8add167b087e0259190a043c9514f910fe" dependencies = [ "pathdiff", "windows-sys", @@ -1835,6 +1835,12 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91409674c628d07a6b4b79cc877c6b63ba5ccbfbadddd77ca822f55069ed1bd4" +[[package]] +name = "os_str_bytes" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" + [[package]] name = "pango" version = "0.15.10" @@ -2280,7 +2286,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.9", + "semver 1.0.10", ] [[package]] @@ -2372,9 +2378,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd" +checksum = "a41d061efea015927ac527063765e73601444cdc344ba855bc7bd44578b25e1c" [[package]] name = "semver-parser" @@ -2521,42 +2527,12 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "structopt" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" -dependencies = [ - "clap", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck 0.3.3", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "subtle" version = "2.4.1" @@ -2753,7 +2729,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1a45a1c4c9015217e12347f2a411b57ce2c4fc543913b14b6fe40483328e709" dependencies = [ "cfg-expr", - "heck 0.4.0", + "heck", "pkg-config", "toml", "version-compare", @@ -2774,14 +2750,20 @@ dependencies = [ ] [[package]] -name = "textwrap" -version = "0.11.0" +name = "termcolor" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" dependencies = [ - "unicode-width", + "winapi-util", ] +[[package]] +name = "textwrap" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" + [[package]] name = "thiserror" version = "1.0.31" @@ -2840,7 +2822,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", - "wasi", + "wasi 0.10.0+wasi-snapshot-preview1", "winapi", ] @@ -2981,9 +2963,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" +checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" [[package]] name = "unicode-normalization" @@ -2994,18 +2976,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-segmentation" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" - -[[package]] -name = "unicode-width" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" - [[package]] name = "url" version = "2.2.2" @@ -3020,15 +2990,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6d5d669b51467dcf7b2f1a796ce0f955f05f01cafda6c19d6e95f730df29238" - -[[package]] -name = "vec_map" -version = "0.8.2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f" [[package]] name = "version-compare" @@ -3076,11 +3040,17 @@ version = "0.10.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" +checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3088,9 +3058,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" +checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" dependencies = [ "bumpalo", "lazy_static", @@ -3103,9 +3073,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" +checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3113,9 +3083,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" +checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" dependencies = [ "proc-macro2", "quote", @@ -3126,9 +3096,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.80" +version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" +checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" [[package]] name = "weezl" diff --git a/Changelog.md b/Changelog.md index 81e1291..783d416 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,12 +4,17 @@ - Fix removing only one item from list view - [#466](https://github.com/qarmin/czkawka/pull/466) - Fix showing help command in duplicate CLI mode - [#720](https://github.com/qarmin/czkawka/pull/720) - Fix freeze when not choosing any tag in similar music mode - [TODO]() +- Fix preview of files with non-lowercase extensions - [#694](https://github.com/qarmin/czkawka/pull/694) - Read more tags from music files - [#705](https://github.com/qarmin/czkawka/pull/705) -- Improve checking for invalid extensions - [#705](https://github.com/qarmin/czkawka/pull/705) +- Improve checking for invalid extensions - [#705](https://github.com/qarmin/czkawka/pull/705), [#747](https://github.com/qarmin/czkawka/pull/747), [#749](https://github.com/qarmin/czkawka/pull/749) - Support for finding invalid PDF files - [#705](https://github.com/qarmin/czkawka/pull/705) - Re-enable checking for broken music files(`libasound.so.2` no longer needed) - [#705](https://github.com/qarmin/czkawka/pull/705) - Fix disabled ui when using invalid settings in similar music - [#740](https://github.com/qarmin/czkawka/pull/740) - Speedup searching for invalid extensions - [#740](https://github.com/qarmin/czkawka/pull/740) +- Support for finding the smallest files - [#741](https://github.com/qarmin/czkawka/pull/741) +- Improve Windows CI - [#749](https://github.com/qarmin/czkawka/pull/749) +- Ability to check for broken files by types - [#749](https://github.com/qarmin/czkawka/pull/749) +- Add heif and Webp files support - [#750](https://github.com/qarmin/czkawka/pull/750) ## Version 4.1.0 - 24.04.2022r - New mode - finding files whose content not match with their extension - [#678](https://github.com/qarmin/czkawka/pull/678) diff --git a/README.md b/README.md index 1981558..3fa6456 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,6 @@ **Czkawka** (_tch•kav•ka_ (IPA: [ʈ͡ʂkafka]), "hiccup" in Polish) is a simple, fast and free app to remove unnecessary files from your computer. -## UNSTABLE WARNING -**Currently, master branch of this repository contains unstable GTK 4 port, so multiple regression, broken features etc. are expected.** - -**You can use old stable version built with GTK 3 - [4.1.0](https://github.com/qarmin/czkawka/releases/tag/4.1.0) or compile app from git before GTK 4 PR merge.** - -**Due build problems Windows binaries are not available yet, you can help by creating/modifying CI to produce valid windows binaries** - ## Features - Written in memory-safe Rust - Amazingly fast - due to using more or less advanced algorithms and multithreading @@ -32,7 +25,6 @@ - Broken Files - Finds files that are invalid or corrupted - Bad Extensions - Lists files whose content not match with their extension - ![Czkawka](https://user-images.githubusercontent.com/41945903/145280350-506f7e94-4db0-4de7-a68d-6e7c26bbd2bf.gif) ## How do I use it? @@ -56,8 +48,8 @@ I prepared a disk and performed a test without any folder exceptions and with di I set the minimal file size to check to 1KB on all programs. -| App | Executing Time | -|:---------------------------:|:--------------:| +| App | Executing Time | +|:----------------------------|:--------------:| | FSlint 2.4.7 (First Run) | 86s | | FSlint 2.4.7 (Second Run) | 43s | | Czkawka 3.0.0 (First Run) | 8s | @@ -67,11 +59,11 @@ I set the minimal file size to check to 1KB on all programs. I used Mprof for checking memory usage of FSlint and DupeGuru, and Heaptrack for Czkawka. -| App | Idle Ram | Max Operational Ram Usage | Stabilized after search | -|:--------------:|:--------:|:-------------------------:|:-----------------------:| -| FSlint 2.4.7 | 62 MB | 164 MB | 158 MB | -| Dupeguru 4.1.1 | 90 MB | 170 MB | 166 MB | -| Czkawka 3.0.0 | 12 MB | 122 MB | 60 MB | +| App | Idle Ram | Max Operational Ram Usage | Stabilized after search | +|:----------------|:--------:|:-------------------------:|:-----------------------:| +| FSlint 2.4.7 | 62 MB | 164 MB | 158 MB | +| Dupeguru 4.1.1 | 90 MB | 170 MB | 166 MB | +| Czkawka 3.0.0 | 12 MB | 122 MB | 60 MB | In Dupeguru, I enabled checking images with different dimensions to match Czkawka behavior. @@ -79,8 +71,8 @@ Both apps use a caching mechanism, so the second scan is really fast. Similar images which check 10949 files that occupied 6.6 GB -| App | Scan time | -|:---------------------------:|:---------:| +| App | Scan time | +|:----------------------------|:---------:| | Czkawka 3.0.0 (First Run) | 276s | | Czkawka 3.0.0 (Second Run) | 1s | | DupeGuru 4.1.1 (First Run) | 539s | @@ -88,12 +80,12 @@ Similar images which check 10949 files that occupied 6.6 GB Similar images which check 349 image files that occupied 1.7 GB -| App | Scan time | -|:---------------------------:|:----------| -| Czkawka 3.0.0 (First Run) | 54s | -| Czkawka 3.0.0 (Second Run) | 1s | -| DupeGuru 4.1.1 (First Run) | 55s | -| DupeGuru 4.1.1 (Second Run) | 1s | +| App | Scan time | +|:----------------------------|:----------:| +| Czkawka 3.0.0 (First Run) | 54s | +| Czkawka 3.0.0 (Second Run) | 1s | +| DupeGuru 4.1.1 (First Run) | 55s | +| DupeGuru 4.1.1 (Second Run) | 1s | ## Comparison to other tools @@ -171,9 +163,9 @@ Code is distributed under MIT license. Icon was created by [jannuary](https://github.com/jannuary) and licensed CC-BY-4.0. -Windows dark theme is used from [AdMin repo](https://github.com/nrhodes91/AdMin) with MIT license. +Windows dark theme is used from project [WhiteSur](https://github.com/slypy/whitesur-gtk4-theme) with MIT license. -Some icons were taken from [ReShot](https://www.reshot.com) site and are licensed under Reshot Free License +Some icons were taken from [ReShot](https://www.reshot.com) site and are licensed under Reshot Free License. The program is completely free to use. diff --git a/czkawka_cli/Cargo.toml b/czkawka_cli/Cargo.toml index 0a7cf9b..e5a1630 100644 --- a/czkawka_cli/Cargo.toml +++ b/czkawka_cli/Cargo.toml @@ -9,7 +9,7 @@ homepage = "https://github.com/qarmin/czkawka" repository = "https://github.com/qarmin/czkawka" [dependencies] -structopt = "0.3.26" +clap = { version = "3.2.3", features = ["derive"]} # For enum types image_hasher = "1.0.0" diff --git a/czkawka_cli/src/commands.rs b/czkawka_cli/src/commands.rs index 03ca87b..49a18b6 100644 --- a/czkawka_cli/src/commands.rs +++ b/czkawka_cli/src/commands.rs @@ -1,254 +1,253 @@ use std::path::PathBuf; use image_hasher::{FilterType, HashAlg}; -use structopt::StructOpt; use czkawka_core::common_dir_traversal::CheckingMethod; use czkawka_core::duplicate::{DeleteMethod, HashType}; use czkawka_core::same_music::MusicSimilarity; use czkawka_core::similar_images::SimilarityPreset; -#[derive(Debug, StructOpt)] -#[structopt(name = "czkawka", help_message = HELP_MESSAGE, template = HELP_TEMPLATE)] +#[derive(Debug, clap::StructOpt)] +#[clap(name = "czkawka", help_message = HELP_MESSAGE, template = HELP_TEMPLATE)] pub enum Commands { - #[structopt(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")] + #[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 { - #[structopt(flatten)] + #[clap(flatten)] directories: Directories, - #[structopt(flatten)] + #[clap(flatten)] excluded_directories: ExcludedDirectories, - #[structopt(flatten)] + #[clap(flatten)] excluded_items: ExcludedItems, - #[structopt(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")] + #[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, - #[structopt(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")] + #[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, - #[structopt(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 will cause that lower amount of files will be cached, but loading of cache will be faster")] + #[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 will cause that lower amount of files will be cached, but loading of cache will be faster")] minimal_cached_file_size: u64, - #[structopt(flatten)] + #[clap(flatten)] allowed_extensions: AllowedExtensions, - #[structopt(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")] + #[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, - #[structopt(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")] + #[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, - #[structopt(short = "t", long, default_value = "BLAKE3", parse(try_from_str = parse_hash_type), help = "Hash type (BLAKE3, CRC32, XXH3)")] + #[clap(short = 't', long, default_value = "BLAKE3", parse(try_from_str = parse_hash_type), help = "Hash type (BLAKE3, CRC32, XXH3)")] hash_type: HashType, - #[structopt(flatten)] + #[clap(flatten)] file_to_save: FileToSave, - #[structopt(flatten)] + #[clap(flatten)] not_recursive: NotRecursive, #[cfg(target_family = "unix")] - #[structopt(flatten)] + #[clap(flatten)] exclude_other_filesystems: ExcludeOtherFilesystems, - #[structopt(flatten)] + #[clap(flatten)] allow_hard_links: AllowHardLinks, - #[structopt(flatten)] + #[clap(flatten)] dryrun: DryRun, }, - #[structopt(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")] + #[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 { - #[structopt(flatten)] + #[clap(flatten)] directories: Directories, - #[structopt(flatten)] + #[clap(flatten)] excluded_directories: ExcludedDirectories, - #[structopt(flatten)] + #[clap(flatten)] excluded_items: ExcludedItems, - #[structopt(short = "D", long, help = "Delete found folders")] + #[clap(short = 'D', long, help = "Delete found folders")] delete_folders: bool, - #[structopt(flatten)] + #[clap(flatten)] file_to_save: FileToSave, #[cfg(target_family = "unix")] - #[structopt(flatten)] + #[clap(flatten)] exclude_other_filesystems: ExcludeOtherFilesystems, }, - #[structopt(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 -x VIDEO -f results.txt")] + #[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 -x VIDEO -f results.txt")] BiggestFiles { - #[structopt(flatten)] + #[clap(flatten)] directories: Directories, - #[structopt(flatten)] + #[clap(flatten)] excluded_directories: ExcludedDirectories, - #[structopt(flatten)] + #[clap(flatten)] excluded_items: ExcludedItems, - #[structopt(flatten)] + #[clap(flatten)] allowed_extensions: AllowedExtensions, - #[structopt(short, long, default_value = "50", help = "Number of files to be shown")] + #[clap(short, long, default_value = "50", help = "Number of files to be shown")] number_of_files: usize, - #[structopt(short = "D", long, help = "Delete found files")] + #[clap(short = 'D', long, help = "Delete found files")] delete_files: bool, - #[structopt(flatten)] + #[clap(flatten)] file_to_save: FileToSave, - #[structopt(flatten)] + #[clap(flatten)] not_recursive: NotRecursive, #[cfg(target_family = "unix")] - #[structopt(flatten)] + #[clap(flatten)] exclude_other_filesystems: ExcludeOtherFilesystems, }, - #[structopt(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")] + #[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 { - #[structopt(flatten)] + #[clap(flatten)] directories: Directories, - #[structopt(flatten)] + #[clap(flatten)] excluded_directories: ExcludedDirectories, - #[structopt(flatten)] + #[clap(flatten)] excluded_items: ExcludedItems, - #[structopt(flatten)] + #[clap(flatten)] allowed_extensions: AllowedExtensions, - #[structopt(short = "D", long, help = "Delete found files")] + #[clap(short = 'D', long, help = "Delete found files")] delete_files: bool, - #[structopt(flatten)] + #[clap(flatten)] file_to_save: FileToSave, - #[structopt(flatten)] + #[clap(flatten)] not_recursive: NotRecursive, #[cfg(target_family = "unix")] - #[structopt(flatten)] + #[clap(flatten)] exclude_other_filesystems: ExcludeOtherFilesystems, }, - #[structopt(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")] + #[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 { - #[structopt(flatten)] + #[clap(flatten)] directories: Directories, - #[structopt(flatten)] + #[clap(flatten)] excluded_directories: ExcludedDirectories, - #[structopt(flatten)] + #[clap(flatten)] excluded_items: ExcludedItems, - #[structopt(short = "D", long, help = "Delete found files")] + #[clap(short = 'D', long, help = "Delete found files")] delete_files: bool, - #[structopt(flatten)] + #[clap(flatten)] file_to_save: FileToSave, - #[structopt(flatten)] + #[clap(flatten)] not_recursive: NotRecursive, #[cfg(target_family = "unix")] - #[structopt(flatten)] + #[clap(flatten)] exclude_other_filesystems: ExcludeOtherFilesystems, }, - #[structopt(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")] + #[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 { - #[structopt(flatten)] + #[clap(flatten)] directories: Directories, - #[structopt(flatten)] + #[clap(flatten)] excluded_directories: ExcludedDirectories, - #[structopt(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")] + #[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, - #[structopt(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")] + #[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, - #[structopt(short, long, default_value = "High", parse(try_from_str = parse_similar_images_similarity), help = "Similairty level (Minimal, VerySmall, Small, Medium, High, VeryHigh)", long_help = "Methods to choose similarity level of images which will be considered as duplicated.")] + #[clap(short, long, default_value = "High", parse(try_from_str = parse_similar_images_similarity), help = "Similairty level (Minimal, VerySmall, Small, Medium, High, VeryHigh)", long_help = "Methods to choose similarity level of images which will be considered as duplicated.")] similarity_preset: SimilarityPreset, - #[structopt(flatten)] + #[clap(flatten)] excluded_items: ExcludedItems, - #[structopt(flatten)] + #[clap(flatten)] file_to_save: FileToSave, - #[structopt(flatten)] + #[clap(flatten)] not_recursive: NotRecursive, #[cfg(target_family = "unix")] - #[structopt(flatten)] + #[clap(flatten)] exclude_other_filesystems: ExcludeOtherFilesystems, - #[structopt(short = "g", long, default_value = "Gradient", parse(try_from_str = parse_similar_hash_algorithm), help = "Hash algorithm (allowed: Mean, Gradient, Blockhash, VertGradient, DoubleGradient)")] + #[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, - #[structopt(short = "z", long, default_value = "Lanczos3", parse(try_from_str = parse_similar_image_filter), help = "Hash algorithm (allowed: Lanczos3, Nearest, Triangle, Faussian, Catmullrom)")] + #[clap(short = 'z', long, default_value = "Lanczos3", parse(try_from_str = parse_similar_image_filter), help = "Hash algorithm (allowed: Lanczos3, Nearest, Triangle, Faussian, Catmullrom)")] image_filter: FilterType, - #[structopt(short = "c", long, default_value = "8", parse(try_from_str = parse_image_hash_size), help = "Hash size (allowed: 4, 8, 16)")] + #[clap(short = 'c', long, default_value = "8", parse(try_from_str = parse_image_hash_size), help = "Hash size (allowed: 4, 8, 16)")] hash_size: u8, }, - #[structopt(name = "music", about = "Finds same music by tags", help_message = HELP_MESSAGE, after_help = "EXAMPLE:\n czkawka music -d /home/rafal -f results.txt")] + #[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 { - #[structopt(flatten)] + #[clap(flatten)] directories: Directories, - #[structopt(flatten)] + #[clap(flatten)] excluded_directories: ExcludedDirectories, - #[structopt(flatten)] + #[clap(flatten)] excluded_items: ExcludedItems, - // #[structopt(short = "D", long, help = "Delete found files")] + // #[clap(short = 'D', long, help = "Delete found files")] // delete_files: bool, TODO - #[structopt(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).")] + #[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, - #[structopt(flatten)] + #[clap(flatten)] file_to_save: FileToSave, - #[structopt(flatten)] + #[clap(flatten)] not_recursive: NotRecursive, #[cfg(target_family = "unix")] - #[structopt(flatten)] + #[clap(flatten)] exclude_other_filesystems: ExcludeOtherFilesystems, - #[structopt(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")] + #[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, - #[structopt(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")] + #[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, }, - #[structopt(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")] + #[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 { - #[structopt(flatten)] + #[clap(flatten)] directories: Directories, - #[structopt(flatten)] + #[clap(flatten)] excluded_directories: ExcludedDirectories, - #[structopt(flatten)] + #[clap(flatten)] excluded_items: ExcludedItems, - #[structopt(flatten)] + #[clap(flatten)] allowed_extensions: AllowedExtensions, - #[structopt(short = "D", long, help = "Delete found files")] + #[clap(short = 'D', long, help = "Delete found files")] delete_files: bool, - #[structopt(flatten)] + #[clap(flatten)] file_to_save: FileToSave, - #[structopt(flatten)] + #[clap(flatten)] not_recursive: NotRecursive, #[cfg(target_family = "unix")] - #[structopt(flatten)] + #[clap(flatten)] exclude_other_filesystems: ExcludeOtherFilesystems, }, - #[structopt(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")] + #[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 { - #[structopt(flatten)] + #[clap(flatten)] directories: Directories, - #[structopt(flatten)] + #[clap(flatten)] excluded_directories: ExcludedDirectories, - #[structopt(flatten)] + #[clap(flatten)] excluded_items: ExcludedItems, - #[structopt(flatten)] + #[clap(flatten)] allowed_extensions: AllowedExtensions, - #[structopt(short = "D", long, help = "Delete found files")] + #[clap(short = 'D', long, help = "Delete found files")] delete_files: bool, - #[structopt(flatten)] + #[clap(flatten)] file_to_save: FileToSave, - #[structopt(flatten)] + #[clap(flatten)] not_recursive: NotRecursive, #[cfg(target_family = "unix")] - #[structopt(flatten)] + #[clap(flatten)] exclude_other_filesystems: ExcludeOtherFilesystems, }, - #[structopt(name = "video", about = "Finds similar video files", help_message = HELP_MESSAGE, after_help = "EXAMPLE:\n czkawka videos -d /home/rafal -f results.txt")] + #[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 { - #[structopt(flatten)] + #[clap(flatten)] directories: Directories, - #[structopt(flatten)] + #[clap(flatten)] excluded_directories: ExcludedDirectories, - #[structopt(flatten)] + #[clap(flatten)] excluded_items: ExcludedItems, - // #[structopt(short = "D", long, help = "Delete found files")] + // #[clap(short = 'D', long, help = "Delete found files")] // delete_files: bool, TODO - #[structopt(flatten)] + #[clap(flatten)] file_to_save: FileToSave, - #[structopt(flatten)] + #[clap(flatten)] allowed_extensions: AllowedExtensions, - #[structopt(flatten)] + #[clap(flatten)] not_recursive: NotRecursive, #[cfg(target_family = "unix")] - #[structopt(flatten)] + #[clap(flatten)] exclude_other_filesystems: ExcludeOtherFilesystems, - #[structopt(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")] + #[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, - #[structopt(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")] + #[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, - #[structopt(short = "t", long, parse(try_from_str = parse_tolerance), default_value = "10", help = "Video maximium 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>)")] + #[clap(short = 't', long, parse(try_from_str = parse_tolerance), default_value = "10", help = "Video maximium 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, }, - #[structopt(name = "tester", about = "Contains various test", help_message = HELP_MESSAGE, after_help = "EXAMPLE:\n czkawka tests -i")] + #[clap(name = "tester", about = "Contains various test", help_message = HELP_MESSAGE, after_help = "EXAMPLE:\n czkawka tests -i")] Tester { - #[structopt(short = "i", long = "test_image", help = "Test speed of hashing provided test.jpg image with different filters and methods.")] + #[clap(short = 'i', long = "test_image", help = "Test speed of hashing provided test.jpg image with different filters and methods.")] test_image: bool, }, } -#[derive(Debug, StructOpt)] +#[derive(Debug, clap::StructOpt)] pub struct Directories { - #[structopt( + #[clap( short, long, parse(from_os_str), @@ -259,9 +258,9 @@ pub struct Directories { pub directories: Vec, } -#[derive(Debug, StructOpt)] +#[derive(Debug, clap::StructOpt)] pub struct ExcludedDirectories { - #[structopt( + #[clap( short, long, parse(from_os_str), @@ -271,10 +270,10 @@ pub struct ExcludedDirectories { pub excluded_directories: Vec, } -#[derive(Debug, StructOpt)] +#[derive(Debug, clap::StructOpt)] pub struct ExcludedItems { - #[structopt( - short = "E", + #[clap( + short = 'E', long, help = "Excluded item(s)", long_help = "List of excluded item(s) which contains * wildcard(may be slow, so use -e where possible)" @@ -282,10 +281,10 @@ pub struct ExcludedItems { pub excluded_items: Vec, } -#[derive(Debug, StructOpt)] +#[derive(Debug, clap::StructOpt)] pub struct AllowedExtensions { - #[structopt( - short = "x", + #[clap( + short = 'x', long, help = "Allowed file extension(s)", long_help = "List of checked files with provided extension(s). There are also helpful macros which allow to easy use a typical extensions like:\nIMAGE(\"jpg,kra,gif,png,bmp,tiff,hdr,svg\"),\nTEXT(\"txt,doc,docx,odt,rtf\"),\nVIDEO(\"mp4,flv,mkv,webm,vob,ogv,gifv,avi,mov,wmv,mpg,m4v,m4p,mpeg,3gp\") or\nMUSIC(\"mp3,flac,ogg,tta,wma,webm\")\n " @@ -293,34 +292,34 @@ pub struct AllowedExtensions { pub allowed_extensions: Vec, } -#[derive(Debug, StructOpt)] +#[derive(Debug, clap::StructOpt)] pub struct NotRecursive { - #[structopt(short = "R", long, help = "Prevents from recursive check of folders")] + #[clap(short = 'R', long, help = "Prevents from recursive check of folders")] pub not_recursive: bool, } #[cfg(target_family = "unix")] -#[derive(Debug, StructOpt)] +#[derive(Debug, clap::StructOpt)] pub struct ExcludeOtherFilesystems { - #[structopt(short = "X", long, help = "Exclude files on other filesystems")] + #[clap(short = 'X', long, help = "Exclude files on other filesystems")] pub exclude_other_filesystems: bool, } -#[derive(Debug, StructOpt)] +#[derive(Debug, clap::StructOpt)] pub struct FileToSave { - #[structopt(short, long, value_name = "file-name", help = "Saves the results into the file")] + #[clap(short, long, value_name = "file-name", help = "Saves the results into the file")] pub file_to_save: Option, } -#[derive(Debug, StructOpt)] +#[derive(Debug, clap::StructOpt)] pub struct AllowHardLinks { - #[structopt(short = "L", long, help = "Do not ignore hard links")] + #[clap(short = 'L', long, help = "Do not ignore hard links")] pub allow_hard_links: bool, } -#[derive(Debug, StructOpt)] +#[derive(Debug, clap::StructOpt)] pub struct DryRun { - #[structopt(long, help = "Do nothing and print the operation that would happen.")] + #[clap(long, help = "Do nothing and print the operation that would happen.")] pub dryrun: bool, } @@ -487,8 +486,8 @@ const HELP_TEMPLATE: &str = r#" USAGE: {usage} [SCFLAGS] [SCOPTIONS] -FLAGS: -{flags} +OPTIONS: +{options} SUBCOMMANDS: {subcommands} diff --git a/czkawka_cli/src/main.rs b/czkawka_cli/src/main.rs index 79b3125..3565657 100644 --- a/czkawka_cli/src/main.rs +++ b/czkawka_cli/src/main.rs @@ -1,9 +1,6 @@ #![allow(clippy::needless_late_init)] -use std::process; - -use structopt::StructOpt; - +use clap::Parser; use commands::Commands; #[allow(unused_imports)] // It is used in release for print_results(). use czkawka_core::common_traits::*; @@ -21,6 +18,7 @@ use czkawka_core::{ similar_videos::SimilarVideos, temporary::{self, Temporary}, }; +use std::process; mod commands; diff --git a/czkawka_gui/Cargo.toml b/czkawka_gui/Cargo.toml index 55a5d0a..6216cee 100644 --- a/czkawka_gui/Cargo.toml +++ b/czkawka_gui/Cargo.toml @@ -25,7 +25,7 @@ futures = "0.3.21" directories-next = "2.0.0" # For opening files -open = "2.1.2" +open = "3.0.1" # To get image preview image = "0.24.2" diff --git a/czkawka_gui/src/connect_things/connect_about_buttons.rs b/czkawka_gui/src/connect_things/connect_about_buttons.rs index f87903d..fdc1722 100644 --- a/czkawka_gui/src/connect_things/connect_about_buttons.rs +++ b/czkawka_gui/src/connect_things/connect_about_buttons.rs @@ -10,34 +10,29 @@ const TRANSLATION_SITE: &str = "https://crwd.in/czkawka"; pub fn connect_about_buttons(gui_data: &GuiData) { let button_donation = gui_data.about.button_donation.clone(); button_donation.connect_clicked(move |_| { - open::that_in_background(SPONSOR_SITE); - // TODO find way to handle errors when opening this sites - // if let Err(e) = open::that(SPONSOR_SITE) { - // println!("Failed to open sponsor site: {}, reason {}", SPONSOR_SITE, e) - // }; + if let Err(e) = open::that(SPONSOR_SITE) { + println!("Failed to open sponsor site: {}, reason {}", SPONSOR_SITE, e) + }; }); let button_instruction = gui_data.about.button_instruction.clone(); button_instruction.connect_clicked(move |_| { - open::that_in_background(INSTRUCTION_SITE); - // if let Err(e) = open::that(INSTRUCTION_SITE) { - // println!("Failed to open instruction site: {}, reason {}", INSTRUCTION_SITE, e) - // }; + if let Err(e) = open::that(INSTRUCTION_SITE) { + println!("Failed to open instruction site: {}, reason {}", INSTRUCTION_SITE, e) + }; }); let button_repository = gui_data.about.button_repository.clone(); button_repository.connect_clicked(move |_| { - open::that_in_background(REPOSITORY_SITE); - // if let Err(e) = open::that(REPOSITORY_SITE) { - // println!("Failed to open repository site: {}, reason {}", REPOSITORY_SITE, e) - // }; + if let Err(e) = open::that(REPOSITORY_SITE) { + println!("Failed to open repository site: {}, reason {}", REPOSITORY_SITE, e) + }; }); let button_translation = gui_data.about.button_translation.clone(); button_translation.connect_clicked(move |_| { - open::that_in_background(TRANSLATION_SITE); - // if let Err(e) = open::that(TRANSLATION_SITE) { - // println!("Failed to open repository site: {}, reason {}", TRANSLATION_SITE, e) - // }; + if let Err(e) = open::that(TRANSLATION_SITE) { + println!("Failed to open repository site: {}, reason {}", TRANSLATION_SITE, e) + }; }); } diff --git a/czkawka_gui/src/connect_things/connect_settings.rs b/czkawka_gui/src/connect_things/connect_settings.rs index fb7f821..9d11e02 100644 --- a/czkawka_gui/src/connect_things/connect_settings.rs +++ b/czkawka_gui/src/connect_things/connect_settings.rs @@ -73,7 +73,10 @@ pub fn connect_settings(gui_data: &GuiData) { button_settings_open_cache_folder.connect_clicked(move |_| { if let Some(proj_dirs) = ProjectDirs::from("pl", "Qarmin", "Czkawka") { let cache_dir = proj_dirs.cache_dir(); - open::that_in_background(cache_dir); + + if let Err(e) = open::that(&cache_dir) { + println!("Failed to open config folder {:?}, reason {}", cache_dir, e); + }; } }); } @@ -83,7 +86,10 @@ pub fn connect_settings(gui_data: &GuiData) { button_settings_open_settings_folder.connect_clicked(move |_| { if let Some(proj_dirs) = ProjectDirs::from("pl", "Qarmin", "Czkawka") { let config_dir = proj_dirs.config_dir(); - open::that_in_background(config_dir); + + if let Err(e) = open::that(&config_dir) { + println!("Failed to open config folder {:?}, reason {}", config_dir, e); + }; } }); } diff --git a/czkawka_gui/src/opening_selecting_records.rs b/czkawka_gui/src/opening_selecting_records.rs index fc59e70..a38bce1 100644 --- a/czkawka_gui/src/opening_selecting_records.rs +++ b/czkawka_gui/src/opening_selecting_records.rs @@ -132,11 +132,9 @@ fn common_open_function(tree_view: >k4::TreeView, column_name: i32, column_pat OpenMode::PathAndName => get_full_name_from_path_name(&path, &name), }; - open::that_in_background(&end_path); - - // if let Err(e) = open::that(&end_path) { - // println!("Failed to open {} - Error {}", end_path, e); - // } + if let Err(e) = open::that(&end_path) { + println!("Failed to open file {}, reason {}", end_path, e); + }; } } @@ -192,7 +190,9 @@ fn common_open_function_upper_directories(tree_view: >k4::TreeView, column_ful for tree_path in selected_rows.iter().rev() { let full_path = tree_model.get::(&tree_model.iter(tree_path).unwrap(), column_full_path); - open::that_in_background(&full_path); + if let Err(e) = open::that(&full_path) { + println!("Failed to open file {}, reason {}", full_path, e); + }; } } diff --git a/czkawka_gui/src/saving_loading.rs b/czkawka_gui/src/saving_loading.rs index d47959a..9b4efaf 100644 --- a/czkawka_gui/src/saving_loading.rs +++ b/czkawka_gui/src/saving_loading.rs @@ -213,6 +213,7 @@ impl LoadSaveStruct { self.loaded_items.insert(key, vec_string); } + //noinspection RsLift pub fn open_save_file(&self, text_view_errors: &TextView, save_configuration: bool, manual_execution: bool) -> Option<(File, PathBuf)> { if let Some(proj_dirs) = ProjectDirs::from("pl", "Qarmin", "Czkawka") { // Lin: /home/username/.config/czkawka diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000..9a27ee1 --- /dev/null +++ b/deny.toml @@ -0,0 +1,25 @@ +[advisories] +vulnerability = "deny" +unmaintained = "warn" +yanked = "deny" +ignore = [ + "RUSTSEC-2020-0071", # https://rustsec.org/advisories/RUSTSEC-2020-0071 - Potential segfault in the time crate. +] + + +[bans] +multiple-versions = "deny" +wildcards = "allow" +deny = [] +skip = [] +skip-tree = [] + + +[licenses] +unlicensed = "allow" +allow-osi-fsf-free = "either" +copyleft = "allow" +allow = [ + "MIT", + "Apache-2.0 WITH LLVM-exception", +]