diff --git a/Cargo.lock b/Cargo.lock
index d01a80c..b9dce7b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -92,9 +92,9 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.86"
+version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
+checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519"
[[package]]
name = "async-speed-limit"
@@ -119,12 +119,6 @@ dependencies = [
"syn",
]
-[[package]]
-name = "atomic-waker"
-version = "1.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
-
[[package]]
name = "autocfg"
version = "1.3.0"
@@ -194,9 +188,9 @@ checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
[[package]]
name = "cc"
-version = "1.0.98"
+version = "1.0.96"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f"
+checksum = "065a29261d53ba54260972629f9ca6bffa69bac13cd1fed61420f7fa68b9f8bd"
[[package]]
name = "cfg-if"
@@ -244,7 +238,7 @@ dependencies = [
"anstream",
"anstyle",
"clap_lex",
- "strsim",
+ "strsim 0.11.1",
]
[[package]]
@@ -349,7 +343,7 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]]
name = "crunchy-cli"
-version = "3.6.7"
+version = "3.6.0"
dependencies = [
"chrono",
"clap",
@@ -362,7 +356,7 @@ dependencies = [
[[package]]
name = "crunchy-cli-core"
-version = "3.6.7"
+version = "3.6.0"
dependencies = [
"anyhow",
"async-speed-limit",
@@ -392,7 +386,6 @@ dependencies = [
"shlex",
"sys-locale",
"tempfile",
- "time",
"tokio",
"tokio-util",
"tower-service",
@@ -400,9 +393,9 @@ dependencies = [
[[package]]
name = "crunchyroll-rs"
-version = "0.11.4"
+version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6e38c223aecf65c9c9bec50764beea5dc70b6c97cd7f767bf6860f2fc8e0a07"
+checksum = "58580acc9c0abf96a231ec8b1a4597ea55d9426ea17f684ce3582e2b26437bbb"
dependencies = [
"async-trait",
"chrono",
@@ -426,9 +419,9 @@ dependencies = [
[[package]]
name = "crunchyroll-rs-internal"
-version = "0.11.4"
+version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "144a38040a21aaa456741a9f6749354527bb68ad3bb14210e0bbc40fbd95186c"
+checksum = "ce3c844dec8a3390f8c9853b5cf1d65c3d38fd0657b8b5d0e008db8945dea326"
dependencies = [
"darling",
"quote",
@@ -447,9 +440,9 @@ dependencies = [
[[package]]
name = "darling"
-version = "0.20.9"
+version = "0.20.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1"
+checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391"
dependencies = [
"darling_core",
"darling_macro",
@@ -457,23 +450,23 @@ dependencies = [
[[package]]
name = "darling_core"
-version = "0.20.9"
+version = "0.20.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120"
+checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
- "strsim",
+ "strsim 0.10.0",
"syn",
]
[[package]]
name = "darling_macro"
-version = "0.20.9"
+version = "0.20.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
+checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
dependencies = [
"darling_core",
"quote",
@@ -482,13 +475,12 @@ dependencies = [
[[package]]
name = "dash-mpd"
-version = "0.16.3"
+version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4618a5e165bf47b084963611bcf1d568c681f52d8a237e8862a0cd8c546ba255"
+checksum = "79b4bdd5f1c0c7493d780c645f0bff5b9361e6408210fa88910adb181efca64c"
dependencies = [
"base64 0.22.1",
"base64-serde",
- "bytes",
"chrono",
"fs-err",
"iso8601",
@@ -561,9 +553,9 @@ dependencies = [
[[package]]
name = "either"
-version = "1.12.0"
+version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"
+checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2"
[[package]]
name = "encode_unicode"
@@ -588,9 +580,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
-version = "0.3.9"
+version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
+checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
dependencies = [
"libc",
"windows-sys 0.52.0",
@@ -720,9 +712,9 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.15"
+version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
+checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"
dependencies = [
"cfg-if",
"js-sys",
@@ -739,15 +731,15 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
[[package]]
name = "h2"
-version = "0.4.5"
+version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab"
+checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069"
dependencies = [
- "atomic-waker",
"bytes",
"fnv",
"futures-core",
"futures-sink",
+ "futures-util",
"http",
"indexmap 2.2.6",
"slab",
@@ -985,9 +977,9 @@ dependencies = [
[[package]]
name = "instant"
-version = "0.1.13"
+version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222"
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if",
]
@@ -1049,9 +1041,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
-version = "0.2.155"
+version = "0.2.154"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
+checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346"
[[package]]
name = "libredox"
@@ -1065,9 +1057,9 @@ dependencies = [
[[package]]
name = "linux-raw-sys"
-version = "0.4.14"
+version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
[[package]]
name = "log"
@@ -1105,9 +1097,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
-version = "0.7.3"
+version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae"
+checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
dependencies = [
"adler",
]
@@ -1125,8 +1117,8 @@ dependencies = [
[[package]]
name = "native-tls"
-version = "0.2.12"
-source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=c7ac566#c7ac566559d441bbc3e5e5bd04fb7162c38d88b0"
+version = "0.2.11"
+source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=fdba246#fdba246a79986607cbdf573733445498bb6da2a9"
dependencies = [
"libc",
"log",
@@ -1163,9 +1155,9 @@ dependencies = [
[[package]]
name = "num-complex"
-version = "0.4.6"
+version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
+checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6"
dependencies = [
"num-traits",
]
@@ -1259,9 +1251,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-src"
-version = "300.3.0+3.3.0"
+version = "300.2.3+3.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eba8804a1c5765b18c4b3f907e6897ebabeedebc9830e1a0046c4a4cf44663e1"
+checksum = "5cff92b6f71555b61bb9315f7c64da3ca43d87531622120fea0195fc761b4843"
dependencies = [
"cc",
]
@@ -1352,9 +1344,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.83"
+version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43"
+checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
dependencies = [
"unicode-ident",
]
@@ -1519,13 +1511,12 @@ checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316"
[[package]]
name = "rsubs-lib"
-version = "0.3.2"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c9f50e3fbcbf1f0bd109954e2dd813d1715c7b4a92a7bf159a85dea49e9d863"
+checksum = "0df7559a05635a4132b737c736ee286af83f3969cb98d9028d17d333e6b41cc5"
dependencies = [
"regex",
"serde",
- "time",
]
[[package]]
@@ -1542,9 +1533,9 @@ dependencies = [
[[package]]
name = "rustc-demangle"
-version = "0.1.24"
+version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
+checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
[[package]]
name = "rustfft"
@@ -1613,15 +1604,15 @@ dependencies = [
[[package]]
name = "rustls-pki-types"
-version = "1.7.0"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d"
+checksum = "beb461507cee2c2ff151784c52762cf4d9ff6a61f3e80968600ed24fa837fa54"
[[package]]
name = "rustls-webpki"
-version = "0.102.4"
+version = "0.102.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e"
+checksum = "f3bce581c0dd41bce533ce695a1437fa16a7ab5ac3ccfa99fe1a620a7885eabf"
dependencies = [
"ring",
"rustls-pki-types",
@@ -1640,9 +1631,9 @@ dependencies = [
[[package]]
name = "ryu"
-version = "1.0.18"
+version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
+checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
[[package]]
name = "schannel"
@@ -1655,11 +1646,11 @@ dependencies = [
[[package]]
name = "security-framework"
-version = "2.11.0"
+version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0"
+checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6"
dependencies = [
- "bitflags 2.5.0",
+ "bitflags 1.3.2",
"core-foundation",
"core-foundation-sys",
"libc",
@@ -1668,9 +1659,9 @@ dependencies = [
[[package]]
name = "security-framework-sys"
-version = "2.11.0"
+version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7"
+checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef"
dependencies = [
"core-foundation-sys",
"libc",
@@ -1678,18 +1669,18 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.202"
+version = "1.0.200"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395"
+checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.202"
+version = "1.0.200"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838"
+checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb"
dependencies = [
"proc-macro2",
"quote",
@@ -1698,9 +1689,9 @@ dependencies = [
[[package]]
name = "serde_json"
-version = "1.0.117"
+version = "1.0.116"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
+checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
dependencies = [
"itoa",
"ryu",
@@ -1828,6 +1819,12 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82"
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
[[package]]
name = "strsim"
version = "0.11.1"
@@ -1842,9 +1839,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]]
name = "syn"
-version = "2.0.65"
+version = "2.0.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106"
+checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3"
dependencies = [
"proc-macro2",
"quote",
@@ -1901,18 +1898,18 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "1.0.61"
+version = "1.0.59"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
+checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.61"
+version = "1.0.59"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
+checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66"
dependencies = [
"proc-macro2",
"quote",
@@ -1967,9 +1964,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.38.0"
+version = "1.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
+checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787"
dependencies = [
"backtrace",
"bytes",
@@ -1984,9 +1981,9 @@ dependencies = [
[[package]]
name = "tokio-macros"
-version = "2.3.0"
+version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
+checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
dependencies = [
"proc-macro2",
"quote",
diff --git a/Cargo.toml b/Cargo.toml
index c1e28bb..fe7b301 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "crunchy-cli"
authors = ["Crunchy Labs Maintainers"]
-version = "3.6.7"
+version = "3.6.0"
edition = "2021"
license = "MIT"
@@ -14,9 +14,9 @@ openssl-tls = ["dep:native-tls-crate", "native-tls-crate/openssl", "crunchy-cli-
openssl-tls-static = ["dep:native-tls-crate", "native-tls-crate/openssl", "crunchy-cli-core/openssl-tls-static"]
[dependencies]
-tokio = { version = "1.38", features = ["macros", "rt-multi-thread", "time"], default-features = false }
+tokio = { version = "1.37", features = ["macros", "rt-multi-thread", "time"], default-features = false }
-native-tls-crate = { package = "native-tls", version = "0.2.12", optional = true }
+native-tls-crate = { package = "native-tls", version = "0.2.11", optional = true }
crunchy-cli-core = { path = "./crunchy-cli-core" }
@@ -34,7 +34,7 @@ members = ["crunchy-cli-core"]
[patch.crates-io]
# fork of the `native-tls` crate which can use openssl as backend on every platform. this is done as `reqwest` only
# supports `rustls` and `native-tls` as tls backend
-native-tls = { git = "https://github.com/crunchy-labs/rust-not-so-native-tls.git", rev = "c7ac566" }
+native-tls = { git = "https://github.com/crunchy-labs/rust-not-so-native-tls.git", rev = "fdba246" }
[profile.release]
strip = true
diff --git a/README.md b/README.md
index 1ae2645..1735a6e 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,6 @@
-# This project has been sunset as Crunchyroll moved to a DRM-only system. See [#362](https://github.com/crunchy-labs/crunchy-cli/issues/362).
+> ~~This project has been sunset as Crunchyroll moved to a DRM-only system. See [#362](https://github.com/crunchy-labs/crunchy-cli/issues/362).~~
+>
+> Well there is one endpoint which still has DRM-free streams, I guess I still have a bit time until (finally) everything is DRM-only.
# crunchy-cli
@@ -20,8 +22,8 @@
-
-
+
+
diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml
index 399053f..896b68f 100644
--- a/crunchy-cli-core/Cargo.toml
+++ b/crunchy-cli-core/Cargo.toml
@@ -1,7 +1,7 @@
[package]
name = "crunchy-cli-core"
authors = ["Crunchy Labs Maintainers"]
-version = "3.6.7"
+version = "3.6.0"
edition = "2021"
license = "MIT"
@@ -16,7 +16,7 @@ anyhow = "1.0"
async-speed-limit = "0.4"
clap = { version = "4.5", features = ["derive", "string"] }
chrono = "0.4"
-crunchyroll-rs = { version = "0.11.4", features = ["experimental-stabilizations", "tower"] }
+crunchyroll-rs = { version = "0.11.1", features = ["experimental-stabilizations", "tower"] }
ctrlc = "3.4"
dialoguer = { version = "0.11", default-features = false }
dirs = "5.0"
@@ -30,7 +30,7 @@ log = { version = "0.4", features = ["std"] }
num_cpus = "1.16"
regex = "1.10"
reqwest = { version = "0.12", features = ["socks", "stream"] }
-rsubs-lib = "~0.3.2"
+rsubs-lib = "0.2"
rusty-chromaprint = "0.2"
serde = "1.0"
serde_json = "1.0"
@@ -38,8 +38,7 @@ serde_plain = "1.0"
shlex = "1.3"
sys-locale = "0.3"
tempfile = "3.10"
-time = "0.3"
-tokio = { version = "1.38", features = ["io-util", "macros", "net", "rt-multi-thread", "time"] }
+tokio = { version = "1.37", features = ["io-util", "macros", "net", "rt-multi-thread", "time"] }
tokio-util = "0.7"
tower-service = "0.3"
rustls-native-certs = { version = "0.7", optional = true }
diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs
index 0d1b3a4..38bddc1 100644
--- a/crunchy-cli-core/src/archive/command.rs
+++ b/crunchy-cli-core/src/archive/command.rs
@@ -1,9 +1,10 @@
+use crate::archive::filter::ArchiveFilter;
use crate::utils::context::Context;
use crate::utils::download::{
DownloadBuilder, DownloadFormat, DownloadFormatMetadata, MergeBehavior,
};
use crate::utils::ffmpeg::FFmpegPreset;
-use crate::utils::filter::{Filter, FilterMediaScope};
+use crate::utils::filter::Filter;
use crate::utils::format::{Format, SingleFormat};
use crate::utils::locale::{all_locale_in_locales, resolve_locales, LanguageTagging};
use crate::utils::log::progress;
@@ -233,10 +234,6 @@ impl Execute for Archive {
bail!("`--include-chapters` can only be used if `--merge` is set to 'audio' or 'sync'")
}
- if !self.skip_existing_method.is_empty() && !self.skip_existing {
- warn!("`--skip-existing-method` has no effect if `--skip-existing` is not set")
- }
-
self.audio = all_locale_in_locales(self.audio.clone());
self.subtitle = all_locale_in_locales(self.subtitle.clone());
@@ -283,49 +280,9 @@ impl Execute for Archive {
for (i, (media_collection, url_filter)) in parsed_urls.into_iter().enumerate() {
let progress_handler = progress!("Fetching series details");
- let single_format_collection = Filter::new(
+ let single_format_collection = ArchiveFilter::new(
url_filter,
- self.audio.clone(),
- self.subtitle.clone(),
- |scope, locales| {
- let audios = locales.into_iter().map(|l| l.to_string()).collect::>().join(", ");
- match scope {
- FilterMediaScope::Series(series) => warn!("Series {} is not available with {} audio", series.title, audios),
- FilterMediaScope::Season(season) => warn!("Season {} is not available with {} audio", season.season_number, audios),
- FilterMediaScope::Episode(episodes) => {
- if episodes.len() == 1 {
- warn!("Episode {} is not available with {} audio", episodes[0].sequence_number, audios)
- } else if episodes.len() == 2 {
- warn!("Season {} is only available with {} audio from episode {} to {}", episodes[0].season_number, audios, episodes[0].sequence_number, episodes[1].sequence_number)
- } else {
- unimplemented!()
- }
- }
- }
- Ok(true)
- },
- |scope, locales| {
- let subtitles = locales.into_iter().map(|l| l.to_string()).collect::>().join(", ");
- match scope {
- FilterMediaScope::Series(series) => warn!("Series {} is not available with {} subtitles", series.title, subtitles),
- FilterMediaScope::Season(season) => warn!("Season {} is not available with {} subtitles", season.season_number, subtitles),
- FilterMediaScope::Episode(episodes) => {
- if episodes.len() == 1 {
- warn!("Episode {} of season {} is not available with {} subtitles", episodes[0].sequence_number, episodes[0].season_title, subtitles)
- } else if episodes.len() == 2 {
- warn!("Season {} of season {} is only available with {} subtitles from episode {} to {}", episodes[0].season_number, episodes[0].season_title, subtitles, episodes[0].sequence_number, episodes[1].sequence_number)
- } else {
- unimplemented!()
- }
- }
- }
- Ok(true)
- },
- |season| {
- warn!("Skipping premium episodes in season {season}");
- Ok(())
- },
- Format::has_relative_fmt(&self.output),
+ self.clone(),
!self.yes,
self.skip_specials,
ctx.crunchy.premium().await,
@@ -540,28 +497,29 @@ async fn get_format(
.subtitle
.iter()
.flat_map(|s| {
- let mut subtitles = vec![];
- if let Some(caption) = stream.captions.get(s) {
- subtitles.push((caption.clone(), true))
- }
- if let Some(subtitle) = stream.subtitles.get(s) {
- // the subtitle is probably cc if the audio is not japanese or only one subtitle
- // exists for this stream
- let cc = single_format.audio != Locale::ja_JP && stream.subtitles.len() == 1;
- // only include the subtitles if no cc subtitle is already present or if it's
- // not cc
- if subtitles.is_empty() || !cc {
- subtitles.push((subtitle.clone(), cc))
- }
- }
+ let subtitles = stream
+ .subtitles
+ .get(s)
+ .cloned()
+ // the subtitle is probably cc if the audio is not japanese or only one
+ // subtitle exists for this stream
+ .map(|l| {
+ (
+ l,
+ single_format.audio != Locale::ja_JP && stream.subtitles.len() == 1,
+ )
+ });
+ let cc = stream.captions.get(s).cloned().map(|l| (l, true));
+
subtitles
+ .into_iter()
+ .chain(cc.into_iter())
+ .collect::>()
})
.collect();
format_pairs.push((single_format, video.clone(), audio, subtitles.clone()));
- single_format_to_format_pairs.push((single_format.clone(), video, subtitles));
-
- stream.invalidate().await?
+ single_format_to_format_pairs.push((single_format.clone(), video, subtitles))
}
let mut download_formats = vec![];
diff --git a/crunchy-cli-core/src/archive/filter.rs b/crunchy-cli-core/src/archive/filter.rs
new file mode 100644
index 0000000..b08fb6c
--- /dev/null
+++ b/crunchy-cli-core/src/archive/filter.rs
@@ -0,0 +1,466 @@
+use crate::archive::command::Archive;
+use crate::utils::filter::{real_dedup_vec, Filter};
+use crate::utils::format::{Format, SingleFormat, SingleFormatCollection};
+use crate::utils::interactive_select::{check_for_duplicated_seasons, get_duplicated_seasons};
+use crate::utils::parse::{fract, UrlFilter};
+use anyhow::Result;
+use crunchyroll_rs::{Concert, Episode, Locale, Movie, MovieListing, MusicVideo, Season, Series};
+use log::{info, warn};
+use std::collections::{BTreeMap, HashMap};
+use std::ops::Not;
+
+enum Visited {
+ Series,
+ Season,
+ None,
+}
+
+pub(crate) struct ArchiveFilter {
+ url_filter: UrlFilter,
+ archive: Archive,
+ interactive_input: bool,
+ skip_special: bool,
+ season_episodes: HashMap>,
+ season_subtitles_missing: Vec,
+ seasons_with_premium: Option>,
+ season_sorting: Vec,
+ visited: Visited,
+}
+
+impl ArchiveFilter {
+ pub(crate) fn new(
+ url_filter: UrlFilter,
+ archive: Archive,
+ interactive_input: bool,
+ skip_special: bool,
+ is_premium: bool,
+ ) -> Self {
+ Self {
+ url_filter,
+ archive,
+ interactive_input,
+ skip_special,
+ season_episodes: HashMap::new(),
+ season_subtitles_missing: vec![],
+ seasons_with_premium: is_premium.not().then_some(vec![]),
+ season_sorting: vec![],
+ visited: Visited::None,
+ }
+ }
+}
+
+impl Filter for ArchiveFilter {
+ type T = Vec;
+ type Output = SingleFormatCollection;
+
+ async fn visit_series(&mut self, series: Series) -> Result> {
+ // `series.audio_locales` isn't always populated b/c of crunchyrolls api. so check if the
+ // audio is matching only if the field is populated
+ if !series.audio_locales.is_empty() {
+ let missing_audio = missing_locales(&series.audio_locales, &self.archive.audio);
+ if !missing_audio.is_empty() {
+ warn!(
+ "Series {} is not available with {} audio",
+ series.title,
+ missing_audio
+ .into_iter()
+ .map(|l| l.to_string())
+ .collect::>()
+ .join(", ")
+ )
+ }
+ let missing_subtitle =
+ missing_locales(&series.subtitle_locales, &self.archive.subtitle);
+ if !missing_subtitle.is_empty() {
+ warn!(
+ "Series {} is not available with {} subtitles",
+ series.title,
+ missing_subtitle
+ .into_iter()
+ .map(|l| l.to_string())
+ .collect::>()
+ .join(", ")
+ )
+ }
+ self.visited = Visited::Series
+ }
+
+ let mut seasons = series.seasons().await?;
+ let mut remove_ids = vec![];
+ for season in seasons.iter_mut() {
+ if !self.url_filter.is_season_valid(season.season_number)
+ || (!season
+ .audio_locales
+ .iter()
+ .any(|l| self.archive.audio.contains(l))
+ && !season
+ .available_versions()
+ .await?
+ .iter()
+ .any(|l| self.archive.audio.contains(l)))
+ {
+ remove_ids.push(season.id.clone());
+ }
+ }
+
+ seasons.retain(|s| !remove_ids.contains(&s.id));
+
+ let duplicated_seasons = get_duplicated_seasons(&seasons);
+ if !duplicated_seasons.is_empty() {
+ if self.interactive_input {
+ check_for_duplicated_seasons(&mut seasons);
+ } else {
+ info!(
+ "Found duplicated seasons: {}",
+ duplicated_seasons
+ .iter()
+ .map(|d| d.to_string())
+ .collect::>()
+ .join(", ")
+ )
+ }
+ }
+
+ Ok(seasons)
+ }
+
+ async fn visit_season(&mut self, mut season: Season) -> Result> {
+ if !self.url_filter.is_season_valid(season.season_number) {
+ return Ok(vec![]);
+ }
+
+ let mut seasons = season.version(self.archive.audio.clone()).await?;
+ if self
+ .archive
+ .audio
+ .iter()
+ .any(|l| season.audio_locales.contains(l))
+ {
+ seasons.insert(0, season.clone());
+ }
+
+ if !matches!(self.visited, Visited::Series) {
+ let mut audio_locales: Vec = seasons
+ .iter()
+ .flat_map(|s| s.audio_locales.clone())
+ .collect();
+ real_dedup_vec(&mut audio_locales);
+ let missing_audio = missing_locales(&audio_locales, &self.archive.audio);
+ if !missing_audio.is_empty() {
+ warn!(
+ "Season {} is not available with {} audio",
+ season.season_number,
+ missing_audio
+ .into_iter()
+ .map(|l| l.to_string())
+ .collect::>()
+ .join(", ")
+ )
+ }
+
+ let subtitle_locales: Vec = seasons
+ .iter()
+ .flat_map(|s| s.subtitle_locales.clone())
+ .collect();
+ let missing_subtitle = missing_locales(&subtitle_locales, &self.archive.subtitle);
+ if !missing_subtitle.is_empty() {
+ warn!(
+ "Season {} is not available with {} subtitles",
+ season.season_number,
+ missing_subtitle
+ .into_iter()
+ .map(|l| l.to_string())
+ .collect::>()
+ .join(", ")
+ )
+ }
+ self.visited = Visited::Season
+ }
+
+ let mut episodes = vec![];
+ for season in seasons {
+ self.season_sorting.push(season.id.clone());
+ let season_locale = if season.audio_locales.len() < 2 {
+ Some(
+ season
+ .audio_locales
+ .first()
+ .cloned()
+ .unwrap_or(Locale::ja_JP),
+ )
+ } else {
+ None
+ };
+ let mut eps = season.episodes().await?;
+ let before_len = eps.len();
+
+ for mut ep in eps.clone() {
+ if let Some(l) = &season_locale {
+ if &ep.audio_locale == l {
+ continue;
+ }
+ eps.remove(eps.iter().position(|p| p.id == ep.id).unwrap());
+ } else {
+ let mut requested_locales = self.archive.audio.clone();
+ if let Some(idx) = requested_locales.iter().position(|p| p == &ep.audio_locale)
+ {
+ requested_locales.remove(idx);
+ } else {
+ eps.remove(eps.iter().position(|p| p.id == ep.id).unwrap());
+ }
+ eps.extend(ep.version(self.archive.audio.clone()).await?);
+ }
+ }
+ if eps.len() < before_len {
+ if eps.is_empty() {
+ if matches!(self.visited, Visited::Series) {
+ warn!(
+ "Season {} is not available with {} audio",
+ season.season_number,
+ season_locale.unwrap_or(Locale::ja_JP)
+ )
+ }
+ } else {
+ let last_episode = eps.last().unwrap();
+ warn!(
+ "Season {} is only available with {} audio until episode {} ({})",
+ season.season_number,
+ season_locale.unwrap_or(Locale::ja_JP),
+ last_episode.sequence_number,
+ last_episode.title
+ )
+ }
+ }
+ episodes.extend(eps)
+ }
+
+ if Format::has_relative_fmt(&self.archive.output) {
+ for episode in episodes.iter() {
+ self.season_episodes
+ .entry(episode.season_id.clone())
+ .or_default()
+ .push(episode.clone())
+ }
+ }
+
+ Ok(episodes)
+ }
+
+ async fn visit_episode(&mut self, mut episode: Episode) -> Result