diff --git a/Cargo.lock b/Cargo.lock index f03d47e..1c2befc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -88,16 +88,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi 0.1.19", "libc", - "winapi 0.3.9", -] - -[[package]] -name = "autocfg" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" -dependencies = [ - "autocfg 1.1.0", + "winapi", ] [[package]] @@ -114,22 +105,13 @@ checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", - "cfg-if 1.0.0", + "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", ] -[[package]] -name = "base64" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" -dependencies = [ - "byteorder", -] - [[package]] name = "base64" version = "0.21.5" @@ -160,17 +142,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" -[[package]] -name = "bytes" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -dependencies = [ - "byteorder", - "either", - "iovec", -] - [[package]] name = "bytes" version = "1.5.0" @@ -194,15 +165,9 @@ checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" dependencies = [ "byteorder", "fnv", - "uuid 1.5.0", + "uuid", ] -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -254,7 +219,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] @@ -263,49 +228,12 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "colorchoice" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" -[[package]] -name = "cookie" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5" -dependencies = [ - "time", - "url 1.7.2", -] - -[[package]] -name = "cookie_store" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46750b3f362965f197996c4448e4a0935e791bf7d6631bfce9ee0af3d24c919c" -dependencies = [ - "cookie", - "failure", - "idna 0.1.5", - "log", - "publicsuffix", - "serde", - "serde_json", - "time", - "try_from", - "url 1.7.2", -] - [[package]] name = "core-foundation" version = "0.9.3" @@ -322,63 +250,6 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "crossbeam-deque" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20ff29ded3204c5106278a81a38f4b482636ed4fa1e6cfbeef193291beb29ed" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", - "maybe-uninit", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" -dependencies = [ - "autocfg 1.1.0", - "cfg-if 0.1.10", - "crossbeam-utils", - "lazy_static", - "maybe-uninit", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-queue" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" -dependencies = [ - "cfg-if 0.1.10", - "crossbeam-utils", - "maybe-uninit", -] - -[[package]] -name = "crossbeam-utils" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -dependencies = [ - "autocfg 1.1.0", - "cfg-if 0.1.10", - "lazy_static", -] - [[package]] name = "crossterm" version = "0.25.0" @@ -388,11 +259,11 @@ dependencies = [ "bitflags 1.3.2", "crossterm_winapi", "libc", - "mio 0.8.9", - "parking_lot 0.12.1", + "mio", + "parking_lot", "signal-hook", "signal-hook-mio", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -401,34 +272,22 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" dependencies = [ - "winapi 0.3.9", + "winapi", ] -[[package]] -name = "dtoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" - [[package]] name = "dyn-clone" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" -[[package]] -name = "either" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" - [[package]] name = "encoding_rs" version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -441,44 +300,12 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "failure" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" -dependencies = [ - "backtrace", - "failure_derive", -] - -[[package]] -name = "failure_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "synstructure", -] - [[package]] name = "fastrand" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" -[[package]] -name = "flate2" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - [[package]] name = "fnv" version = "1.0.7" @@ -506,37 +333,9 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ - "percent-encoding 2.3.0", + "percent-encoding", ] -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags 1.3.2", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - -[[package]] -name = "futures" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" - [[package]] name = "futures-channel" version = "0.3.29" @@ -552,16 +351,6 @@ version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" -[[package]] -name = "futures-cpupool" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -dependencies = [ - "futures", - "num_cpus", -] - [[package]] name = "futures-io" version = "0.3.29" @@ -601,39 +390,21 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" -[[package]] -name = "h2" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" -dependencies = [ - "byteorder", - "bytes 0.4.12", - "fnv", - "futures", - "http 0.1.21", - "indexmap", - "log", - "slab", - "string", - "tokio-io", -] - [[package]] name = "h2" version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ - "bytes 1.5.0", + "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http 0.2.9", + "http", "indexmap", "slab", - "tokio 1.33.0", + "tokio", "tokio-util", "tracing", ] @@ -665,38 +436,15 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" -[[package]] -name = "http" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" -dependencies = [ - "bytes 0.4.12", - "fnv", - "itoa 0.4.8", -] - [[package]] name = "http" version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ - "bytes 1.5.0", + "bytes", "fnv", - "itoa 1.0.9", -] - -[[package]] -name = "http-body" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" -dependencies = [ - "bytes 0.4.12", - "futures", - "http 0.1.21", - "tokio-buf", + "itoa", ] [[package]] @@ -705,8 +453,8 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ - "bytes 1.5.0", - "http 0.2.9", + "bytes", + "http", "pin-project-lite", ] @@ -722,71 +470,28 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "hyper" -version = "0.12.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c843caf6296fc1f93444735205af9ed4e109a539005abb2564ae1d6fad34c52" -dependencies = [ - "bytes 0.4.12", - "futures", - "futures-cpupool", - "h2 0.1.26", - "http 0.1.21", - "http-body 0.1.0", - "httparse", - "iovec", - "itoa 0.4.8", - "log", - "net2", - "rustc_version", - "time", - "tokio 0.1.22", - "tokio-buf", - "tokio-executor", - "tokio-io", - "tokio-reactor", - "tokio-tcp", - "tokio-threadpool", - "tokio-timer", - "want 0.2.0", -] - [[package]] name = "hyper" version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ - "bytes 1.5.0", + "bytes", "futures-channel", "futures-core", "futures-util", - "h2 0.3.21", - "http 0.2.9", - "http-body 0.4.5", + "h2", + "http", + "http-body", "httparse", "httpdate", - "itoa 1.0.9", + "itoa", "pin-project-lite", "socket2 0.4.10", - "tokio 1.33.0", + "tokio", "tower-service", "tracing", - "want 0.3.1", -] - -[[package]] -name = "hyper-tls" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" -dependencies = [ - "bytes 0.4.12", - "futures", - "hyper 0.12.36", - "native-tls", - "tokio-io", + "want", ] [[package]] @@ -795,10 +500,10 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes 1.5.0", - "hyper 0.14.27", + "bytes", + "hyper", "native-tls", - "tokio 1.33.0", + "tokio", "tokio-native-tls", ] @@ -825,28 +530,6 @@ dependencies = [ "cc", ] -[[package]] -name = "idna" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - [[package]] name = "idna" version = "0.4.0" @@ -863,7 +546,7 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "autocfg 1.1.0", + "autocfg", "hashbrown", ] @@ -876,6 +559,12 @@ dependencies = [ "cfb", ] +[[package]] +name = "inline_colorization" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1804bdb6a9784758b200007273a8b84e2b0b0b97a8f1e18e763eceb3e9f98a" + [[package]] name = "inquire" version = "0.6.2" @@ -892,27 +581,12 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - [[package]] name = "ipnet" version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - [[package]] name = "itoa" version = "1.0.9" @@ -928,16 +602,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -956,22 +620,13 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" -[[package]] -name = "lock_api" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" -dependencies = [ - "scopeguard", -] - [[package]] name = "lock_api" version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ - "autocfg 1.1.0", + "autocfg", "scopeguard", ] @@ -981,49 +636,18 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - [[package]] name = "memchr" version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" -[[package]] -name = "memoffset" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" -dependencies = [ - "autocfg 1.1.0", -] - [[package]] name = "mime" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "mime_guess" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" -dependencies = [ - "mime", - "unicase", -] - [[package]] name = "miniz_oxide" version = "0.7.1" @@ -1033,25 +657,6 @@ dependencies = [ "adler", ] -[[package]] -name = "mio" -version = "0.6.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" -dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log", - "miow", - "net2", - "slab", - "winapi 0.2.8", -] - [[package]] name = "mio" version = "0.8.9" @@ -1060,22 +665,10 @@ checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys", ] -[[package]] -name = "miow" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", -] - [[package]] name = "native-tls" version = "0.2.11" @@ -1094,17 +687,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "net2" -version = "0.2.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b13b648036a2339d06de780866fbdfda0dde886de7b3af2ddeba8b14f4ee34ac" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", -] - [[package]] name = "newline-converter" version = "0.2.2" @@ -1120,7 +702,7 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] [[package]] @@ -1155,7 +737,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" dependencies = [ "bitflags 2.4.1", - "cfg-if 1.0.0", + "cfg-if", "foreign-types", "libc", "once_cell", @@ -1171,7 +753,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] @@ -1192,40 +774,14 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "parking_lot" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" -dependencies = [ - "lock_api 0.3.4", - "parking_lot_core 0.6.3", - "rustc_version", -] - [[package]] name = "parking_lot" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ - "lock_api 0.4.11", - "parking_lot_core 0.9.9", -] - -[[package]] -name = "parking_lot_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66b810a62be75176a80873726630147a5ca780cd33921e0b5709033e66b0a" -dependencies = [ - "cfg-if 0.1.10", - "cloudabi", - "libc", - "redox_syscall 0.1.57", - "rustc_version", - "smallvec 0.6.14", - "winapi 0.3.9", + "lock_api", + "parking_lot_core", ] [[package]] @@ -1234,19 +790,13 @@ version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", - "redox_syscall 0.4.1", - "smallvec 1.11.1", + "redox_syscall", + "smallvec", "windows-targets", ] -[[package]] -name = "percent-encoding" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" - [[package]] name = "percent-encoding" version = "2.3.0" @@ -1277,13 +827,14 @@ version = "0.1.0" dependencies = [ "clap", "infer", + "inline_colorization", "inquire", "log", - "reqwest 0.11.22", + "reqwest", + "sanitise-file-name", "serde", "serde_json", "stderrlog", - "tmdb_client", "urlencoding", "walkdir", ] @@ -1297,16 +848,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "publicsuffix" -version = "1.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b4ce31ff0a27d93c8de1849cf58162283752f065a90d508f1105fa6c9a213f" -dependencies = [ - "idna 0.2.3", - "url 2.4.1", -] - [[package]] name = "quote" version = "1.0.33" @@ -1316,127 +857,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -dependencies = [ - "autocfg 0.1.8", - "libc", - "rand_chacha", - "rand_core 0.4.2", - "rand_hc", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg", - "rand_xorshift", - "winapi 0.3.9", -] - -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.3.1", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_jitter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi 0.3.9", -] - -[[package]] -name = "rand_os" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi 0.3.9", -] - -[[package]] -name = "rand_pcg" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.4.2", -] - -[[package]] -name = "rand_xorshift" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - [[package]] name = "redox_syscall" version = "0.4.1" @@ -1446,76 +866,42 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "reqwest" -version = "0.9.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f88643aea3c1343c804950d7bf983bd2067f5ab59db6d613a08e05572f2714ab" -dependencies = [ - "base64 0.10.1", - "bytes 0.4.12", - "cookie", - "cookie_store", - "encoding_rs", - "flate2", - "futures", - "http 0.1.21", - "hyper 0.12.36", - "hyper-tls 0.3.2", - "log", - "mime", - "mime_guess", - "native-tls", - "serde", - "serde_json", - "serde_urlencoded 0.5.5", - "time", - "tokio 0.1.22", - "tokio-executor", - "tokio-io", - "tokio-threadpool", - "tokio-timer", - "url 1.7.2", - "uuid 0.7.4", - "winreg 0.6.2", -] - [[package]] name = "reqwest" version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64 0.21.5", - "bytes 1.5.0", + "base64", + "bytes", "encoding_rs", "futures-core", "futures-util", - "h2 0.3.21", - "http 0.2.9", - "http-body 0.4.5", - "hyper 0.14.27", - "hyper-tls 0.5.0", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", "ipnet", "js-sys", "log", "mime", "native-tls", "once_cell", - "percent-encoding 2.3.0", + "percent-encoding", "pin-project-lite", "serde", "serde_json", - "serde_urlencoded 0.7.1", + "serde_urlencoded", "system-configuration", - "tokio 1.33.0", + "tokio", "tokio-native-tls", "tower-service", - "url 2.4.1", + "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg 0.50.0", + "winreg", ] [[package]] @@ -1524,15 +910,6 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", -] - [[package]] name = "rustix" version = "0.38.21" @@ -1561,6 +938,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "sanitise-file-name" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d36299972b96b8ae7e8f04ecbf75fb41a27bf3781af00abcf57609774cb911" + [[package]] name = "schannel" version = "0.1.22" @@ -1599,21 +982,6 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "serde" version = "1.0.190" @@ -1631,7 +999,7 @@ checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] @@ -1640,23 +1008,11 @@ version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ - "itoa 1.0.9", + "itoa", "ryu", "serde", ] -[[package]] -name = "serde_urlencoded" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a" -dependencies = [ - "dtoa", - "itoa 0.4.8", - "serde", - "url 1.7.2", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1664,7 +1020,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 1.0.9", + "itoa", "ryu", "serde", ] @@ -1686,7 +1042,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" dependencies = [ "libc", - "mio 0.8.9", + "mio", "signal-hook", ] @@ -1705,16 +1061,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ - "autocfg 1.1.0", -] - -[[package]] -name = "smallvec" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" -dependencies = [ - "maybe-uninit", + "autocfg", ] [[package]] @@ -1730,7 +1077,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1756,32 +1103,12 @@ dependencies = [ "thread_local", ] -[[package]] -name = "string" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" -dependencies = [ - "bytes 0.4.12", -] - [[package]] name = "strsim" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.38" @@ -1793,18 +1120,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "unicode-xid", -] - [[package]] name = "system-configuration" version = "0.5.1" @@ -1832,9 +1147,9 @@ version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "fastrand", - "redox_syscall 0.4.1", + "redox_syscall", "rustix", "windows-sys", ] @@ -1865,7 +1180,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", ] [[package]] @@ -1874,21 +1189,10 @@ version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "once_cell", ] -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi 0.3.9", -] - [[package]] name = "tinyvec" version = "1.6.0" @@ -1904,40 +1208,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" -[[package]] -name = "tmdb_client" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85199ceb637a648c19e4744d69b5c59e2a4cc1f9936760dc9f042f5e9a4c766" -dependencies = [ - "chrono", - "flate2", - "reqwest 0.9.24", - "serde", - "serde_derive", - "serde_json", - "url 1.7.2", -] - -[[package]] -name = "tokio" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" -dependencies = [ - "bytes 0.4.12", - "futures", - "mio 0.6.23", - "num_cpus", - "tokio-current-thread", - "tokio-executor", - "tokio-io", - "tokio-reactor", - "tokio-tcp", - "tokio-threadpool", - "tokio-timer", -] - [[package]] name = "tokio" version = "1.33.0" @@ -1945,57 +1215,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ "backtrace", - "bytes 1.5.0", + "bytes", "libc", - "mio 0.8.9", + "mio", "num_cpus", "pin-project-lite", "socket2 0.5.5", "windows-sys", ] -[[package]] -name = "tokio-buf" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" -dependencies = [ - "bytes 0.4.12", - "either", - "futures", -] - -[[package]] -name = "tokio-current-thread" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" -dependencies = [ - "futures", - "tokio-executor", -] - -[[package]] -name = "tokio-executor" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" -dependencies = [ - "crossbeam-utils", - "futures", -] - -[[package]] -name = "tokio-io" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" -dependencies = [ - "bytes 0.4.12", - "futures", - "log", -] - [[package]] name = "tokio-native-tls" version = "0.3.1" @@ -2003,79 +1231,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", - "tokio 1.33.0", -] - -[[package]] -name = "tokio-reactor" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" -dependencies = [ - "crossbeam-utils", - "futures", - "lazy_static", - "log", - "mio 0.6.23", - "num_cpus", - "parking_lot 0.9.0", - "slab", - "tokio-executor", - "tokio-io", - "tokio-sync", -] - -[[package]] -name = "tokio-sync" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" -dependencies = [ - "fnv", - "futures", -] - -[[package]] -name = "tokio-tcp" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" -dependencies = [ - "bytes 0.4.12", - "futures", - "iovec", - "mio 0.6.23", - "tokio-io", - "tokio-reactor", -] - -[[package]] -name = "tokio-threadpool" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df720b6581784c118f0eb4310796b12b1d242a7eb95f716a8367855325c25f89" -dependencies = [ - "crossbeam-deque", - "crossbeam-queue", - "crossbeam-utils", - "futures", - "lazy_static", - "log", - "num_cpus", - "slab", - "tokio-executor", -] - -[[package]] -name = "tokio-timer" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" -dependencies = [ - "crossbeam-utils", - "futures", - "slab", - "tokio-executor", + "tokio", ] [[package]] @@ -2084,11 +1240,11 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ - "bytes 1.5.0", + "bytes", "futures-core", "futures-sink", "pin-project-lite", - "tokio 1.33.0", + "tokio", "tracing", ] @@ -2123,24 +1279,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" -[[package]] -name = "try_from" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b" -dependencies = [ - "cfg-if 0.1.10", -] - -[[package]] -name = "unicase" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - [[package]] name = "unicode-bidi" version = "0.3.13" @@ -2174,23 +1312,6 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - -[[package]] -name = "url" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -dependencies = [ - "idna 0.1.5", - "matches", - "percent-encoding 1.0.1", -] - [[package]] name = "url" version = "2.4.1" @@ -2198,8 +1319,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", - "idna 0.4.0", - "percent-encoding 2.3.0", + "idna", + "percent-encoding", ] [[package]] @@ -2214,15 +1335,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" -[[package]] -name = "uuid" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" -dependencies = [ - "rand", -] - [[package]] name = "uuid" version = "1.5.0" @@ -2235,12 +1347,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - [[package]] name = "walkdir" version = "2.4.0" @@ -2251,17 +1357,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "want" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" -dependencies = [ - "futures", - "log", - "try-lock", -] - [[package]] name = "want" version = "0.3.1" @@ -2271,12 +1366,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -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" @@ -2289,7 +1378,7 @@ version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] @@ -2304,7 +1393,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn", "wasm-bindgen-shared", ] @@ -2314,7 +1403,7 @@ version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "js-sys", "wasm-bindgen", "web-sys", @@ -2338,7 +1427,7 @@ checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2359,12 +1448,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" - [[package]] name = "winapi" version = "0.3.9" @@ -2375,12 +1458,6 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -2393,7 +1470,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2477,31 +1554,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" -[[package]] -name = "winreg" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" -dependencies = [ - "winapi 0.3.9", -] - [[package]] name = "winreg" version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "windows-sys", ] - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] diff --git a/Cargo.toml b/Cargo.toml index aef1589..414d857 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,12 +8,13 @@ edition = "2021" [dependencies] clap = { version = "4.4.7", features = ["derive"] } infer = "0.15.0" +inline_colorization = "0.1.6" inquire = "0.6.2" log = "0.4.20" reqwest = { version = "0.11.22", features = ["json", "blocking"] } +sanitise-file-name = "1.0.0" serde = { version = "1.0.190", features = ["derive"] } serde_json = "1.0.108" stderrlog = "0.5.4" -tmdb_client = "1.6.0" urlencoding = "2.1.3" walkdir = "2.4.0" diff --git a/src/directory.rs b/src/directory.rs index 60c751d..16470c6 100644 --- a/src/directory.rs +++ b/src/directory.rs @@ -1,6 +1,8 @@ use std::{path::PathBuf, fs::{self, DirEntry}, error::Error}; -use crate::{media::handle_media, config::Config}; +use log::trace; + +use crate::{movie::{handle_movie_files_and_folders, self, Move}, config::Config}; /*fn is_not_hidden(entry: &DirEntry) -> bool { entry @@ -20,17 +22,17 @@ pub fn walk_path(path: PathBuf) -> Vec { entries }*/ -pub fn search_path(path: PathBuf, cfg: Config) -> Result<(), Box> { +pub fn search_path(path: PathBuf, cfg: Config) -> Result, Box> { let entries = fs::read_dir(path)?; let mut files: Vec = Vec::new(); - let mut dirs: Vec = Vec::new(); + let mut folders: Vec = Vec::new(); // Put all files and folders in corresponding vectors for entry in entries { if let Ok(entry) = entry { if let Ok(file_type) = entry.file_type() { if file_type.is_dir() { - dirs.push(entry); + folders.push(entry); } else if file_type.is_file() { files.push(entry); } @@ -38,14 +40,15 @@ pub fn search_path(path: PathBuf, cfg: Config) -> Result<(), Box> { } } - if dirs.len() == 0 { - // No folders present, assuming there are only distinct media files - for file in files { - handle_media(file, cfg.clone()); - } - } + folders.sort_by(|a, b| b.metadata().unwrap().len().cmp(&a.metadata().unwrap().len())); + files.sort_by(|a, b| b.metadata().unwrap().len().cmp(&a.metadata().unwrap().len())); + trace!("Sorted Dirs: {:#?}", folders); + trace!("Sorted Files: {:#?}", files); - Ok(()) + let mut moves: Vec = Vec::new(); + moves.append(&mut handle_movie_files_and_folders(files, folders, cfg.clone())); + + Ok(moves) } /* diff --git a/src/main.rs b/src/main.rs index a8d3492..c14447e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ mod config; mod directory; -mod media; +mod movie; use log::*; use clap::Parser; @@ -21,6 +21,14 @@ struct Args { #[arg(short, long)] first_run: bool, + /// Move files rather than copying them + #[arg(short, long, name="move")] + moov: bool, + + /// Look for shows instead of movies + #[arg(short, long)] + shows: bool, + /// Custom config file #[arg(short, long, value_name = "FILE")] config: Option, @@ -64,8 +72,14 @@ fn main() { }; //let files = directory::walk_path(search_path); - directory::search_path(search_path, cfg).unwrap(); + let moves = directory::search_path(search_path, cfg).unwrap(); + + for move_file in moves { + info!("Moving: {:#?}: {:#?}", args.moov, move_file); + _ = move_file.from; + _ = move_file.to; + } /*for file in files.clone() { info!("Found: {}", file.to_str().unwrap()); }*/ diff --git a/src/media.rs b/src/media.rs deleted file mode 100644 index e51e7da..0000000 --- a/src/media.rs +++ /dev/null @@ -1,182 +0,0 @@ -use std::{path::PathBuf, error::Error, io::Read, fs::{File, DirEntry}, cmp, fmt, ops::Deref}; -use infer; -use inquire::Select; -use log::{info, warn, error, trace, debug}; -use serde::Deserialize; -use urlencoding::encode; - -use crate::config::Config; - -#[derive(Deserialize, Debug)] -struct TMDBResponse { - page: i32, - results: Vec, - total_pages: i32, - total_results: i32 -} - -#[derive(Deserialize, Debug)] -struct TMDBEntry { - id: i32, - #[serde(alias = "name")] - title: String, - original_language: Option, - #[serde(alias = "original_name")] - original_title: String, - overview: Option, - media_type: String, - popularity: f32, - #[serde(alias = "first_air_date")] - release_date: Option, -} - -impl fmt::Display for TMDBEntry { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if self.media_type == "movie" { - write!(f, "[MOVIE] {} ({}, {}) (ID: {})", self.title, self.release_date.clone().unwrap_or("unknown".to_string()), self.original_language.as_ref().unwrap(), self.id) - } else if self.media_type == "tv" { - write!(f, "[SHOW] {} ({}, {}) (ID: {})", self.title, self.release_date.clone().unwrap_or("unknown".to_string()), self.original_language.as_ref().unwrap(), self.id) - } else { - write!(f, "[{}] {} (ID: {})", self.media_type, self.title, self.id) - } - } -} - -fn get_file_header(path: PathBuf) -> Result, Box> { - let f = File::open(path)?; - - let limit = f - .metadata() - .map(|m| cmp::min(m.len(), 8192) as usize + 1) - .unwrap_or(0); - let mut bytes = Vec::with_capacity(limit); - f.take(8192).read_to_end(&mut bytes)?; - Ok(bytes) -} - -fn token_valid(t: &&str) -> bool { - if - t.eq_ignore_ascii_case("dvd") || - t.eq_ignore_ascii_case("bluray") || - t.eq_ignore_ascii_case("webrip") || - t.eq_ignore_ascii_case("youtube") || - t.eq_ignore_ascii_case("download") || - t.eq_ignore_ascii_case("web") || - t.eq_ignore_ascii_case("uhd") || - t.eq_ignore_ascii_case("hd") || - t.eq_ignore_ascii_case("tv") || - t.eq_ignore_ascii_case("tvrip") || - t.eq_ignore_ascii_case("1080p") || - t.eq_ignore_ascii_case("1080i") || - t.eq_ignore_ascii_case("2160p") || - t.eq_ignore_ascii_case("x264") || - t.eq_ignore_ascii_case("x265") || - t.eq_ignore_ascii_case("h265") || - t.eq_ignore_ascii_case("dts") || - t.eq_ignore_ascii_case("hevc") || - t.eq_ignore_ascii_case("10bit") || - t.eq_ignore_ascii_case("12bit") || - t.eq_ignore_ascii_case("hdr") || - t.eq_ignore_ascii_case("xvid") || - t.eq_ignore_ascii_case("AAC5") || - t.eq_ignore_ascii_case("AAC") || - t.eq_ignore_ascii_case("AC3") || - t.eq_ignore_ascii_case("sample") || // This just removes the word sample, maybe we want to ban files with the word sample all together - (t.starts_with('[') || t.ends_with(']')) || - (t.starts_with('(') || t.ends_with(')')) || - (t.starts_with('{') || t.ends_with('}')) - { - return false; - } - true -} - -fn tokenize_media_name(file_name: String) -> Vec { - let mut tokens: Vec = file_name.split(&['-', ' ', ':', '@', '.'][..]).filter(|t| token_valid(t)).map(String::from).collect(); - trace!("Tokens are: {:#?}", tokens); - - // Remove last token (file ext) - _ = tokens.pop(); - tokens -} - -fn lookup_media(file_name: PathBuf, mut name_tokens: Vec, cfg: Config) -> Option { - let mut h = reqwest::header::HeaderMap::new(); - h.insert("Accept", reqwest::header::HeaderValue::from_static("application/json")); - h.insert("Authorization", reqwest::header::HeaderValue::from_str(format!("Bearer {}", cfg.tmdb_key).as_str()).unwrap()); - - let client = reqwest::blocking::Client::builder() - .default_headers(h) - .build().unwrap(); - - let mut response: TMDBResponse; - loop { - if name_tokens.len() == 0 { - error!("Could not find title on TMDB!"); - return None; - } - - let name = name_tokens.join(" "); - trace!("Searching on TMDB for {:#?}", name); - - let http_response = client - .get(format!("https://api.themoviedb.org/3/search/multi?query={}&include_adult=false&language=en-US&page=1", encode(name.as_str()).into_owned())) - .send().unwrap(); - - response = http_response.json::().unwrap(); - trace!("TMDB Reponse: {:#?}", response); - - if response.total_results == 0 { - name_tokens.pop(); - } else { - break; - } - } - - let options = response.results; - - let ans = Select::new(format!("Select movie or show that matches the file \x1b[93m{}\x1b[0m:", file_name.display()).as_str(), options).prompt(); - match ans { - Ok(choice) => { - debug!("Selected: {:#?}", choice); - return Some(choice); - }, - Err(e) => { - error!("Error while selecting content: {:#?}", e); - return None; - }, - } -} - -fn video_file_handler(entry: DirEntry, cfg: Config) { - let path = entry.path(); - info!("Found video file: {:#?}", path); - - let file_name = path.file_name().unwrap_or_default(); - trace!("File name is: {:#?}", file_name); - - let name_tokens = tokenize_media_name(file_name.to_str().unwrap_or_default().to_string()); - - match lookup_media(entry.path(), name_tokens, cfg) { - Some(entry) => todo!("Save media info in some struct to move media afterwards, or move directly"), - None => {}, - } - -} - -pub fn handle_media(entry: DirEntry, cfg: Config) { - if entry.file_type().is_ok_and(|t| t.is_dir()) { - warn!("Directory passed to handle_media, {:#?} will be skipped", entry); - return - } - - match get_file_header(entry.path()) { - Ok(header) => { - // Handle video files - if infer::is_video(&header) { - video_file_handler(entry, cfg.clone()); - } - }, - Err(error) => error!("Can not get file header for {:#?}, Error: {:#?}", entry, error), - } -} \ No newline at end of file diff --git a/src/movie.rs b/src/movie.rs new file mode 100644 index 0000000..98faad4 --- /dev/null +++ b/src/movie.rs @@ -0,0 +1,339 @@ +use std::{path::PathBuf, error::Error, io::Read, fs::{File, DirEntry}, cmp, fmt}; +use infer; +use inquire::{Select, Text, Confirm}; +use log::{info, warn, error, trace, debug}; +use reqwest::{blocking::Client, header::{HeaderMap, HeaderValue}}; +use serde::Deserialize; +use urlencoding::encode; +use inline_colorization::*; +use sanitise_file_name::sanitise; +use walkdir::WalkDir; + +use crate::{config::Config, directory::search_path}; + +#[derive(Deserialize, Debug)] +struct TMDBResponse { + results: Vec, + total_results: i32 +} + +#[derive(Deserialize, Debug, Clone)] +struct TMDBEntry { + id: i32, + #[serde(alias = "name")] + title: String, + original_language: Option, + media_type: String, + #[serde(alias = "first_air_date")] + release_date: Option, +} + +impl fmt::Display for TMDBEntry { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.media_type == "movie" { + write!(f, "[MOVIE] {} ({}, {}) (ID: {})", self.title, self.release_date.clone().unwrap_or("unknown".to_string()), self.original_language.as_ref().unwrap(), self.id) + } else if self.media_type == "tv" { + write!(f, "[SHOW] {} ({}, {}) (ID: {})", self.title, self.release_date.clone().unwrap_or("unknown".to_string()), self.original_language.as_ref().unwrap(), self.id) + } else { + write!(f, "[{}] {} (ID: {})", self.media_type, self.title, self.id) + } + } +} + +#[derive(Debug)] +pub struct Move { + pub from: PathBuf, + pub to: PathBuf +} + +fn get_file_header(path: PathBuf) -> Result, Box> { + let f = File::open(path)?; + + let limit = f + .metadata() + .map(|m| cmp::min(m.len(), 8192) as usize + 1) + .unwrap_or(0); + let mut bytes = Vec::with_capacity(limit); + f.take(8192).read_to_end(&mut bytes)?; + Ok(bytes) +} + +fn token_valid(t: &&str) -> bool { + if + t.eq_ignore_ascii_case("dvd") || + t.eq_ignore_ascii_case("bluray") || + t.eq_ignore_ascii_case("webrip") || + t.eq_ignore_ascii_case("youtube") || + t.eq_ignore_ascii_case("download") || + t.eq_ignore_ascii_case("web") || + t.eq_ignore_ascii_case("uhd") || + t.eq_ignore_ascii_case("hd") || + t.eq_ignore_ascii_case("tv") || + t.eq_ignore_ascii_case("tvrip") || + t.eq_ignore_ascii_case("1080p") || + t.eq_ignore_ascii_case("1080i") || + t.eq_ignore_ascii_case("2160p") || + t.eq_ignore_ascii_case("x264") || + t.eq_ignore_ascii_case("x265") || + t.eq_ignore_ascii_case("h265") || + t.eq_ignore_ascii_case("dts") || + t.eq_ignore_ascii_case("hevc") || + t.eq_ignore_ascii_case("10bit") || + t.eq_ignore_ascii_case("12bit") || + t.eq_ignore_ascii_case("hdr") || + t.eq_ignore_ascii_case("xvid") || + t.eq_ignore_ascii_case("AAC5") || + t.eq_ignore_ascii_case("AAC") || + t.eq_ignore_ascii_case("AC3") || + t.eq_ignore_ascii_case("sample") || // This just removes the word sample, maybe we want to ban files with the word sample all together + (t.starts_with('[') || t.ends_with(']')) || + (t.starts_with('(') || t.ends_with(')')) || + (t.starts_with('{') || t.ends_with('}')) + { + return false; + } + true +} + +fn tokenize_media_name(file_name: String) -> Vec { + let mut tokens: Vec = file_name.split(&['-', ' ', ':', '@', '.'][..]).filter(|t| token_valid(t)).map(String::from).collect(); + trace!("Tokens are: {:#?}", tokens); + + // Remove last token (file ext) + _ = tokens.pop(); + tokens +} + +fn lookup_media(file_name: PathBuf, mut name_tokens: Vec, cfg: Config) -> Option { + let mut h = HeaderMap::new(); + h.insert("Accept", HeaderValue::from_static("application/json")); + h.insert("Authorization", HeaderValue::from_str(format!("Bearer {}", cfg.tmdb_key).as_str()).unwrap()); + + let client = Client::builder() + .default_headers(h) + .build().unwrap(); + + let mut response: TMDBResponse; + loop { + if name_tokens.len() == 0 { + error!("Could not find title on TMDB!"); + return None; + } + + let name = name_tokens.join(" "); + trace!("Searching on TMDB for {:#?}", name); + + let http_response = client + .get(format!("https://api.themoviedb.org/3/search/multi?query={}&include_adult=false&language=en-US&page=1", encode(name.as_str()).into_owned())) + .send().unwrap(); + + response = http_response.json::().unwrap(); + trace!("TMDB Reponse: {:#?}", response); + + if response.total_results == 0 { + name_tokens.pop(); + } else { + break; + } + } + + let options = response.results; + + let ans = Select::new(format!("Select movie or show that matches the file {style_bold}{}{style_reset}:", file_name.display()).as_str(), options).prompt(); + match ans { + Ok(choice) => { + debug!("Selected: {:#?}", choice); + return Some(choice); + }, + Err(e) => { + error!("Error while selecting content: {:#?}", e); + return None; + }, + } +} + +fn video_file_handler(entry: PathBuf, cfg: Config) -> Option { + info!("Found video file: {:#?}", entry); + + let file_name = entry.file_name().unwrap_or_default(); + trace!("File name is: {:#?}", file_name); + + let name_tokens = tokenize_media_name(file_name.to_str().unwrap_or_default().to_string()); + + lookup_media(entry, name_tokens, cfg) +} + +pub fn handle_movie_files_and_folders(files: Vec, folders: Vec, cfg: Config) -> Vec { + let mut moves: Vec = Vec::new(); + let mut primary_media: Option = None; // Assuming first file (biggest file) is primary media, store the information of this, for the rest, do lazy matching for extra content/subs and so on + for file in files { + check_movie_file(file.path(), &mut primary_media, &cfg, &mut moves); + } + match primary_media { + Some(_) => { + // There is already primary media, check directories for more media for same movie + for folder in folders { + for entry in WalkDir::new(folder.path()) { + match entry { + Ok(entry) => { + if entry.file_type().is_file() { + check_movie_file(entry.into_path(), &mut primary_media, &cfg, &mut moves); + } + }, + Err(e) => { + error!("Error walking the directory: {:#?}", e); + continue; + } + } + } + } + }, + None => { + // There is no primary media yet, try every folder as main folder + for folder in folders { + moves.append(&mut search_path(folder.path(), cfg.clone()).unwrap()); + } + } + } + moves +} + +fn check_movie_file(file: PathBuf, primary_media: &mut Option, cfg: &Config, moves: &mut Vec) { + trace!("Checking {:#?}", file); + match get_file_header(file.clone()) { + Ok(header) => { + // Handle video files + if infer::is_video(&header) { + match primary_media.as_ref() { + None => { + // No primary media found yet, look up media on TMDB + match video_file_handler(file.clone(), cfg.clone()) { + Some(meta) => { + *primary_media = Some(meta.clone()); + let original_path = file; + let ext = original_path.extension().unwrap_or_default(); + let new_path = cfg.plex_library.join(format!("Movies/{0} {{tmdb-{1}}}/{0} {{tmdb-{1}}}.{2}", sanitise(meta.title.as_str()), meta.id, ext.to_str().unwrap_or_default())); + moves.push(Move { from: original_path, to: new_path }); + }, + None => { + warn!("Could not find a TMDB entry for {:#?}", file); + return; + }, + } + }, + Some(primary_media) => { + // No additional TMDB lookup needed, treat media as extras + let extra_types: Vec<&str> = vec!["Ignore", "Edition", "Behind The Scenes", "Deleted Scenes", "Featurettes", "Interviews", "Scenes", "Shorts", "Trailers", "Other"]; + let ans = Select::new(format!("Select extra type {style_bold}{}{style_reset} (Ignore to ignore the file, Edition to treat it as alternate edition of the main movie):", file.display()).as_str(), extra_types).prompt(); + + match ans { + Ok(choice) => { + if choice == "Ignore" { + // Ignoring the given file + return; + } + if choice == "Edition" { + // Treat the given file as different edition of main movie + let edition_name = Text::new("Specify the edition's name (e.g. Director's Cut, Theatrical Version):").prompt(); + match edition_name { + Ok(edition_name) => { + let original_path = file; + let ext = original_path.extension().unwrap_or_default(); + let new_path = cfg.plex_library.join(format!("Movies/{0} {{tmdb-{1}}}/{0} {{tmdb-{1}}} {{edition-{3}}}.{2}", sanitise(primary_media.title.as_str()), primary_media.id, ext.to_str().unwrap_or_default(), edition_name)); + moves.push(Move { from: original_path, to: new_path }); + return; + }, + Err(e) => { + error!("There was an error: {:#?}", e); + return; + }, + } + } + let initial_value = file.file_stem().unwrap_or_default().to_str().unwrap_or_default(); + let description = Text::new(format!("Give this {} a descriptive name:", choice).as_str()).with_initial_value(initial_value).prompt(); + match description { + Ok(description) => { + let original_path = file; + let ext = original_path.extension().unwrap_or_default(); + let new_path = cfg.plex_library.join(format!("Movies/{0} {{tmdb-{1}}}/{3}/{4}.{2}", sanitise(primary_media.title.as_str()), primary_media.id, ext.to_str().unwrap_or_default(), choice, description)); + moves.push(Move { from: original_path, to: new_path }); + return; + }, + Err(e) => { + error!("There was an error: {:#?}", e); + return; + }, + } + }, + Err(e) => { + error!("There was an error: {:#?}", e); + return; + }, + } + } + } + } else { + match file.extension() { + Some(ext) => { + if ext.eq_ignore_ascii_case("srt") || + ext.eq_ignore_ascii_case("ass") || + ext.eq_ignore_ascii_case("ssa") || + ext.eq_ignore_ascii_case("smi") || + ext.eq_ignore_ascii_case("pgs") || + ext.eq_ignore_ascii_case("vob") { + // Subtitle file + if primary_media.is_none() { + warn!("Can not categorize subtitle file without primary media, skipping."); + return; + } + + let lang_code = Text::new(format!("Specify ISO-639-1 (2-letter) language code (e.g. 'en', 'de') or leave empty to discard for {style_bold}{}{style_reset}:", file.display()).as_str()).prompt(); + match lang_code { + Ok(lang_code) => { + if lang_code == "" { + return; + } + let forced = Confirm::new("Is this a forced sub?").with_default(false).prompt(); + match forced { + Ok(true) => { + // Forced + let original_path = file; + let ext = original_path.extension().unwrap_or_default(); + let new_path = cfg.plex_library.join(format!("Movies/{0} {{tmdb-{1}}}/{0} {{tmdb-{1}}}.{3}.forced.{2}", sanitise(primary_media.as_ref().unwrap().title.as_str()), primary_media.as_ref().unwrap().id, ext.to_str().unwrap_or_default(), lang_code.to_ascii_lowercase())); + moves.push(Move { from: original_path, to: new_path }); + return; + }, + Ok(false) => { + // Non-forced + let original_path = file; + let ext = original_path.extension().unwrap_or_default(); + let new_path = cfg.plex_library.join(format!("Movies/{0} {{tmdb-{1}}}/{0} {{tmdb-{1}}}.{3}.{2}", sanitise(primary_media.as_ref().unwrap().title.as_str()), primary_media.as_ref().unwrap().id, ext.to_str().unwrap_or_default(), lang_code.to_ascii_lowercase())); + moves.push(Move { from: original_path, to: new_path }); + return; + }, + Err(e) => { + error!("There was an error: {:#?}", e); + return; + }, + } + }, + Err(e) => { + error!("There was an error: {:#?}", e); + return; + }, + } + } else { + info!("Not a video file nor subtitle, skipping"); + return; + } + }, + None => { + error!("File {:#?} has no file extension", file); + return; + } + } + } + }, + Err(error) => error!("Can not get file header for {:#?}, Error: {:#?}", file, error), + } +} \ No newline at end of file