From 13d8cc26c95f75032d297be6c8e7d37042882dd9 Mon Sep 17 00:00:00 2001 From: ByteDream Date: Thu, 13 Apr 2023 22:47:14 +0200 Subject: [PATCH 001/272] Remove signal-hook dependency --- Cargo.lock | 20 -------------------- crunchy-cli-core/Cargo.lock | 20 -------------------- crunchy-cli-core/Cargo.toml | 1 - 3 files changed, 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7a8cb6a..c8328f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -366,7 +366,6 @@ dependencies = [ "serde", "serde_json", "shlex", - "signal-hook", "sys-locale", "tempfile", "terminal_size", @@ -1623,25 +1622,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" -[[package]] -name = "signal-hook" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - [[package]] name = "slab" version = "0.4.8" diff --git a/crunchy-cli-core/Cargo.lock b/crunchy-cli-core/Cargo.lock index 595596f..a60668a 100644 --- a/crunchy-cli-core/Cargo.lock +++ b/crunchy-cli-core/Cargo.lock @@ -335,7 +335,6 @@ dependencies = [ "serde", "serde_json", "shlex", - "signal-hook", "sys-locale", "tempfile", "terminal_size", @@ -1586,25 +1585,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" -[[package]] -name = "signal-hook" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - [[package]] name = "slab" version = "0.4.8" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 6000843..bbae22e 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -24,7 +24,6 @@ sanitize-filename = "0.4" serde = "1.0" serde_json = "1.0" shlex = "1.1" -signal-hook = "0.3" tempfile = "3.5" terminal_size = "0.2" tokio = { version = "1.27", features = ["macros", "rt-multi-thread", "time"] } From c4a4651164523d87f66dcf454d40f23d355b9757 Mon Sep 17 00:00:00 2001 From: bocchi <121779542+hitorilabs@users.noreply.github.com> Date: Fri, 14 Apr 2023 23:11:58 -0400 Subject: [PATCH 002/272] set default value for locale to empty vec --- crunchy-cli-core/src/archive/command.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index cf24c84..7fadf55 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -31,7 +31,7 @@ pub struct Archive { #[arg(short, long, default_values_t = vec![Locale::ja_JP, crate::utils::locale::system_locale()])] pub(crate) audio: Vec, #[arg(help = "Deprecated. Use '-a' / '--audio' instead")] - #[arg(short, long, default_values_t = vec![Locale::ja_JP, crate::utils::locale::system_locale()])] + #[arg(short, long, default_values_t = Vec::::new())] locale: Vec, #[arg(help = format!("Subtitle languages. Can be used multiple times. \ Available languages are: {}", Locale::all().into_iter().map(|l| l.to_string()).collect::>().join(", ")))] From c0e2df480484394c912d9693ae2c0fb1141273d0 Mon Sep 17 00:00:00 2001 From: bocchi <121779542+hitorilabs@users.noreply.github.com> Date: Fri, 14 Apr 2023 23:25:56 -0400 Subject: [PATCH 003/272] redundant to specify default value --- crunchy-cli-core/src/archive/command.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 7fadf55..580276b 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -31,7 +31,7 @@ pub struct Archive { #[arg(short, long, default_values_t = vec![Locale::ja_JP, crate::utils::locale::system_locale()])] pub(crate) audio: Vec, #[arg(help = "Deprecated. Use '-a' / '--audio' instead")] - #[arg(short, long, default_values_t = Vec::::new())] + #[arg(short, long)] locale: Vec, #[arg(help = format!("Subtitle languages. Can be used multiple times. \ Available languages are: {}", Locale::all().into_iter().map(|l| l.to_string()).collect::>().join(", ")))] From 847c6a1abcb0ca00ec08896f270f2183b3e09b93 Mon Sep 17 00:00:00 2001 From: ByteDream Date: Mon, 17 Apr 2023 18:14:54 +0200 Subject: [PATCH 004/272] Mark CC subtitle track as CC & grab normal subtitles and CC when using -m audio (#141) --- crunchy-cli-core/src/archive/command.rs | 13 +++++--- crunchy-cli-core/src/download/command.rs | 6 ++-- crunchy-cli-core/src/utils/download.rs | 41 ++++++++++++++---------- crunchy-cli-core/src/utils/format.rs | 4 +-- 4 files changed, 38 insertions(+), 26 deletions(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 580276b..a048685 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -242,10 +242,16 @@ async fn get_format( } }; - let subtitles: Vec = archive + let subtitles: Vec<(Subtitle, bool)> = archive .subtitle .iter() - .filter_map(|s| stream.subtitles.get(s).cloned()) + .filter_map(|s| { + stream + .subtitles + .get(s) + .cloned() + .map(|l| (l, single_format.audio == Locale::ja_JP)) + }) .collect(); format_pairs.push((single_format, video.clone(), audio, subtitles.clone())); @@ -278,9 +284,6 @@ async fn get_format( subtitles: format_pairs .iter() .flat_map(|(_, _, _, subtitles)| subtitles.clone()) - .map(|s| (s.locale.clone(), s)) - .collect::>() - .into_values() .collect(), }), MergeBehavior::Auto => { diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index d18320a..142bf9c 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -203,12 +203,14 @@ async fn get_format( let download_format = DownloadFormat { video: (video.clone(), single_format.audio.clone()), audios: vec![(audio, single_format.audio.clone())], - subtitles: subtitle.clone().map_or(vec![], |s| vec![s]), + subtitles: subtitle + .clone() + .map_or(vec![], |s| vec![(s, single_format.audio == Locale::ja_JP)]), }; let format = Format::from_single_formats(vec![( single_format.clone(), video, - subtitle.map_or(vec![], |s| vec![s]), + subtitle.map_or(vec![], |s| vec![(s, single_format.audio == Locale::ja_JP)]), )]); Ok((download_format, format)) diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index f0f51c1..57baf83 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -11,6 +11,7 @@ use log::{debug, warn, LevelFilter}; use regex::Regex; use std::borrow::Borrow; use std::borrow::BorrowMut; +use std::cmp::Ordering; use std::collections::BTreeMap; use std::env; use std::io::Write; @@ -81,7 +82,7 @@ struct FFmpegMeta { pub struct DownloadFormat { pub video: (VariantData, Locale), pub audios: Vec<(VariantData, Locale)>, - pub subtitles: Vec, + pub subtitles: Vec<(Subtitle, bool)>, } pub struct Downloader { @@ -144,12 +145,19 @@ impl Downloader { }) } if let Some(subtitle_sort) = &self.subtitle_sort { - format.subtitles.sort_by(|a, b| { - subtitle_sort - .iter() - .position(|l| l == &a.locale) - .cmp(&subtitle_sort.iter().position(|l| l == &b.locale)) - }) + format + .subtitles + .sort_by(|(a_subtitle, a_not_cc), (b_subtitle, b_not_cc)| { + let ordering = subtitle_sort + .iter() + .position(|l| l == &a_subtitle.locale) + .cmp(&subtitle_sort.iter().position(|l| l == &b_subtitle.locale)); + if matches!(ordering, Ordering::Equal) { + a_not_cc.cmp(b_not_cc).reverse() + } else { + ordering + } + }) } } @@ -191,20 +199,19 @@ impl Downloader { }) } let len = get_video_length(&video_path)?; - for subtitle in format.subtitles.iter() { + for (subtitle, not_cc) in format.subtitles.iter() { let subtitle_path = self.download_subtitle(subtitle.clone(), len).await?; + let mut subtitle_title = subtitle.locale.to_human_readable(); + if !not_cc { + subtitle_title += " (CC)" + } + if i != 0 { + subtitle_title += &format!(" [Video: #{}]", i + 1) + } subtitles.push(FFmpegMeta { path: subtitle_path, language: subtitle.locale.clone(), - title: if i == 0 { - subtitle.locale.to_human_readable() - } else { - format!( - "{} [Video: #{}]", - subtitle.locale.to_human_readable(), - i + 1 - ) - }, + title: subtitle_title, }) } videos.push(FFmpegMeta { diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index c6f3168..2f546df 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -301,7 +301,7 @@ pub struct Format { impl Format { pub fn from_single_formats( - mut single_formats: Vec<(SingleFormat, VariantData, Vec)>, + mut single_formats: Vec<(SingleFormat, VariantData, Vec<(Subtitle, bool)>)>, ) -> Self { let locales: Vec<(Locale, Vec)> = single_formats .iter() @@ -310,7 +310,7 @@ impl Format { single_format.audio.clone(), subtitles .into_iter() - .map(|s| s.locale.clone()) + .map(|(s, _)| s.locale.clone()) .collect::>(), ) }) From e277b4200f37536ee3b70eedc0c84b7b3f39df1a Mon Sep 17 00:00:00 2001 From: ByteDream Date: Mon, 17 Apr 2023 18:24:20 +0200 Subject: [PATCH 005/272] Update version --- Cargo.lock | 13 +++++++------ Cargo.toml | 2 +- crunchy-cli-core/Cargo.lock | 11 ++++++----- crunchy-cli-core/Cargo.toml | 2 +- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c8328f9..d154304 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -333,7 +333,7 @@ dependencies = [ [[package]] name = "crunchy-cli" -version = "3.0.0-dev.11" +version = "3.0.0-dev.12" dependencies = [ "chrono", "clap", @@ -345,7 +345,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.0.0-dev.11" +version = "3.0.0-dev.12" dependencies = [ "anyhow", "async-trait", @@ -546,9 +546,9 @@ dependencies = [ [[package]] name = "dash-mpd" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df35f3b3b0fde2747a01530de0a81f7a27620d050f656e518ef0550557f564de" +checksum = "4937210c839d6f764b196afa05349927a8a2cc204ad613086e81defcddd4ade1" dependencies = [ "chrono", "fs-err", @@ -560,6 +560,7 @@ dependencies = [ "serde", "serde_with", "thiserror", + "tokio", "xattr", ] @@ -849,9 +850,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.25" +version = "0.14.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899" +checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" dependencies = [ "bytes", "futures-channel", diff --git a/Cargo.toml b/Cargo.toml index f53a9b1..2b7a255 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.0.0-dev.11" +version = "3.0.0-dev.12" edition = "2021" [dependencies] diff --git a/crunchy-cli-core/Cargo.lock b/crunchy-cli-core/Cargo.lock index a60668a..15f2bea 100644 --- a/crunchy-cli-core/Cargo.lock +++ b/crunchy-cli-core/Cargo.lock @@ -314,7 +314,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.0.0-dev.11" +version = "3.0.0-dev.12" dependencies = [ "anyhow", "async-trait", @@ -515,9 +515,9 @@ dependencies = [ [[package]] name = "dash-mpd" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df35f3b3b0fde2747a01530de0a81f7a27620d050f656e518ef0550557f564de" +checksum = "4937210c839d6f764b196afa05349927a8a2cc204ad613086e81defcddd4ade1" dependencies = [ "chrono", "fs-err", @@ -529,6 +529,7 @@ dependencies = [ "serde", "serde_with", "thiserror", + "tokio", "xattr", ] @@ -818,9 +819,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.25" +version = "0.14.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899" +checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" dependencies = [ "bytes", "futures-channel", diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index bbae22e..6cdb2af 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.0.0-dev.11" +version = "3.0.0-dev.12" edition = "2021" [dependencies] From ff258c072220ee494eaf4e5302a0b9ec81107227 Mon Sep 17 00:00:00 2001 From: ByteDream Date: Sun, 23 Apr 2023 13:21:50 +0200 Subject: [PATCH 006/272] Remove --vv flag --- crunchy-cli-core/src/lib.rs | 19 ++++++------------- crunchy-cli-core/src/utils/log.rs | 10 ++++------ 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index 65c3ca1..fee019f 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -5,6 +5,7 @@ use anyhow::bail; use anyhow::Result; use clap::{Parser, Subcommand}; use crunchyroll_rs::crunchyroll::CrunchyrollBuilder; +use crunchyroll_rs::error::CrunchyrollError; use crunchyroll_rs::{Crunchyroll, Locale}; use log::{debug, error, warn, LevelFilter}; use reqwest::Proxy; @@ -15,9 +16,7 @@ mod download; mod login; mod utils; -use crate::login::session_file_path; pub use archive::Archive; -use crunchyroll_rs::error::CrunchyrollError; pub use download::Download; pub use login::Login; @@ -90,10 +89,6 @@ struct Verbosity { #[arg(short)] v: bool, - #[arg(help = "Very verbose output. Generally not recommended, use '-v' instead")] - #[arg(long)] - vv: bool, - #[arg(help = "Quiet output. Does not print anything unless it's a error")] #[arg( long_help = "Quiet output. Does not print anything unless it's a error. Can be helpful if you pipe the output to stdout" @@ -124,18 +119,16 @@ pub async fn cli_entrypoint() { let mut cli: Cli = Cli::parse(); if let Some(verbosity) = &cli.verbosity { - if verbosity.v as u8 + verbosity.q as u8 + verbosity.vv as u8 > 1 { + if verbosity.v as u8 + verbosity.q as u8 > 1 { eprintln!("Output cannot be verbose ('-v') and quiet ('-q') at the same time"); std::process::exit(1) } else if verbosity.v { - CliLogger::init(false, LevelFilter::Debug).unwrap() + CliLogger::init(LevelFilter::Debug).unwrap() } else if verbosity.q { - CliLogger::init(false, LevelFilter::Error).unwrap() - } else if verbosity.vv { - CliLogger::init(true, LevelFilter::Debug).unwrap() + CliLogger::init(LevelFilter::Error).unwrap() } } else { - CliLogger::init(false, LevelFilter::Info).unwrap() + CliLogger::init(LevelFilter::Info).unwrap() } debug!("cli input: {:?}", cli); @@ -145,7 +138,7 @@ pub async fn cli_entrypoint() { Command::Download(download) => pre_check_executor(download).await, Command::Login(login) => { if login.remove { - if let Some(session_file) = session_file_path() { + if let Some(session_file) = login::session_file_path() { let _ = fs::remove_file(session_file); } return; diff --git a/crunchy-cli-core/src/utils/log.rs b/crunchy-cli-core/src/utils/log.rs index 8472250..37bc5a9 100644 --- a/crunchy-cli-core/src/utils/log.rs +++ b/crunchy-cli-core/src/utils/log.rs @@ -50,7 +50,6 @@ pub(crate) use tab_info; #[allow(clippy::type_complexity)] pub struct CliLogger { - all: bool, level: LevelFilter, progress: Mutex>, } @@ -64,7 +63,7 @@ impl Log for CliLogger { if !self.enabled(record.metadata()) || (record.target() != "progress" && record.target() != "progress_end" - && (!self.all && !record.target().starts_with("crunchy_cli"))) + && !record.target().starts_with("crunchy_cli")) { return; } @@ -95,17 +94,16 @@ impl Log for CliLogger { } impl CliLogger { - pub fn new(all: bool, level: LevelFilter) -> Self { + pub fn new(level: LevelFilter) -> Self { Self { - all, level, progress: Mutex::new(None), } } - pub fn init(all: bool, level: LevelFilter) -> Result<(), SetLoggerError> { + pub fn init(level: LevelFilter) -> Result<(), SetLoggerError> { set_max_level(level); - set_boxed_logger(Box::new(CliLogger::new(all, level))) + set_boxed_logger(Box::new(CliLogger::new(level))) } fn extended(&self, record: &Record) { From ce358041bef4c19b47803d0a91f317f11e04f1d4 Mon Sep 17 00:00:00 2001 From: ByteDream Date: Sun, 23 Apr 2023 13:45:08 +0200 Subject: [PATCH 007/272] Removed unused struct --- crunchy-cli-core/src/archive/filter.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crunchy-cli-core/src/archive/filter.rs b/crunchy-cli-core/src/archive/filter.rs index d135800..e44ebab 100644 --- a/crunchy-cli-core/src/archive/filter.rs +++ b/crunchy-cli-core/src/archive/filter.rs @@ -269,8 +269,6 @@ impl Filter for ArchiveFilter { let mut single_format_collection = SingleFormatCollection::new(); - struct SortKey(u32, String); - let mut sorted: BTreeMap<(u32, String), Self::T> = BTreeMap::new(); for data in flatten_input { sorted From 7b1ed30b20212c076567f571cfb0c11674f698fd Mon Sep 17 00:00:00 2001 From: ByteDream Date: Sun, 23 Apr 2023 13:45:53 +0200 Subject: [PATCH 008/272] Fix subtitle burn-in error (#198) --- crunchy-cli-core/src/utils/download.rs | 63 ++++++++++++++------------ 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index 57baf83..8bd8c28 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -252,20 +252,28 @@ impl Downloader { format!("title={}", meta.title), ]); } - for (i, meta) in subtitles.iter().enumerate() { - input.extend(["-i".to_string(), meta.path.to_string_lossy().to_string()]); - maps.extend([ - "-map".to_string(), - (i + videos.len() + audios.len()).to_string(), - ]); - metadata.extend([ - format!("-metadata:s:s:{}", i), - format!("language={}", meta.language), - ]); - metadata.extend([ - format!("-metadata:s:s:{}", i), - format!("title={}", meta.title), - ]); + + // this formats are supporting embedding subtitles into the video container instead of + // burning it into the video stream directly + let container_supports_softsubs = + ["mkv", "mp4"].contains(&dst.extension().unwrap_or_default().to_str().unwrap()); + + if container_supports_softsubs { + for (i, meta) in subtitles.iter().enumerate() { + input.extend(["-i".to_string(), meta.path.to_string_lossy().to_string()]); + maps.extend([ + "-map".to_string(), + (i + videos.len() + audios.len()).to_string(), + ]); + metadata.extend([ + format!("-metadata:s:s:{}", i), + format!("language={}", meta.language), + ]); + metadata.extend([ + format!("-metadata:s:s:{}", i), + format!("title={}", meta.title), + ]); + } } let (input_presets, mut output_presets) = self.ffmpeg_preset.into_input_output_args(); @@ -283,17 +291,12 @@ impl Downloader { .position(|m| m.language == default_subtitle) { match dst.extension().unwrap_or_default().to_str().unwrap() { + "mkv" => (), "mp4" => output_presets.extend([ "-movflags".to_string(), "faststart".to_string(), "-c:s".to_string(), "mov_text".to_string(), - format!("-disposition:s:s:{}", position), - "forced".to_string(), - ]), - "mkv" => output_presets.extend([ - format!("-disposition:s:s:{}", position), - "forced".to_string(), ]), _ => { // remove '-c:v copy' and '-c:a copy' from output presets as its causes issues with @@ -314,7 +317,7 @@ impl Downloader { output_presets.extend([ "-vf".to_string(), format!( - "subtitles={}", + "ass={}", subtitles.get(position).unwrap().path.to_str().unwrap() ), ]) @@ -322,14 +325,16 @@ impl Downloader { } } - if let Some(position) = subtitles - .iter() - .position(|meta| meta.language == default_subtitle) - { - command_args.extend([ - format!("-disposition:s:s:{}", position), - "forced".to_string(), - ]) + if container_supports_softsubs { + if let Some(position) = subtitles + .iter() + .position(|meta| meta.language == default_subtitle) + { + command_args.extend([ + format!("-disposition:s:s:{}", position), + "forced".to_string(), + ]) + } } } From 94fcf1590ac1ecdcfd1c9807da18effb668674d5 Mon Sep 17 00:00:00 2001 From: ByteDream Date: Sun, 23 Apr 2023 14:02:52 +0200 Subject: [PATCH 009/272] Add .mov to known soft-sub containers --- crunchy-cli-core/src/utils/download.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index 8bd8c28..0fbd792 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -256,7 +256,7 @@ impl Downloader { // this formats are supporting embedding subtitles into the video container instead of // burning it into the video stream directly let container_supports_softsubs = - ["mkv", "mp4"].contains(&dst.extension().unwrap_or_default().to_str().unwrap()); + ["mkv", "mov", "mp4"].contains(&dst.extension().unwrap_or_default().to_str().unwrap()); if container_supports_softsubs { for (i, meta) in subtitles.iter().enumerate() { @@ -292,7 +292,7 @@ impl Downloader { { match dst.extension().unwrap_or_default().to_str().unwrap() { "mkv" => (), - "mp4" => output_presets.extend([ + "mov" | "mp4" => output_presets.extend([ "-movflags".to_string(), "faststart".to_string(), "-c:s".to_string(), From 0f73d8dbeceb2c02a54313d9e3ade0e1bdf34595 Mon Sep 17 00:00:00 2001 From: ByteDream Date: Sun, 23 Apr 2023 15:57:49 +0200 Subject: [PATCH 010/272] Update conditions for subtitle to be marked as CC --- crunchy-cli-core/src/archive/command.rs | 9 ++++++++- crunchy-cli-core/src/download/command.rs | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index a048685..a09c1a3 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -250,7 +250,14 @@ async fn get_format( .subtitles .get(s) .cloned() - .map(|l| (l, single_format.audio == Locale::ja_JP)) + // the subtitle is probably not cc if the audio is japanese or more than one + // subtitle exists for this stream + .map(|l| { + ( + l, + single_format.audio == Locale::ja_JP || stream.subtitles.len() > 1, + ) + }) }) .collect(); diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index 142bf9c..c1388f1 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -205,12 +205,12 @@ async fn get_format( audios: vec![(audio, single_format.audio.clone())], subtitles: subtitle .clone() - .map_or(vec![], |s| vec![(s, single_format.audio == Locale::ja_JP)]), + .map_or(vec![], |s| vec![(s, single_format.audio == Locale::ja_JP || stream.subtitles.len() > 1)]), }; let format = Format::from_single_formats(vec![( single_format.clone(), video, - subtitle.map_or(vec![], |s| vec![(s, single_format.audio == Locale::ja_JP)]), + subtitle.map_or(vec![], |s| vec![(s, single_format.audio == Locale::ja_JP || stream.subtitles.len() > 1)]), )]); Ok((download_format, format)) From dc431a963755e428b2f7b9771984182c6dfd094f Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 25 Apr 2023 10:47:08 +0200 Subject: [PATCH 011/272] Update version --- Cargo.lock | 68 ++++++++++++++++++------------------- Cargo.toml | 2 +- crunchy-cli-core/Cargo.lock | 62 ++++++++++++++++----------------- crunchy-cli-core/Cargo.toml | 4 +-- 4 files changed, 68 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d154304..4635644 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,9 +15,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ "memchr", ] @@ -33,9 +33,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e579a7752471abc2a8268df8b20005e3eadd975f585398f17efcfd8d4927371" +checksum = "6342bd4f5a1205d7f41e94a41a901f5647c938cdfa96036338e8533c9d6c2450" dependencies = [ "anstyle", "anstyle-parse", @@ -72,9 +72,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcd8291a340dd8ac70e18878bc4501dd7b4ff970cfa21c207d36ece51ea88fd" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -132,9 +132,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.12.0" +version = "3.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" [[package]] name = "bytes" @@ -191,9 +191,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.2.2" +version = "4.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b802d85aaf3a1cdb02b224ba472ebdea62014fccfcb269b95a4d76443b5ee5a" +checksum = "956ac1f6381d8d82ab4684768f89c0ea3afe66925ceadb4eeb3fc452ffc55d62" dependencies = [ "clap_builder", "clap_derive", @@ -202,9 +202,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.2.2" +version = "4.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14a1a858f532119338887a4b8e1af9c60de8249cd7bafd68036a489e261e37b6" +checksum = "84080e799e54cff944f4b4a4b0e71630b0e0443b25b985175c7dddc1a859b749" dependencies = [ "anstream", "anstyle", @@ -215,9 +215,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.2.0" +version = "4.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c22dcfb410883764b29953103d9ef7bb8fe21b3fa1158bc99986c2067294bd" +checksum = "1a19591b2ab0e3c04b588a0e04ddde7b9eaa423646d1b4a8092879216bf47473" dependencies = [ "clap", ] @@ -324,16 +324,16 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" dependencies = [ "libc", ] [[package]] name = "crunchy-cli" -version = "3.0.0-dev.12" +version = "3.0.0-dev.13" dependencies = [ "chrono", "clap", @@ -345,7 +345,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.0.0-dev.12" +version = "3.0.0-dev.13" dependencies = [ "anyhow", "async-trait", @@ -764,9 +764,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66b91535aa35fea1523ad1b86cb6b53c28e0ae566ba4a460f4457e936cad7c6f" +checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21" dependencies = [ "bytes", "fnv", @@ -1052,9 +1052,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.141" +version = "0.2.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "link-cplusplus" @@ -1067,9 +1067,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" +checksum = "36eb31c1778188ae1e64398743890d0877fef36d11521ac60406b42016e8c2cf" [[package]] name = "log" @@ -1209,9 +1209,9 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "openssl" -version = "0.10.50" +version = "0.10.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e30d8bc91859781f0a943411186324d580f2bbeb71b452fe91ae344806af3f1" +checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" dependencies = [ "bitflags", "cfg-if", @@ -1241,9 +1241,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.85" +version = "0.9.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d3d193fb1488ad46ffe3aaabc912cc931d02ee8518fe2959aea8ef52718b0c0" +checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" dependencies = [ "cc", "libc", @@ -1356,9 +1356,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.3" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ "aho-corasick", "memchr", @@ -1367,9 +1367,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.29" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "reqwest" @@ -1439,9 +1439,9 @@ checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" [[package]] name = "rustix" -version = "0.37.11" +version = "0.37.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77" +checksum = "d9b864d3c18a5785a05953adeed93e2dca37ed30f18e69bba9f30079d51f363f" dependencies = [ "bitflags", "errno", diff --git a/Cargo.toml b/Cargo.toml index 2b7a255..bad4772 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.0.0-dev.12" +version = "3.0.0-dev.13" edition = "2021" [dependencies] diff --git a/crunchy-cli-core/Cargo.lock b/crunchy-cli-core/Cargo.lock index 15f2bea..3904323 100644 --- a/crunchy-cli-core/Cargo.lock +++ b/crunchy-cli-core/Cargo.lock @@ -15,9 +15,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ "memchr", ] @@ -33,9 +33,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e579a7752471abc2a8268df8b20005e3eadd975f585398f17efcfd8d4927371" +checksum = "6342bd4f5a1205d7f41e94a41a901f5647c938cdfa96036338e8533c9d6c2450" dependencies = [ "anstyle", "anstyle-parse", @@ -72,9 +72,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcd8291a340dd8ac70e18878bc4501dd7b4ff970cfa21c207d36ece51ea88fd" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -132,9 +132,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.12.0" +version = "3.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" [[package]] name = "bytes" @@ -191,9 +191,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.2.2" +version = "4.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b802d85aaf3a1cdb02b224ba472ebdea62014fccfcb269b95a4d76443b5ee5a" +checksum = "956ac1f6381d8d82ab4684768f89c0ea3afe66925ceadb4eeb3fc452ffc55d62" dependencies = [ "clap_builder", "clap_derive", @@ -202,9 +202,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.2.2" +version = "4.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14a1a858f532119338887a4b8e1af9c60de8249cd7bafd68036a489e261e37b6" +checksum = "84080e799e54cff944f4b4a4b0e71630b0e0443b25b985175c7dddc1a859b749" dependencies = [ "anstream", "anstyle", @@ -305,16 +305,16 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" dependencies = [ "libc", ] [[package]] name = "crunchy-cli-core" -version = "3.0.0-dev.12" +version = "3.0.0-dev.13" dependencies = [ "anyhow", "async-trait", @@ -733,9 +733,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66b91535aa35fea1523ad1b86cb6b53c28e0ae566ba4a460f4457e936cad7c6f" +checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21" dependencies = [ "bytes", "fnv", @@ -1021,9 +1021,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.141" +version = "0.2.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "link-cplusplus" @@ -1036,9 +1036,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" +checksum = "36eb31c1778188ae1e64398743890d0877fef36d11521ac60406b42016e8c2cf" [[package]] name = "log" @@ -1178,9 +1178,9 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "openssl" -version = "0.10.50" +version = "0.10.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e30d8bc91859781f0a943411186324d580f2bbeb71b452fe91ae344806af3f1" +checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" dependencies = [ "bitflags", "cfg-if", @@ -1210,9 +1210,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.85" +version = "0.9.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d3d193fb1488ad46ffe3aaabc912cc931d02ee8518fe2959aea8ef52718b0c0" +checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" dependencies = [ "cc", "libc", @@ -1325,9 +1325,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.3" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ "aho-corasick", "memchr", @@ -1336,9 +1336,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.29" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "reqwest" @@ -1402,9 +1402,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.11" +version = "0.37.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77" +checksum = "d9b864d3c18a5785a05953adeed93e2dca37ed30f18e69bba9f30079d51f363f" dependencies = [ "bitflags", "errno", diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 6cdb2af..62f83ec 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.0.0-dev.12" +version = "3.0.0-dev.13" edition = "2021" [dependencies] @@ -18,7 +18,7 @@ indicatif = "0.17" lazy_static = "1.4" log = { version = "0.4", features = ["std"] } num_cpus = "1.15" -regex = "1.7" +regex = "1.8" reqwest = { version = "0.11", default-features = false, features = ["socks"] } sanitize-filename = "0.4" serde = "1.0" From c2e953043e02d6049ee8c92f1bbc53b6e071f5e1 Mon Sep 17 00:00:00 2001 From: ByteDream Date: Sat, 6 May 2023 22:06:52 +0200 Subject: [PATCH 012/272] Fix output filename if file stem is empty but file exists --- crunchy-cli-core/src/utils/os.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/utils/os.rs b/crunchy-cli-core/src/utils/os.rs index bd30c2a..f6d9ad0 100644 --- a/crunchy-cli-core/src/utils/os.rs +++ b/crunchy-cli-core/src/utils/os.rs @@ -52,9 +52,18 @@ pub fn free_file(mut path: PathBuf) -> (PathBuf, bool) { while path.exists() { i += 1; - let ext = path.extension().unwrap_or_default().to_string_lossy(); + let mut ext = path.extension().unwrap_or_default().to_str().unwrap(); let mut filename = path.file_stem().unwrap_or_default().to_str().unwrap(); + // if the extension is empty, the filename without extension is probably empty + // (e.g. `.mp4`). in this case Rust assumes that `.mp4` is the file stem rather than the + // extension. if this is the case, set the extension to the file stem and make the file stem + // empty + if ext.is_empty() { + ext = filename; + filename = ""; + } + if filename.ends_with(&format!(" ({})", i - 1)) { filename = filename.strip_suffix(&format!(" ({})", i - 1)).unwrap(); } From 61766c74fab93397d46620f786b1b116a7272cee Mon Sep 17 00:00:00 2001 From: ByteDream Date: Sun, 7 May 2023 01:34:41 +0200 Subject: [PATCH 013/272] Enable usage of auth flags behind login command --- crunchy-cli-core/src/download/command.rs | 16 ++++++-- crunchy-cli-core/src/lib.rs | 50 ++++++++++++------------ crunchy-cli-core/src/login/command.rs | 23 ++++++++++- crunchy-cli-core/src/login/mod.rs | 3 +- 4 files changed, 59 insertions(+), 33 deletions(-) diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index c1388f1..7d42d97 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -203,14 +203,22 @@ async fn get_format( let download_format = DownloadFormat { video: (video.clone(), single_format.audio.clone()), audios: vec![(audio, single_format.audio.clone())], - subtitles: subtitle - .clone() - .map_or(vec![], |s| vec![(s, single_format.audio == Locale::ja_JP || stream.subtitles.len() > 1)]), + subtitles: subtitle.clone().map_or(vec![], |s| { + vec![( + s, + single_format.audio == Locale::ja_JP || stream.subtitles.len() > 1, + )] + }), }; let format = Format::from_single_formats(vec![( single_format.clone(), video, - subtitle.map_or(vec![], |s| vec![(s, single_format.audio == Locale::ja_JP || stream.subtitles.len() > 1)]), + subtitle.map_or(vec![], |s| { + vec![( + s, + single_format.audio == Locale::ja_JP || stream.subtitles.len() > 1, + )] + }), )]); Ok((download_format, format)) diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index fee019f..fdc801c 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -51,7 +51,7 @@ pub struct Cli { experimental_fixes: bool, #[clap(flatten)] - login_method: LoginMethod, + login_method: login::LoginMethod, #[arg(help = "Use a proxy to route all traffic through")] #[arg(long_help = "Use a proxy to route all traffic through. \ @@ -97,24 +97,6 @@ struct Verbosity { q: bool, } -#[derive(Debug, Parser)] -struct LoginMethod { - #[arg( - help = "Login with credentials (username or email and password). Must be provided as user:password" - )] - #[arg(long)] - credentials: Option, - #[arg(help = "Login with the etp-rt cookie")] - #[arg( - long_help = "Login with the etp-rt cookie. This can be obtained when you login on crunchyroll.com and extract it from there" - )] - #[arg(long)] - etp_rt: Option, - #[arg(help = "Login anonymously / without an account")] - #[arg(long, default_value_t = false)] - anonymous: bool, -} - pub async fn cli_entrypoint() { let mut cli: Cli = Cli::parse(); @@ -148,7 +130,7 @@ pub async fn cli_entrypoint() { } }; - let ctx = match create_ctx(&cli).await { + let ctx = match create_ctx(&mut cli).await { Ok(ctx) => ctx, Err(e) => { error!("{}", e); @@ -222,12 +204,12 @@ async fn execute_executor(executor: impl Execute, ctx: Context) { } } -async fn create_ctx(cli: &Cli) -> Result { +async fn create_ctx(cli: &mut Cli) -> Result { let crunchy = crunchyroll_session(cli).await?; Ok(Context { crunchy }) } -async fn crunchyroll_session(cli: &Cli) -> Result { +async fn crunchyroll_session(cli: &mut Cli) -> Result { let supported_langs = vec![ Locale::ar_ME, Locale::de_DE, @@ -276,12 +258,18 @@ async fn crunchyroll_session(cli: &Cli) -> Result { builder = builder.preferred_audio_locale(download.audio.clone()) } - let login_methods_count = cli.login_method.credentials.is_some() as u8 + let root_login_methods_count = cli.login_method.credentials.is_some() as u8 + cli.login_method.etp_rt.is_some() as u8 + cli.login_method.anonymous as u8; + let mut login_login_methods_count = 0; + if let Command::Login(login) = &cli.command { + login_login_methods_count += login.login_method.credentials.is_some() as u8 + + cli.login_method.etp_rt.is_some() as u8 + + cli.login_method.anonymous as u8 + } let progress_handler = progress!("Logging in"); - if login_methods_count == 0 { + if root_login_methods_count + login_login_methods_count == 0 { if let Some(login_file_path) = login::session_file_path() { if login_file_path.exists() { let session = fs::read_to_string(login_file_path)?; @@ -298,11 +286,21 @@ async fn crunchyroll_session(cli: &Cli) -> Result { } } bail!("Please use a login method ('--credentials', '--etp-rt' or '--anonymous')") - } else if login_methods_count > 1 { + } else if root_login_methods_count + login_login_methods_count > 1 { bail!("Please use only one login method ('--credentials', '--etp-rt' or '--anonymous')") } - let crunchy = if let Some(credentials) = &cli.login_method.credentials { + let login_method = if login_login_methods_count > 0 { + if let Command::Login(login) = &cli.command { + login.login_method.clone() + } else { + unreachable!() + } + } else { + cli.login_method.clone() + }; + + let crunchy = if let Some(credentials) = &login_method.credentials { if let Some((user, password)) = credentials.split_once(':') { builder.login_with_credentials(user, password).await? } else { diff --git a/crunchy-cli-core/src/login/command.rs b/crunchy-cli-core/src/login/command.rs index ad101da..ab16e06 100644 --- a/crunchy-cli-core/src/login/command.rs +++ b/crunchy-cli-core/src/login/command.rs @@ -2,6 +2,7 @@ use crate::utils::context::Context; use crate::Execute; use anyhow::bail; use anyhow::Result; +use clap::Parser; use crunchyroll_rs::crunchyroll::SessionToken; use std::fs; use std::path::PathBuf; @@ -9,7 +10,9 @@ use std::path::PathBuf; #[derive(Debug, clap::Parser)] #[clap(about = "Save your login credentials persistent on disk")] pub struct Login { - #[arg(help = "Remove your stored credentials (instead of save them)")] + #[clap(flatten)] + pub login_method: LoginMethod, + #[arg(help = "Remove your stored credentials (instead of saving them)")] #[arg(long)] pub remove: bool, } @@ -36,6 +39,24 @@ impl Execute for Login { } } +#[derive(Clone, Debug, Parser)] +pub struct LoginMethod { + #[arg( + help = "Login with credentials (username or email and password). Must be provided as user:password" + )] + #[arg(long)] + pub credentials: Option, + #[arg(help = "Login with the etp-rt cookie")] + #[arg( + long_help = "Login with the etp-rt cookie. This can be obtained when you login on crunchyroll.com and extract it from there" + )] + #[arg(long)] + pub etp_rt: Option, + #[arg(help = "Login anonymously / without an account")] + #[arg(long, default_value_t = false)] + pub anonymous: bool, +} + pub fn session_file_path() -> Option { dirs::config_dir().map(|config_dir| config_dir.join("crunchy-cli").join("session")) } diff --git a/crunchy-cli-core/src/login/mod.rs b/crunchy-cli-core/src/login/mod.rs index e2ab88c..8c1220a 100644 --- a/crunchy-cli-core/src/login/mod.rs +++ b/crunchy-cli-core/src/login/mod.rs @@ -1,4 +1,3 @@ mod command; -pub use command::session_file_path; -pub use command::Login; +pub use command::{session_file_path, Login, LoginMethod}; From b24827dc6bd5faa7819d51e35b2d993087f5aa11 Mon Sep 17 00:00:00 2001 From: bocchi <131238467+hitorilabs@users.noreply.github.com> Date: Sat, 13 May 2023 12:19:44 -0400 Subject: [PATCH 014/272] fix login (#202) --- crunchy-cli-core/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index fdc801c..9ae8e83 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -264,8 +264,8 @@ async fn crunchyroll_session(cli: &mut Cli) -> Result { let mut login_login_methods_count = 0; if let Command::Login(login) = &cli.command { login_login_methods_count += login.login_method.credentials.is_some() as u8 - + cli.login_method.etp_rt.is_some() as u8 - + cli.login_method.anonymous as u8 + + login.login_method.etp_rt.is_some() as u8 + + login.login_method.anonymous as u8 } let progress_handler = progress!("Logging in"); From 4bd172df060157d62e19b85005de714fca75a67c Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 24 May 2023 12:55:47 +0200 Subject: [PATCH 015/272] Fix japanese episode download if episode isn't available in specified language with archive (#207) --- crunchy-cli-core/src/archive/filter.rs | 29 +++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/archive/filter.rs b/crunchy-cli-core/src/archive/filter.rs index e44ebab..514b540 100644 --- a/crunchy-cli-core/src/archive/filter.rs +++ b/crunchy-cli-core/src/archive/filter.rs @@ -129,7 +129,34 @@ impl Filter for ArchiveFilter { let mut episodes = vec![]; for season in seasons { - episodes.extend(season.episodes().await?) + let season_locale = season + .audio_locales + .get(0) + .cloned() + .unwrap_or(Locale::ja_JP); + let mut eps = season.episodes().await?; + let before_len = eps.len(); + eps.retain(|e| e.audio_locale == season_locale); + if eps.len() != before_len { + if eps.len() == 0 { + if matches!(self.visited, Visited::Series) { + warn!( + "Season {} is not available with {} audio", + season.season_number, season_locale + ) + } + } else { + let last_episode = eps.last().unwrap(); + warn!( + "Season {} is only available with {} audio until episode {} ({})", + season.season_number, + season_locale, + last_episode.episode_number, + last_episode.title + ) + } + } + episodes.extend(eps) } if Format::has_relative_episodes_fmt(&self.archive.output) { From a2b7c78752f916923f619864144a550f1610bedf Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 24 May 2023 13:15:28 +0200 Subject: [PATCH 016/272] Fix long help language formatting --- crunchy-cli-core/src/archive/command.rs | 2 +- crunchy-cli-core/src/download/command.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index a09c1a3..9af14fb 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -27,7 +27,7 @@ pub struct Archive { #[arg(help = format!("Audio languages. Can be used multiple times. \ Available languages are: {}", Locale::all().into_iter().map(|l| l.to_string()).collect::>().join(", ")))] #[arg(long_help = format!("Audio languages. Can be used multiple times. \ - Available languages are:\n{}", Locale::all().into_iter().map(|l| format!("{:<6} → {}", l.to_string(), l.to_human_readable())).collect::>().join("\n ")))] + Available languages are:\n {}", Locale::all().into_iter().map(|l| format!("{:<6} → {}", l.to_string(), l.to_human_readable())).collect::>().join("\n ")))] #[arg(short, long, default_values_t = vec![Locale::ja_JP, crate::utils::locale::system_locale()])] pub(crate) audio: Vec, #[arg(help = "Deprecated. Use '-a' / '--audio' instead")] diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index 7d42d97..644e4e5 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -23,7 +23,7 @@ pub struct Download { #[arg(help = format!("Audio language. Can only be used if the provided url(s) point to a series. \ Available languages are: {}", Locale::all().into_iter().map(|l| l.to_string()).collect::>().join(", ")))] #[arg(long_help = format!("Audio language. Can only be used if the provided url(s) point to a series. \ - Available languages are:\n{}", Locale::all().into_iter().map(|l| format!("{:<6} → {}", l.to_string(), l.to_human_readable())).collect::>().join("\n ")))] + Available languages are:\n {}", Locale::all().into_iter().map(|l| format!("{:<6} → {}", l.to_string(), l.to_human_readable())).collect::>().join("\n ")))] #[arg(short, long, default_value_t = crate::utils::locale::system_locale())] pub(crate) audio: Locale, #[arg(help = format!("Subtitle language. Available languages are: {}", Locale::all().into_iter().map(|l| l.to_string()).collect::>().join(", ")))] From f3f900064a0800a4175f5ea4b27e2e1efe032e09 Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 25 May 2023 18:54:41 +0200 Subject: [PATCH 017/272] Fix flag README typo --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 846c59f..b1cd9ea 100644 --- a/README.md +++ b/README.md @@ -205,9 +205,9 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any - Default subtitle - `--default_subtitle` Set which subtitle language is to be flagged as **default** and **forced**. + `--default-subtitle` Set which subtitle language is to be flagged as **default** and **forced**. ```shell - $ crunchy archive --default_subtitle en-US https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + $ crunchy archive --default-subtitle en-US https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` Default is none. From 19f79a434916663c1e33c2911ebebdd875aa65ba Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 25 May 2023 18:58:03 +0200 Subject: [PATCH 018/272] Remove no-subtitle-optimization flag in README --- README.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/README.md b/README.md index b1cd9ea..059c7f2 100644 --- a/README.md +++ b/README.md @@ -211,16 +211,6 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any ``` Default is none. -- Subtitle optimizations - - Crunchyroll's subtitles look weird in some players (#66). - This can be fixed by adding a specific entry to the subtitles. - Even though this entry is a de facto standard, it is not defined in the official specification for the `.ass` format (cf. [Advanced SubStation Subtitles](https://wiki.videolan.org/SubStation_Alpha)). This could cause compatibility issues, but no issues have been reported yet. - `--no_subtitle_optimizations` disables these optimizations. - ```shell - $ crunchy archive --no_subtitle_optimizations https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx - ``` - ### Episode filtering Filters patterns can be used to download a specific range of episodes from a single series. From 49d64805cae6b60f26f3710ccd3d9a680674a4d5 Mon Sep 17 00:00:00 2001 From: StepBroBD Date: Sun, 4 Jun 2023 09:57:28 -0600 Subject: [PATCH 019/272] add nix flake (#210) - add following functionality: - nix develop with direnv support - nix run and nix shell - nix fmt for flake.nix - and package overlay for https://github.com/NixOS/nixpkgs/pull/225502 - useful docs - https://stackoverflow.com/questions/53272197/how-do-i-override-the-libc-in-a-nix-package-to-be-musl - https://github.com/NixOS/nixpkgs/blob/dd3aca2d0b9dcb4888779bfb08805d79596607c9/pkgs/top-level/stage.nix#L136 - inspired by https://github.com/typst/typst/blob/main/flake.nix --- .envrc | 1 + .gitignore | 9 ++++++- README.md | 7 +++++ flake.lock | 59 +++++++++++++++++++++++++++++++++++++++++ flake.nix | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 .envrc create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore index 5bb2fd7..76cbb0a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,10 @@ -/.idea +# Rust /target + +# Editor +/.idea /.vscode + +# Nix +/result +/.direnv diff --git a/README.md b/README.md index 059c7f2..0858123 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,13 @@ A pure [Rust](https://www.rust-lang.org/) CLI for [Crunchyroll](https://www.crun Check out the [releases](https://github.com/crunchy-labs/crunchy-cli/releases) tab and get the binary from the latest (pre-)release. +### ❄️ The nix way + +This requires [nix](https://nixos.org) and you'll probably need `--extra-experimental-features "nix-command flakes"` depending on your configurations. +```shell +$ nix github:crunchy-labs/crunchy-cli +``` + ### 🛠 Build it yourself Since we do not support every platform and architecture you may have to build the project yourself. diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..91bbf3d --- /dev/null +++ b/flake.lock @@ -0,0 +1,59 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1685866647, + "narHash": "sha256-4jKguNHY/edLYImB+uL8jKPL/vpfOvMmSlLAGfxSrnY=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "a53a3bec10deef6e1cc1caba5bc60f53b959b1e8", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixpkgs-unstable", + "type": "indirect" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs", + "utils": "utils" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1685518550, + "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", + "type": "github" + }, + "original": { + "id": "flake-utils", + "type": "indirect" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..4a48dec --- /dev/null +++ b/flake.nix @@ -0,0 +1,78 @@ +{ + inputs = { + nixpkgs.url = "flake:nixpkgs/nixpkgs-unstable"; + utils.url = "flake:flake-utils"; + }; + + outputs = { self, nixpkgs, utils, ... }: utils.lib.eachSystem [ + "aarch64-darwin" + "x86_64-darwin" + "aarch64-linux" + "x86_64-linux" + ] + (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + # enable musl on Linux makes the build time 100x slower + # since it will trigger a toolchain rebuild + # if nixpkgs.legacyPackages.${system}.stdenv.hostPlatform.isLinux + # then nixpkgs.legacyPackages.${system}.pkgsMusl + # else nixpkgs.legacyPackages.${system}; + + crunchy-cli = pkgs.rustPlatform.buildRustPackage.override { stdenv = pkgs.clangStdenv; } rec { + pname = "crunchy-cli"; + inherit ((pkgs.lib.importTOML ./Cargo.toml).package) version; + + src = pkgs.lib.cleanSource ./.; + + cargoLock = { + lockFile = ./Cargo.lock; + allowBuiltinFetchGit = true; + }; + + nativeBuildInputs = [ + pkgs.pkg-config + ] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [ + pkgs.xcbuild + ]; + + buildInputs = [ + pkgs.openssl + ] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [ + pkgs.darwin.Security + ]; + }; + in + { + packages.default = crunchy-cli; + + overlays.default = _: prev: { + crunchy-cli = prev.crunchy-cli.override { }; + }; + + devShells.default = pkgs.mkShell { + packages = with pkgs; [ + cargo + clippy + rust-analyzer + rustc + rustfmt + ]; + + inputsFrom = builtins.attrValues self.packages.${system}; + + buildInputs = [ + pkgs.openssl + pkgs.libiconv + ] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [ + pkgs.darwin.apple_sdk.frameworks.CoreServices + pkgs.darwin.Security + ]; + + RUST_SRC_PATH = pkgs.rustPlatform.rustLibSrc; + }; + + formatter = pkgs.nixpkgs-fmt; + } + ); +} From 32aab193d0ae6902768e648edfaa3741e312dabf Mon Sep 17 00:00:00 2001 From: Peter Mahon Date: Fri, 9 Jun 2023 01:17:59 -0700 Subject: [PATCH 020/272] Add Output Templates section in README.md Added a section for output templates so that users of the application have an easy reference as opposed to searching within the code. I also updated the Output Templates subsection in the downloads section to mention both .ts and .mp4 files since the default changes in version crunchy-cli v3.0.0-dev.9 of the binaries. --- README.md | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0858123..5a52424 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any ```shell $ crunchy download -o "ditf.ts" https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome ``` - Default is `{title}.ts`. + Default is `{title}.ts` or `{title}.mp4`, depending on the version of binary you're using. See the Template Options section below for more options. - Resolution @@ -187,7 +187,7 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any ```shell $ crunchy archive -o "{title}.mkv" https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` - Default is `{title}.mkv`. + Default is `{title}.mkv`. See the Template Options section below for more options. - Resolution @@ -217,6 +217,28 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any $ crunchy archive --default-subtitle en-US https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` Default is none. + +### Output Template Options + +You can use various template options to change how the filename is processed. The following tags are available: + +- {title} → Title of the video +- {series_name} → Name of the series +- {season_name} → Name of the season +- {audio} → Audio language of the video +- {resolution} → Resolution of the video +- {season_number} → Number of the season +- {episode_number} → Number of the episode +- {relative_episode_number} → Number of the episode relative to its season +- {series_id} → ID of the series +- {season_id} → ID of the season +- {episode_id} → ID of the episode + +When including a file extension in the output, use the `.mp4` extension when using a binary crunchy-cli v3.0.0-dev.9 or newer and using the `download` option. `.mkv` is the default file extension for `archive` downloads. Here is an example of using output templates: +```shell +$ crunchy archive -o "[S{season_number}E{episode_number}] {title}.mkv" https://www.crunchyroll.com/series/G8DHV7W21/dragon-ball +# Outputs: '[S01E01] Secret of the Dragon Ball.mkv' +``` ### Episode filtering From b55ac9a51acc9ada716feec64d5db9a3f66d4308 Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 16 Jun 2023 10:14:36 +0200 Subject: [PATCH 021/272] Update README --- README.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 5a52424..64b2f00 100644 --- a/README.md +++ b/README.md @@ -141,9 +141,9 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any Define an output template by using the `-o` / `--output` flag. If you want to use any other file format than [`.ts`](https://en.wikipedia.org/wiki/MPEG_transport_stream) you need [ffmpeg](https://ffmpeg.org/). ```shell - $ crunchy download -o "ditf.ts" https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome + $ crunchy download -o "ditf.mp4" https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome ``` - Default is `{title}.ts` or `{title}.mp4`, depending on the version of binary you're using. See the Template Options section below for more options. + Default is `{title}.mp4`. See the [Template Options section](#output-template-options) below for more options. - Resolution @@ -187,7 +187,7 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any ```shell $ crunchy archive -o "{title}.mkv" https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` - Default is `{title}.mkv`. See the Template Options section below for more options. + Default is `{title}.mkv`. See the [Template Options section](#output-template-options) below for more options. - Resolution @@ -222,22 +222,22 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any You can use various template options to change how the filename is processed. The following tags are available: -- {title} → Title of the video -- {series_name} → Name of the series -- {season_name} → Name of the season -- {audio} → Audio language of the video -- {resolution} → Resolution of the video -- {season_number} → Number of the season -- {episode_number} → Number of the episode -- {relative_episode_number} → Number of the episode relative to its season -- {series_id} → ID of the series -- {season_id} → ID of the season -- {episode_id} → ID of the episode +- `{title}` → Title of the video +- `{series_name}` → Name of the series +- `{season_name}` → Name of the season +- `{audio}` → Audio language of the video +- `{resolution}` → Resolution of the video +- `{season_number}` → Number of the season +- `{episode_number}` → Number of the episode +- `{relative_episode_number}` → Number of the episode relative to its season +- `{series_id}` → ID of the series +- `{season_id}` → ID of the season +- `{episode_id}` → ID of the episode -When including a file extension in the output, use the `.mp4` extension when using a binary crunchy-cli v3.0.0-dev.9 or newer and using the `download` option. `.mkv` is the default file extension for `archive` downloads. Here is an example of using output templates: +Example: ```shell $ crunchy archive -o "[S{season_number}E{episode_number}] {title}.mkv" https://www.crunchyroll.com/series/G8DHV7W21/dragon-ball -# Outputs: '[S01E01] Secret of the Dragon Ball.mkv' +# Output file: '[S01E01] Secret of the Dragon Ball.mkv' ``` ### Episode filtering From 7ed1158339f96b5df459f26c5c2f1c7b0602fa96 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 19 Jun 2023 01:34:30 +0200 Subject: [PATCH 022/272] Fix subtitle sorting (#208) --- crunchy-cli-core/src/utils/download.rs | 88 +++++++++++++------------- 1 file changed, 43 insertions(+), 45 deletions(-) diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index 0fbd792..dcfcf0a 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -475,8 +475,7 @@ impl Downloader { let mut buf = vec![]; subtitle.write_to(&mut buf).await?; - fix_subtitle_look_and_feel(&mut buf); - fix_subtitle_length(&mut buf, max_length); + fix_subtitles(&mut buf, max_length); file.write_all(buf.as_slice())?; @@ -670,27 +669,6 @@ fn estimate_variant_file_size(variant_data: &VariantData, segments: &Vec() } -/// Add `ScaledBorderAndShadows: yes` to subtitles; without it they look very messy on some video -/// players. See [crunchy-labs/crunchy-cli#66](https://github.com/crunchy-labs/crunchy-cli/issues/66) -/// for more information. -fn fix_subtitle_look_and_feel(raw: &mut Vec) { - let mut script_info = false; - let mut new = String::new(); - - for line in String::from_utf8_lossy(raw.as_slice()).split('\n') { - if line.trim().starts_with('[') && script_info { - new.push_str("ScaledBorderAndShadow: yes\n"); - script_info = false - } else if line.trim() == "[Script Info]" { - script_info = true - } - new.push_str(line); - new.push('\n') - } - - *raw = new.into_bytes() -} - /// Get the length of a video. This is required because sometimes subtitles have an unnecessary entry /// long after the actual video ends with artificially extends the video length on some video players. /// To prevent this, the video length must be hard set. See @@ -712,12 +690,22 @@ pub fn get_video_length(path: &Path) -> Result { Ok(NaiveTime::parse_from_str(caps.name("time").unwrap().as_str(), "%H:%M:%S%.f").unwrap()) } -/// Fix the length of subtitles to a specified maximum amount. This is required because sometimes -/// subtitles have an unnecessary entry long after the actual video ends with artificially extends -/// the video length on some video players. To prevent this, the video length must be hard set. See -/// [crunchy-labs/crunchy-cli#32](https://github.com/crunchy-labs/crunchy-cli/issues/32) for more +/// Fix the subtitles in multiple ways as Crunchyroll sometimes delivers them malformed. +/// +/// Look and feel fix: Add `ScaledBorderAndShadows: yes` to subtitles; without it they look very +/// messy on some video players. See +/// [crunchy-labs/crunchy-cli#66](https://github.com/crunchy-labs/crunchy-cli/issues/66) for more /// information. -fn fix_subtitle_length(raw: &mut Vec, max_length: NaiveTime) { +/// Length fix: Sometimes subtitles have an unnecessary long entry which exceeds the video length, +/// some video players can't handle this correctly. To prevent this, the subtitles must be checked +/// if any entry is longer than the video length and if so the entry ending must be hard set to not +/// exceed the video length. See [crunchy-labs/crunchy-cli#32](https://github.com/crunchy-labs/crunchy-cli/issues/32) +/// for more information. +/// Sort fix: Sometimes subtitle entries aren't sorted correctly by time which confuses some video +/// players. To prevent this, the subtitle entries must be manually sorted. See +/// [crunchy-labs/crunchy-cli#208](https://github.com/crunchy-labs/crunchy-cli/issues/208) for more +/// information. +fn fix_subtitles(raw: &mut Vec, max_length: NaiveTime) { let re = Regex::new(r#"^Dialogue:\s\d+,(?P\d+:\d+:\d+\.\d+),(?P\d+:\d+:\d+\.\d+),"#) .unwrap(); @@ -738,10 +726,17 @@ fn fix_subtitle_length(raw: &mut Vec, max_length: NaiveTime) { } let length_as_string = format_naive_time(max_length); - let mut new = String::new(); + let mut entries = (vec![], vec![]); - for line in String::from_utf8_lossy(raw.as_slice()).split('\n') { - if let Some(capture) = re.captures(line) { + let mut as_lines: Vec = String::from_utf8_lossy(raw.as_slice()) + .split('\n') + .map(|s| s.to_string()) + .collect(); + + for (i, line) in as_lines.iter_mut().enumerate() { + if line.trim() == "[Script Info]" { + line.push_str("\nScaledBorderAndShadow: yes") + } else if let Some(capture) = re.captures(line) { let start = capture.name("start").map_or(NaiveTime::default(), |s| { NaiveTime::parse_from_str(s.as_str(), "%H:%M:%S.%f").unwrap() }); @@ -749,29 +744,32 @@ fn fix_subtitle_length(raw: &mut Vec, max_length: NaiveTime) { NaiveTime::parse_from_str(s.as_str(), "%H:%M:%S.%f").unwrap() }); - if start > max_length { - continue; - } else if end > max_length { - new.push_str( - re.replace( + if end > max_length { + *line = re + .replace( line, format!( "Dialogue: {},{},", - format_naive_time(start), + format_naive_time(start.clone()), &length_as_string ), ) .to_string() - .as_str(), - ) - } else { - new.push_str(line) } - } else { - new.push_str(line) + entries.0.push((start, i)); + entries.1.push(i) } - new.push('\n') } - *raw = new.into_bytes() + entries.0.sort_by(|(a, _), (b, _)| a.cmp(b)); + for i in 0..entries.0.len() { + let (_, original_position) = entries.0[i]; + let new_position = entries.1[i]; + + if original_position != new_position { + as_lines.swap(original_position, new_position) + } + } + + *raw = as_lines.join("\n").into_bytes() } From 0beaa99bfd109eab82f07de25a90800d5a753e20 Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 20 Jun 2023 00:08:08 +0200 Subject: [PATCH 023/272] Update supported urls in README --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 64b2f00..a3cbc9a 100644 --- a/README.md +++ b/README.md @@ -108,11 +108,11 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any ### Download **Supported urls** -- Single episode +- Single episode (with [episode filtering](#episode-filtering)) ```shell $ crunchy download https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome ``` -- Series +- Series (with [episode filtering](#episode-filtering)) ```shell $ crunchy download https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` @@ -156,9 +156,11 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any ### Archive **Supported urls** -- Series - - Only series urls are supported, because episode urls are locked to a single audio language. +- Single episode (with [episode filtering](#episode-filtering)) + ```shell + $ crunchy archive https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome + ``` +- Series (with [episode filtering](#episode-filtering)) ```shell $ crunchy archive https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` From 0aa648b1a5239bf4338cd7aebcea33c886a4012e Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 25 May 2023 18:53:56 +0200 Subject: [PATCH 024/272] Add basic search command --- Cargo.lock | 579 +++++++++-------------- Cargo.toml | 6 +- crunchy-cli-core/Cargo.lock | 572 +++++++++------------- crunchy-cli-core/Cargo.toml | 5 +- crunchy-cli-core/src/lib.rs | 5 + crunchy-cli-core/src/search/command.rs | 189 ++++++++ crunchy-cli-core/src/search/filter.rs | 56 +++ crunchy-cli-core/src/search/format.rs | 625 +++++++++++++++++++++++++ crunchy-cli-core/src/search/mod.rs | 5 + crunchy-cli-core/src/utils/parse.rs | 12 +- 10 files changed, 1352 insertions(+), 702 deletions(-) create mode 100644 crunchy-cli-core/src/search/command.rs create mode 100644 crunchy-cli-core/src/search/filter.rs create mode 100644 crunchy-cli-core/src/search/format.rs create mode 100644 crunchy-cli-core/src/search/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 4635644..5fde41d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,13 +15,19 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -33,9 +39,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6342bd4f5a1205d7f41e94a41a901f5647c938cdfa96036338e8533c9d6c2450" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" dependencies = [ "anstyle", "anstyle-parse", @@ -82,9 +88,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.70" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "async-trait" @@ -94,7 +100,7 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn", ] [[package]] @@ -105,15 +111,19 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" [[package]] -name = "base64" -version = "0.21.0" +name = "base64-serde" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +checksum = "ba368df5de76a5bea49aaf0cf1b39ccfbbef176924d1ba5db3e4135216cbe3c7" +dependencies = [ + "base64", + "serde", +] [[package]] name = "bitflags" @@ -132,9 +142,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.12.1" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "bytes" @@ -165,13 +175,13 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.24" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", - "num-integer", "num-traits", "serde", "time 0.1.45", @@ -191,9 +201,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.2.4" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ac1f6381d8d82ab4684768f89c0ea3afe66925ceadb4eeb3fc452ffc55d62" +checksum = "401a4694d2bf92537b6867d94de48c4842089645fdcdf6c71865b175d836e9c2" dependencies = [ "clap_builder", "clap_derive", @@ -202,64 +212,54 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.2.4" +version = "4.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84080e799e54cff944f4b4a4b0e71630b0e0443b25b985175c7dddc1a859b749" +checksum = "72394f3339a76daf211e57d4bcb374410f3965dcc606dd0e03738c7888766980" dependencies = [ "anstream", "anstyle", "bitflags", "clap_lex", - "strsim 0.10.0", + "strsim", ] [[package]] name = "clap_complete" -version = "4.2.1" +version = "4.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a19591b2ab0e3c04b588a0e04ddde7b9eaa423646d1b4a8092879216bf47473" +checksum = "7f6b5c519bab3ea61843a7923d074b04245624bb84a64a8c150f5deb014e388b" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.2.0" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" +checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.15", + "syn", ] [[package]] name = "clap_lex" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" [[package]] name = "clap_mangen" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4237e29de9c6949982ba87d51709204504fb8ed2fd38232fcb1e5bf7d4ba48c8" +checksum = "8f2e32b579dae093c2424a8b7e2bea09c89da01e1ce5065eb2f0a6f1cc15cc1f" dependencies = [ "clap", "roff", ] -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - [[package]] name = "colorchoice" version = "1.0.0" @@ -268,15 +268,15 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "console" -version = "0.15.5" +version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60" +checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" dependencies = [ "encode_unicode", "lazy_static", "libc", "unicode-width", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -286,7 +286,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.20", + "time 0.3.21", "version_check", ] @@ -302,7 +302,7 @@ dependencies = [ "publicsuffix", "serde", "serde_json", - "time 0.3.20", + "time 0.3.21", "url", ] @@ -365,6 +365,7 @@ dependencies = [ "sanitize-filename", "serde", "serde_json", + "serde_plain", "shlex", "sys-locale", "tempfile", @@ -374,9 +375,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75b403a64b4cc8ed9a96cb16588475a93cb5c8643cf960907a54ae6f6ac3f0d" +checksum = "510ab662065c5ff28678e66fc1ad243727044642f2dd02a5bbadc12aa2717779" dependencies = [ "aes", "async-trait", @@ -396,18 +397,18 @@ dependencies = [ "serde_urlencoded", "smart-default", "tokio", - "webpki-roots 0.23.0", + "webpki-roots 0.23.1", ] [[package]] name = "crunchyroll-rs-internal" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91a9978a505750f606a1fcf1efd5970d20521310e886839f2ad95c31354e54e" +checksum = "2a1e71fd50850102f81e439c08ffcb69ae98b64d4eb292c359a33ac2253aaa91" dependencies = [ - "darling 0.14.4", + "darling", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -422,134 +423,57 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.2.5" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbcf33c2a618cbe41ee43ae6e9f2e48368cd9f9db2896f10167d8d762679f639" +checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e" dependencies = [ "nix", - "windows-sys 0.45.0", -] - -[[package]] -name = "cxx" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn 2.0.15", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.15", + "windows-sys 0.48.0", ] [[package]] name = "darling" -version = "0.10.2" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" dependencies = [ - "darling_core 0.10.2", - "darling_macro 0.10.2", -] - -[[package]] -name = "darling" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" -dependencies = [ - "darling_core 0.14.4", - "darling_macro 0.14.4", + "darling_core", + "darling_macro", ] [[package]] name = "darling_core" -version = "0.10.2" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim 0.9.3", - "syn 1.0.109", -] - -[[package]] -name = "darling_core" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn 1.0.109", + "strsim", + "syn", ] [[package]] name = "darling_macro" -version = "0.10.2" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ - "darling_core 0.10.2", + "darling_core", "quote", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" -dependencies = [ - "darling_core 0.14.4", - "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "dash-mpd" -version = "0.7.3" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4937210c839d6f764b196afa05349927a8a2cc204ad613086e81defcddd4ade1" +checksum = "306d758462ad461116dfd0680c824691449974c6ab697464a3ccdad925dde7c0" dependencies = [ + "base64", + "base64-serde", "chrono", "fs-err", "iso8601", @@ -566,34 +490,35 @@ dependencies = [ [[package]] name = "derive_setters" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1cf41b4580a37cca5ef2ada2cc43cf5d6be3983f4522e83010d67ab6925e84b" +checksum = "4e8ef033054e131169b8f0f9a7af8f5533a9436fadf3c500ed547f730f07090d" dependencies = [ - "darling 0.10.2", + "darling", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "dirs" -version = "5.0.0" +version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dece029acd3353e3a58ac2e3eb3c8d6c35827a892edc6cc4138ef9c33df46ecd" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04414300db88f70d74c5ff54e50f9e1d1737d9a5b90f53fcf2e95ca2a9ab554b" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" dependencies = [ "libc", + "option-ext", "redox_users", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -670,9 +595,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] @@ -753,9 +678,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -764,9 +689,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21" +checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" dependencies = [ "bytes", "fnv", @@ -874,9 +799,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.23.2" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7" dependencies = [ "http", "hyper", @@ -914,12 +839,11 @@ dependencies = [ [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", ] [[package]] @@ -949,6 +873,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -962,11 +896,12 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.3" +version = "0.17.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cef509aa9bc73864d6756f0d34d35504af3cf0844373afe9b8669a5b8005a729" +checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057" dependencies = [ "console", + "instant", "number_prefix", "portable-atomic", "unicode-width", @@ -993,9 +928,9 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi 0.3.1", "libc", @@ -1037,9 +972,9 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" dependencies = [ "wasm-bindgen", ] @@ -1052,39 +987,27 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.142" +version = "0.2.146" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" - -[[package]] -name = "link-cplusplus" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" -dependencies = [ - "cc", -] +checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" [[package]] name = "linux-raw-sys" -version = "0.3.4" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36eb31c1778188ae1e64398743890d0877fef36d11521ac60406b42016e8c2cf" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "log" -version = "0.4.17" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" [[package]] name = "m3u8-rs" -version = "5.0.3" +version = "5.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c3b9f971e885044cb57330d3c89a4f3bd45fe97d01c93b3dcec57096efacffc" +checksum = "d39af8845edca961e3286dcbafeb9e6407d3df6a616ef086847162d46f438d75" dependencies = [ "chrono", "nom", @@ -1116,14 +1039,13 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mio" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -1166,16 +1088,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.15" @@ -1203,15 +1115,15 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "once_cell" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.52" +version = "0.10.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" +checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019" dependencies = [ "bitflags", "cfg-if", @@ -1230,7 +1142,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn", ] [[package]] @@ -1241,9 +1153,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.87" +version = "0.9.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" +checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617" dependencies = [ "cc", "libc", @@ -1252,10 +1164,16 @@ dependencies = [ ] [[package]] -name = "percent-encoding" -version = "2.2.0" +name = "option-ext" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" @@ -1271,21 +1189,21 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "portable-atomic" -version = "0.3.19" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f6a7b87c2e435a3241addceeeff740ff8b7e76b74c13bf9acb17fa454ea00b" +checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794" [[package]] name = "proc-macro2" -version = "1.0.56" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" dependencies = [ "unicode-ident", ] @@ -1318,9 +1236,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.26" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] @@ -1356,9 +1274,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.1" +version = "1.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" +checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" dependencies = [ "aho-corasick", "memchr", @@ -1367,17 +1285,17 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "reqwest" -version = "0.11.16" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ - "base64 0.21.0", + "base64", "bytes", "cookie", "cookie_store", @@ -1439,9 +1357,9 @@ checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" [[package]] name = "rustix" -version = "0.37.14" +version = "0.37.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b864d3c18a5785a05953adeed93e2dca37ed30f18e69bba9f30079d51f363f" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" dependencies = [ "bitflags", "errno", @@ -1453,14 +1371,14 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.8" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e" dependencies = [ "log", "ring", + "rustls-webpki", "sct", - "webpki", ] [[package]] @@ -1469,7 +1387,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" dependencies = [ - "base64 0.21.0", + "base64", ] [[package]] @@ -1507,12 +1425,6 @@ dependencies = [ "windows-sys 0.42.0", ] -[[package]] -name = "scratch" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" - [[package]] name = "sct" version = "0.7.0" @@ -1525,9 +1437,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.8.2" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" +checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" dependencies = [ "bitflags", "core-foundation", @@ -1538,9 +1450,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" dependencies = [ "core-foundation-sys", "libc", @@ -1548,22 +1460,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.160" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.160" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn", ] [[package]] @@ -1577,6 +1489,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_plain" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6018081315db179d0ce57b1fe4b62a12a0028c9cf9bbef868c9cf477b3c34ae" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1591,30 +1512,30 @@ dependencies = [ [[package]] name = "serde_with" -version = "2.3.2" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "331bb8c3bf9b92457ab7abecf07078c13f7d270ba490103e84e8b014490cd0b0" +checksum = "9f02d8aa6e3c385bf084924f660ce2a3a6bd333ba55b35e8590b321f35d88513" dependencies = [ - "base64 0.13.1", + "base64", "chrono", "hex", "indexmap", "serde", "serde_json", "serde_with_macros", - "time 0.3.20", + "time 0.3.21", ] [[package]] name = "serde_with_macros" -version = "2.3.2" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859011bddcc11f289f07f467cc1fe01c7a941daa4d8f6c40d4d1c92eb6d9319c" +checksum = "edc7d5d3932fb12ce722ee5e64dd38c504efba37567f0c402f6ca728c3b8b070" dependencies = [ - "darling 0.14.4", + "darling", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -1634,13 +1555,13 @@ dependencies = [ [[package]] name = "smart-default" -version = "0.6.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6" +checksum = "0eb01866308440fc64d6c44d9e86c5cc17adfe33c4d6eed55da9145044d0ffc1" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -1665,12 +1586,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "strsim" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" - [[package]] name = "strsim" version = "0.10.0" @@ -1679,20 +1594,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ "proc-macro2", "quote", @@ -1722,15 +1626,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "termcolor" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" -dependencies = [ - "winapi-util", -] - [[package]] name = "terminal_size" version = "0.2.6" @@ -1758,7 +1653,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn", ] [[package]] @@ -1774,9 +1669,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" dependencies = [ "itoa", "serde", @@ -1786,15 +1681,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" dependencies = [ "time-core", ] @@ -1816,9 +1711,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.27.0" +version = "1.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" +checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" dependencies = [ "autocfg", "bytes", @@ -1828,18 +1723,18 @@ dependencies = [ "pin-project-lite", "socket2", "tokio-macros", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn", ] [[package]] @@ -1854,13 +1749,12 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.23.4" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +checksum = "e0d409377ff5b1e3ca6437aa86c1eb7d40c134bfec254e44c830defa92669db5" dependencies = [ "rustls", "tokio", - "webpki", ] [[package]] @@ -1877,9 +1771,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ "bytes", "futures-core", @@ -1908,9 +1802,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", ] @@ -1935,9 +1829,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "unicode-normalization" @@ -1962,12 +1856,12 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" dependencies = [ "form_urlencoded", - "idna 0.3.0", + "idna 0.4.0", "percent-encoding", ] @@ -2013,9 +1907,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2023,24 +1917,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.109", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.34" +version = "0.4.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e" dependencies = [ "cfg-if", "js-sys", @@ -2050,9 +1944,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2060,28 +1954,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" [[package]] name = "web-sys" -version = "0.3.61" +version = "0.3.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" dependencies = [ "js-sys", "wasm-bindgen", @@ -2108,9 +2002,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.23.0" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa54963694b65584e170cf5dc46aeb4dcaa5584e652ff5f3952e56d66aff0125" +checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" dependencies = [ "rustls-webpki", ] @@ -2131,15 +2025,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index bad4772..4273955 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,14 +5,14 @@ version = "3.0.0-dev.13" edition = "2021" [dependencies] -tokio = { version = "1.27", features = ["macros", "rt-multi-thread", "time"], default-features = false } +tokio = { version = "1.28", features = ["macros", "rt-multi-thread", "time"], default-features = false } crunchy-cli-core = { path = "./crunchy-cli-core" } [build-dependencies] chrono = "0.4" -clap = { version = "4.2", features = ["string"] } -clap_complete = "4.2" +clap = { version = "4.3", features = ["string"] } +clap_complete = "4.3" clap_mangen = "0.2" crunchy-cli-core = { path = "./crunchy-cli-core" } diff --git a/crunchy-cli-core/Cargo.lock b/crunchy-cli-core/Cargo.lock index 3904323..c5b7300 100644 --- a/crunchy-cli-core/Cargo.lock +++ b/crunchy-cli-core/Cargo.lock @@ -15,13 +15,19 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -33,9 +39,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6342bd4f5a1205d7f41e94a41a901f5647c938cdfa96036338e8533c9d6c2450" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" dependencies = [ "anstyle", "anstyle-parse", @@ -82,9 +88,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.70" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "async-trait" @@ -94,7 +100,7 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn", ] [[package]] @@ -105,15 +111,19 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" [[package]] -name = "base64" -version = "0.21.0" +name = "base64-serde" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +checksum = "ba368df5de76a5bea49aaf0cf1b39ccfbbef176924d1ba5db3e4135216cbe3c7" +dependencies = [ + "base64", + "serde", +] [[package]] name = "bitflags" @@ -132,9 +142,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.12.1" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "bytes" @@ -165,13 +175,13 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.24" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", - "num-integer", "num-traits", "serde", "time 0.1.45", @@ -191,9 +201,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.2.4" +version = "4.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ac1f6381d8d82ab4684768f89c0ea3afe66925ceadb4eeb3fc452ffc55d62" +checksum = "ca8f255e4b8027970e78db75e78831229c9815fdbfa67eb1a1b777a62e24b4a0" dependencies = [ "clap_builder", "clap_derive", @@ -202,44 +212,34 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.2.4" +version = "4.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84080e799e54cff944f4b4a4b0e71630b0e0443b25b985175c7dddc1a859b749" +checksum = "acd4f3c17c83b0ba34ffbc4f8bbd74f079413f747f84a6f89292f138057e36ab" dependencies = [ "anstream", "anstyle", "bitflags", "clap_lex", - "strsim 0.10.0", + "strsim", ] [[package]] name = "clap_derive" -version = "4.2.0" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" +checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.15", + "syn", ] [[package]] name = "clap_lex" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" - -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] +checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" [[package]] name = "colorchoice" @@ -249,15 +249,15 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "console" -version = "0.15.5" +version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60" +checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" dependencies = [ "encode_unicode", "lazy_static", "libc", "unicode-width", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -267,7 +267,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.20", + "time 0.3.22", "version_check", ] @@ -283,7 +283,7 @@ dependencies = [ "publicsuffix", "serde", "serde_json", - "time 0.3.20", + "time 0.3.22", "url", ] @@ -343,9 +343,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75b403a64b4cc8ed9a96cb16588475a93cb5c8643cf960907a54ae6f6ac3f0d" +checksum = "510ab662065c5ff28678e66fc1ad243727044642f2dd02a5bbadc12aa2717779" dependencies = [ "aes", "async-trait", @@ -365,18 +365,18 @@ dependencies = [ "serde_urlencoded", "smart-default", "tokio", - "webpki-roots 0.23.0", + "webpki-roots 0.23.1", ] [[package]] name = "crunchyroll-rs-internal" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91a9978a505750f606a1fcf1efd5970d20521310e886839f2ad95c31354e54e" +checksum = "2a1e71fd50850102f81e439c08ffcb69ae98b64d4eb292c359a33ac2253aaa91" dependencies = [ - "darling 0.14.4", + "darling", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -391,134 +391,57 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.2.5" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbcf33c2a618cbe41ee43ae6e9f2e48368cd9f9db2896f10167d8d762679f639" +checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e" dependencies = [ "nix", - "windows-sys 0.45.0", -] - -[[package]] -name = "cxx" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61f1b6389c3fe1c316bf8a4dccc90a38208354b330925bce1f74a6c4756eb93" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cee708e8962df2aeb38f594aae5d827c022b6460ac71a7a3e2c3c2aae5a07b" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn 2.0.15", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7944172ae7e4068c533afbb984114a56c46e9ccddda550499caa222902c7f7bb" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.94" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.15", + "windows-sys 0.48.0", ] [[package]] name = "darling" -version = "0.10.2" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" dependencies = [ - "darling_core 0.10.2", - "darling_macro 0.10.2", -] - -[[package]] -name = "darling" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" -dependencies = [ - "darling_core 0.14.4", - "darling_macro 0.14.4", + "darling_core", + "darling_macro", ] [[package]] name = "darling_core" -version = "0.10.2" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim 0.9.3", - "syn 1.0.109", -] - -[[package]] -name = "darling_core" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim 0.10.0", - "syn 1.0.109", + "strsim", + "syn", ] [[package]] name = "darling_macro" -version = "0.10.2" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ - "darling_core 0.10.2", + "darling_core", "quote", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" -dependencies = [ - "darling_core 0.14.4", - "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "dash-mpd" -version = "0.7.3" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4937210c839d6f764b196afa05349927a8a2cc204ad613086e81defcddd4ade1" +checksum = "8b97b7a11cc6dcf0c803554cbd7f7d8dfef99c598e6a310403bb5699d9a94076" dependencies = [ + "base64", + "base64-serde", "chrono", "fs-err", "iso8601", @@ -535,34 +458,35 @@ dependencies = [ [[package]] name = "derive_setters" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1cf41b4580a37cca5ef2ada2cc43cf5d6be3983f4522e83010d67ab6925e84b" +checksum = "4e8ef033054e131169b8f0f9a7af8f5533a9436fadf3c500ed547f730f07090d" dependencies = [ - "darling 0.10.2", + "darling", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "dirs" -version = "5.0.0" +version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dece029acd3353e3a58ac2e3eb3c8d6c35827a892edc6cc4138ef9c33df46ecd" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04414300db88f70d74c5ff54e50f9e1d1737d9a5b90f53fcf2e95ca2a9ab554b" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" dependencies = [ "libc", + "option-ext", "redox_users", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -639,9 +563,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ "percent-encoding", ] @@ -722,9 +646,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -733,9 +657,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21" +checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" dependencies = [ "bytes", "fnv", @@ -843,9 +767,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.23.2" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7" dependencies = [ "http", "hyper", @@ -869,9 +793,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.56" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -883,12 +807,11 @@ dependencies = [ [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", ] [[package]] @@ -918,6 +841,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -931,11 +864,12 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.3" +version = "0.17.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cef509aa9bc73864d6756f0d34d35504af3cf0844373afe9b8669a5b8005a729" +checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057" dependencies = [ "console", + "instant", "number_prefix", "portable-atomic", "unicode-width", @@ -962,9 +896,9 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ "hermit-abi 0.3.1", "libc", @@ -1006,9 +940,9 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" dependencies = [ "wasm-bindgen", ] @@ -1021,39 +955,27 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.142" +version = "0.2.146" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" - -[[package]] -name = "link-cplusplus" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" -dependencies = [ - "cc", -] +checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" [[package]] name = "linux-raw-sys" -version = "0.3.4" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36eb31c1778188ae1e64398743890d0877fef36d11521ac60406b42016e8c2cf" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "m3u8-rs" -version = "5.0.3" +version = "5.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c3b9f971e885044cb57330d3c89a4f3bd45fe97d01c93b3dcec57096efacffc" +checksum = "d39af8845edca961e3286dcbafeb9e6407d3df6a616ef086847162d46f438d75" dependencies = [ "chrono", "nom", @@ -1085,14 +1007,13 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mio" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -1135,16 +1056,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.15" @@ -1172,15 +1083,15 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "once_cell" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.52" +version = "0.10.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" +checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019" dependencies = [ "bitflags", "cfg-if", @@ -1199,7 +1110,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn", ] [[package]] @@ -1210,9 +1121,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.87" +version = "0.9.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" +checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617" dependencies = [ "cc", "libc", @@ -1221,10 +1132,16 @@ dependencies = [ ] [[package]] -name = "percent-encoding" -version = "2.2.0" +name = "option-ext" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" @@ -1240,21 +1157,21 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "portable-atomic" -version = "0.3.19" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f6a7b87c2e435a3241addceeeff740ff8b7e76b74c13bf9acb17fa454ea00b" +checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794" [[package]] name = "proc-macro2" -version = "1.0.56" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ "unicode-ident", ] @@ -1287,9 +1204,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.26" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] @@ -1325,9 +1242,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.1" +version = "1.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" +checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" dependencies = [ "aho-corasick", "memchr", @@ -1336,17 +1253,17 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "reqwest" -version = "0.11.16" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ - "base64 0.21.0", + "base64", "bytes", "cookie", "cookie_store", @@ -1402,9 +1319,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.14" +version = "0.37.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b864d3c18a5785a05953adeed93e2dca37ed30f18e69bba9f30079d51f363f" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" dependencies = [ "bitflags", "errno", @@ -1416,14 +1333,14 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.8" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e" dependencies = [ "log", "ring", + "rustls-webpki", "sct", - "webpki", ] [[package]] @@ -1432,7 +1349,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" dependencies = [ - "base64 0.21.0", + "base64", ] [[package]] @@ -1470,12 +1387,6 @@ dependencies = [ "windows-sys 0.42.0", ] -[[package]] -name = "scratch" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" - [[package]] name = "sct" version = "0.7.0" @@ -1488,9 +1399,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.8.2" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" +checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" dependencies = [ "bitflags", "core-foundation", @@ -1501,9 +1412,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" dependencies = [ "core-foundation-sys", "libc", @@ -1511,22 +1422,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.160" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.160" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn", ] [[package]] @@ -1554,30 +1465,30 @@ dependencies = [ [[package]] name = "serde_with" -version = "2.3.2" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "331bb8c3bf9b92457ab7abecf07078c13f7d270ba490103e84e8b014490cd0b0" +checksum = "9f02d8aa6e3c385bf084924f660ce2a3a6bd333ba55b35e8590b321f35d88513" dependencies = [ - "base64 0.13.1", + "base64", "chrono", "hex", "indexmap", "serde", "serde_json", "serde_with_macros", - "time 0.3.20", + "time 0.3.22", ] [[package]] name = "serde_with_macros" -version = "2.3.2" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859011bddcc11f289f07f467cc1fe01c7a941daa4d8f6c40d4d1c92eb6d9319c" +checksum = "edc7d5d3932fb12ce722ee5e64dd38c504efba37567f0c402f6ca728c3b8b070" dependencies = [ - "darling 0.14.4", + "darling", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -1597,13 +1508,13 @@ dependencies = [ [[package]] name = "smart-default" -version = "0.6.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6" +checksum = "0eb01866308440fc64d6c44d9e86c5cc17adfe33c4d6eed55da9145044d0ffc1" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -1628,12 +1539,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "strsim" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" - [[package]] name = "strsim" version = "0.10.0" @@ -1642,20 +1547,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ "proc-macro2", "quote", @@ -1674,24 +1568,16 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.5.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" dependencies = [ + "autocfg", "cfg-if", "fastrand", "redox_syscall 0.3.5", "rustix", - "windows-sys 0.45.0", -] - -[[package]] -name = "termcolor" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" -dependencies = [ - "winapi-util", + "windows-sys 0.48.0", ] [[package]] @@ -1721,7 +1607,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn", ] [[package]] @@ -1737,9 +1623,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.20" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" dependencies = [ "itoa", "serde", @@ -1749,15 +1635,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" dependencies = [ "time-core", ] @@ -1779,9 +1665,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.27.0" +version = "1.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" +checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" dependencies = [ "autocfg", "bytes", @@ -1791,18 +1677,18 @@ dependencies = [ "pin-project-lite", "socket2", "tokio-macros", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] name = "tokio-macros" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.15", + "syn", ] [[package]] @@ -1817,13 +1703,12 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.23.4" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ "rustls", "tokio", - "webpki", ] [[package]] @@ -1840,9 +1725,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ "bytes", "futures-core", @@ -1871,9 +1756,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", ] @@ -1898,9 +1783,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "unicode-normalization" @@ -1925,12 +1810,12 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.3.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" dependencies = [ "form_urlencoded", - "idna 0.3.0", + "idna 0.4.0", "percent-encoding", ] @@ -1976,9 +1861,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1986,24 +1871,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.109", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.34" +version = "0.4.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e" dependencies = [ "cfg-if", "js-sys", @@ -2013,9 +1898,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2023,28 +1908,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" [[package]] name = "web-sys" -version = "0.3.61" +version = "0.3.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" dependencies = [ "js-sys", "wasm-bindgen", @@ -2071,9 +1956,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.23.0" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa54963694b65584e170cf5dc46aeb4dcaa5584e652ff5f3952e56d66aff0125" +checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" dependencies = [ "rustls-webpki", ] @@ -2094,15 +1979,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 62f83ec..5cadd08 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -9,7 +9,7 @@ anyhow = "1.0" async-trait = "0.1" clap = { version = "4.2", features = ["derive", "string"] } chrono = "0.4" -crunchyroll-rs = { version = "0.3.4", features = ["dash-stream"] } +crunchyroll-rs = { version = "0.3.6", features = ["dash-stream"] } ctrlc = "3.2" dirs = "5.0" derive_setters = "0.1" @@ -23,10 +23,11 @@ reqwest = { version = "0.11", default-features = false, features = ["socks"] } sanitize-filename = "0.4" serde = "1.0" serde_json = "1.0" +serde_plain = "1.0" shlex = "1.1" tempfile = "3.5" terminal_size = "0.2" -tokio = { version = "1.27", features = ["macros", "rt-multi-thread", "time"] } +tokio = { version = "1.28", features = ["macros", "rt-multi-thread", "time"] } sys-locale = "0.3" [build-dependencies] diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index 9ae8e83..4de5826 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -14,11 +14,13 @@ use std::{env, fs}; mod archive; mod download; mod login; +mod search; mod utils; pub use archive::Archive; pub use download::Download; pub use login::Login; +pub use search::Search; #[async_trait::async_trait(?Send)] trait Execute { @@ -81,6 +83,7 @@ enum Command { Archive(Archive), Download(Download), Login(Login), + Search(Search), } #[derive(Debug, Parser)] @@ -128,6 +131,7 @@ pub async fn cli_entrypoint() { pre_check_executor(login).await } } + Command::Search(search) => pre_check_executor(search).await, }; let ctx = match create_ctx(&mut cli).await { @@ -173,6 +177,7 @@ pub async fn cli_entrypoint() { Command::Archive(archive) => execute_executor(archive, ctx).await, Command::Download(download) => execute_executor(download, ctx).await, Command::Login(login) => execute_executor(login, ctx).await, + Command::Search(search) => execute_executor(search, ctx).await, }; } diff --git a/crunchy-cli-core/src/search/command.rs b/crunchy-cli-core/src/search/command.rs new file mode 100644 index 0000000..442dea5 --- /dev/null +++ b/crunchy-cli-core/src/search/command.rs @@ -0,0 +1,189 @@ +use crate::search::filter::FilterOptions; +use crate::search::format::Format; +use crate::utils::context::Context; +use crate::utils::parse::{parse_url, UrlFilter}; +use crate::Execute; +use anyhow::{bail, Result}; +use crunchyroll_rs::common::StreamExt; +use crunchyroll_rs::search::QueryResults; +use crunchyroll_rs::{Episode, Locale, MediaCollection, MovieListing, MusicVideo, Series}; + +#[derive(Debug, clap::Parser)] +pub struct Search { + #[arg(help = "Audio languages to include")] + #[arg(long, default_values_t = vec![crate::utils::locale::system_locale()])] + audio: Vec, + + #[arg(help = "Filter the locale/language of subtitles according to the value of `--audio`")] + #[arg(long, default_value_t = false)] + filter_subtitles: bool, + + #[arg(help = "Limit of search top search results")] + #[arg(long, default_value_t = 5)] + search_top_results_limit: u32, + #[arg(help = "Limit of search series results")] + #[arg(long, default_value_t = 0)] + search_series_limit: u32, + #[arg(help = "Limit of search movie listing results")] + #[arg(long, default_value_t = 0)] + search_movie_listing_limit: u32, + #[arg(help = "Limit of search episode results")] + #[arg(long, default_value_t = 0)] + search_episode_limit: u32, + #[arg(help = "Limit of search music results")] + #[arg(long, default_value_t = 0)] + search_music_limit: u32, + + /// Format of the output text. + /// + /// You can specify keywords in a specific pattern and they will get replaced in the output text. + /// The required pattern for this begins with `{{`, then the keyword, and closes with `}}` (e.g. `{{episode.title}}`). + /// For example, if you want to get the title of an episode, you can use `Title {{episode.title}}` and `{{episode.title}}` will be replaced with the episode title + /// + /// See the following list for all keywords and their meaning: + /// series.title → Series title + /// series.description → Series description + /// + /// season.title → Season title + /// season.description → Season description + /// season.number → Season number + /// + /// episode.title → Episode title + /// episode.description → Episode description + /// episode.locale → Episode locale/language + /// episode.number → Episode number + /// episode.sequence_number → Episode number. This number is unique unlike `episode.number` which sometimes can be duplicated + /// + /// movie_listing.title → Movie listing title + /// movie_listing.description → Movie listing description + /// + /// movie.title → Movie title + /// movie.description → Movie description + /// + /// music_video.title → Music video title + /// music_video.description → Music video description + /// + /// concert.title → Concert title + /// concert.description → Concert description + /// + /// stream.locale → Stream locale/language + /// stream.dash_url → Stream url in DASH format + /// stream.hls_url → Stream url in HLS format + /// + /// subtitle.locale → Subtitle locale/language + /// subtitle.url → Subtitle url + #[arg(short, long, verbatim_doc_comment)] + #[arg(default_value = "S{{season.number}}E{{episode.number}} - {{episode.title}}")] + output: String, + + input: String, +} + +#[async_trait::async_trait(?Send)] +impl Execute for Search { + async fn execute(self, ctx: Context) -> Result<()> { + let input = if crunchyroll_rs::parse::parse_url(&self.input).is_some() { + match parse_url(&ctx.crunchy, self.input.clone(), true).await { + Ok(ok) => vec![ok], + Err(e) => bail!("url {} could not be parsed: {}", self.input, e), + } + } else { + let mut output = vec![]; + + let query = resolve_query(&self, ctx.crunchy.query(&self.input)).await?; + output.extend(query.0.into_iter().map(|m| (m, UrlFilter::default()))); + output.extend( + query + .1 + .into_iter() + .map(|s| (s.into(), UrlFilter::default())), + ); + output.extend( + query + .2 + .into_iter() + .map(|m| (m.into(), UrlFilter::default())), + ); + output.extend( + query + .3 + .into_iter() + .map(|e| (e.into(), UrlFilter::default())), + ); + output.extend( + query + .4 + .into_iter() + .map(|m| (m.into(), UrlFilter::default())), + ); + + output + }; + + for (media_collection, url_filter) in input { + let filter_options = FilterOptions { + audio: self.audio.clone(), + filter_subtitles: self.filter_subtitles, + url_filter, + }; + + let format = Format::new(self.output.clone(), filter_options)?; + println!("{}", format.parse(media_collection).await?); + } + + Ok(()) + } +} + +macro_rules! resolve_query { + ($limit:expr, $vec:expr, $item:expr) => { + if $limit > 0 { + let mut item_results = $item; + while let Some(item) = item_results.next().await { + $vec.push(item?); + if $vec.len() >= $limit as usize { + break; + } + } + } + }; +} + +async fn resolve_query( + search: &Search, + query_results: QueryResults, +) -> Result<( + Vec, + Vec, + Vec, + Vec, + Vec, +)> { + let mut media_collection = vec![]; + let mut series = vec![]; + let mut movie_listing = vec![]; + let mut episode = vec![]; + let mut music_video = vec![]; + + resolve_query!( + search.search_top_results_limit, + media_collection, + query_results.top_results + ); + resolve_query!(search.search_series_limit, series, query_results.series); + resolve_query!( + search.search_movie_listing_limit, + movie_listing, + query_results.movie_listing + ); + resolve_query!(search.search_episode_limit, episode, query_results.episode); + resolve_query!(search.search_music_limit, music_video, query_results.music); + + Ok(( + media_collection, + series, + movie_listing, + episode, + music_video, + )) +} diff --git a/crunchy-cli-core/src/search/filter.rs b/crunchy-cli-core/src/search/filter.rs new file mode 100644 index 0000000..6a8e4ee --- /dev/null +++ b/crunchy-cli-core/src/search/filter.rs @@ -0,0 +1,56 @@ +use crate::utils::parse::UrlFilter; +use crunchyroll_rs::media::Subtitle; +use crunchyroll_rs::{Episode, Locale, MovieListing, Season, Series}; + +pub struct FilterOptions { + pub audio: Vec, + pub filter_subtitles: bool, + pub url_filter: UrlFilter, +} + +impl FilterOptions { + pub fn check_series(&self, series: &Series) -> bool { + self.check_audio_language(&series.audio_locales) + } + + pub fn filter_seasons(&self, mut seasons: Vec) -> Vec { + seasons.retain(|s| { + self.check_audio_language(&s.audio_locales) + && self.url_filter.is_season_valid(s.season_number) + }); + seasons + } + + pub fn filter_episodes(&self, mut episodes: Vec) -> Vec { + episodes.retain(|e| { + self.check_audio_language(&vec![e.audio_locale.clone()]) + && self + .url_filter + .is_episode_valid(e.episode_number, e.season_number) + }); + episodes + } + + pub fn check_movie_listing(&self, movie_listing: &MovieListing) -> bool { + self.check_audio_language( + &movie_listing + .audio_locale + .clone() + .map_or(vec![], |a| vec![a.clone()]), + ) + } + + pub fn filter_subtitles(&self, mut subtitles: Vec) -> Vec { + if self.filter_subtitles { + subtitles.retain(|s| self.check_audio_language(&vec![s.locale.clone()])) + } + subtitles + } + + fn check_audio_language(&self, audio: &Vec) -> bool { + if !self.audio.is_empty() { + return self.audio.iter().any(|a| audio.contains(a)); + } + true + } +} diff --git a/crunchy-cli-core/src/search/format.rs b/crunchy-cli-core/src/search/format.rs new file mode 100644 index 0000000..946bfd5 --- /dev/null +++ b/crunchy-cli-core/src/search/format.rs @@ -0,0 +1,625 @@ +use crate::search::filter::FilterOptions; +use anyhow::{bail, Result}; +use crunchyroll_rs::media::{Stream, Subtitle}; +use crunchyroll_rs::{ + Concert, Episode, Locale, MediaCollection, Movie, MovieListing, MusicVideo, Season, Series, +}; +use regex::Regex; +use serde::Serialize; +use serde_json::{Map, Value}; +use std::collections::HashMap; +use std::ops::Range; + +#[derive(Default, Serialize)] +struct FormatSeries { + pub title: String, + pub description: String, +} + +impl From<&Series> for FormatSeries { + fn from(value: &Series) -> Self { + Self { + title: value.title.clone(), + description: value.description.clone(), + } + } +} + +#[derive(Default, Serialize)] +struct FormatSeason { + pub title: String, + pub description: String, + pub number: u32, +} + +impl From<&Season> for FormatSeason { + fn from(value: &Season) -> Self { + Self { + title: value.title.clone(), + description: value.description.clone(), + number: value.season_number, + } + } +} + +#[derive(Default, Serialize)] +struct FormatEpisode { + pub title: String, + pub description: String, + pub locale: Locale, + pub number: u32, + pub sequence_number: f32, +} + +impl From<&Episode> for FormatEpisode { + fn from(value: &Episode) -> Self { + Self { + title: value.title.clone(), + description: value.description.clone(), + locale: value.audio_locale.clone(), + number: value.episode_number, + sequence_number: value.sequence_number, + } + } +} + +#[derive(Default, Serialize)] +struct FormatMovieListing { + pub title: String, + pub description: String, +} + +impl From<&MovieListing> for FormatMovieListing { + fn from(value: &MovieListing) -> Self { + Self { + title: value.title.clone(), + description: value.description.clone(), + } + } +} + +#[derive(Default, Serialize)] +struct FormatMovie { + pub title: String, + pub description: String, +} + +impl From<&Movie> for FormatMovie { + fn from(value: &Movie) -> Self { + Self { + title: value.title.clone(), + description: value.description.clone(), + } + } +} + +#[derive(Default, Serialize)] +struct FormatMusicVideo { + pub title: String, + pub description: String, +} + +impl From<&MusicVideo> for FormatMusicVideo { + fn from(value: &MusicVideo) -> Self { + Self { + title: value.title.clone(), + description: value.description.clone(), + } + } +} + +#[derive(Default, Serialize)] +struct FormatConcert { + pub title: String, + pub description: String, +} + +impl From<&Concert> for FormatConcert { + fn from(value: &Concert) -> Self { + Self { + title: value.title.clone(), + description: value.description.clone(), + } + } +} + +#[derive(Default, Serialize)] +struct FormatStream { + pub locale: Locale, + pub dash_url: String, + pub hls_url: String, +} + +impl From<&Stream> for FormatStream { + fn from(value: &Stream) -> Self { + let (dash_url, hls_url) = value.variants.get(&Locale::Custom("".to_string())).map_or( + ("".to_string(), "".to_string()), + |v| { + ( + v.adaptive_dash.clone().unwrap_or_default().url, + v.adaptive_hls.clone().unwrap_or_default().url, + ) + }, + ); + + Self { + locale: value.audio_locale.clone(), + dash_url, + hls_url, + } + } +} + +#[derive(Default, Serialize)] +struct FormatSubtitle { + pub locale: Locale, + pub url: String, +} + +impl From<&Subtitle> for FormatSubtitle { + fn from(value: &Subtitle) -> Self { + Self { + locale: value.locale.clone(), + url: value.url.clone(), + } + } +} + +#[derive(Clone, Eq, PartialEq, Hash)] +enum Scope { + Series, + Season, + Episode, + MovieListing, + Movie, + MusicVideo, + Concert, + Stream, + Subtitle, +} + +pub struct Format { + pattern: Vec<(Range, Scope, String)>, + pattern_count: HashMap, + input: String, + filter_options: FilterOptions, +} + +impl Format { + pub fn new(input: String, filter_options: FilterOptions) -> Result { + let scope_regex = Regex::new(r"(?m)\{\{\s*(?P\w+)\.(?P\w+)\s*}}").unwrap(); + let mut pattern = vec![]; + let mut pattern_count = HashMap::new(); + + let field_check = HashMap::from([ + ( + Scope::Series, + serde_json::to_value(FormatSeries::default()).unwrap(), + ), + ( + Scope::Season, + serde_json::to_value(FormatSeason::default()).unwrap(), + ), + ( + Scope::Episode, + serde_json::to_value(FormatEpisode::default()).unwrap(), + ), + ( + Scope::MovieListing, + serde_json::to_value(FormatMovieListing::default()).unwrap(), + ), + ( + Scope::Movie, + serde_json::to_value(FormatMovie::default()).unwrap(), + ), + ( + Scope::MusicVideo, + serde_json::to_value(FormatMusicVideo::default()).unwrap(), + ), + ( + Scope::Concert, + serde_json::to_value(FormatConcert::default()).unwrap(), + ), + ( + Scope::Stream, + serde_json::to_value(FormatStream::default()).unwrap(), + ), + ( + Scope::Subtitle, + serde_json::to_value(FormatSubtitle::default()).unwrap(), + ), + ]); + + for capture in scope_regex.captures_iter(&input) { + let full = capture.get(0).unwrap(); + let scope = capture.name("scope").unwrap().as_str(); + let field = capture.name("field").unwrap().as_str(); + + let format_pattern_scope = match scope { + "series" => Scope::Series, + "season" => Scope::Season, + "episode" => Scope::Episode, + "movie_listing" => Scope::MovieListing, + "movie" => Scope::Movie, + "music_video" => Scope::MusicVideo, + "concert" => Scope::Concert, + "stream" => Scope::Stream, + "subtitle" => Scope::Subtitle, + _ => bail!("'{}.{}' is not a valid keyword", scope, field), + }; + + if field_check + .get(&format_pattern_scope) + .unwrap() + .as_object() + .unwrap() + .get(field) + .is_none() + { + bail!("'{}.{}' is not a valid keyword", scope, field) + } + + pattern.push(( + full.start()..full.end(), + format_pattern_scope.clone(), + field.to_string(), + )); + *pattern_count.entry(format_pattern_scope).or_default() += 1 + } + + Ok(Self { + pattern, + pattern_count, + input, + filter_options, + }) + } + + fn check_pattern_count_empty(&self, scope: Scope) -> bool { + self.pattern_count.get(&scope).cloned().unwrap_or_default() == 0 + } + + pub async fn parse(&self, media_collection: MediaCollection) -> Result { + match &media_collection { + MediaCollection::Series(_) + | MediaCollection::Season(_) + | MediaCollection::Episode(_) => self.parse_series(media_collection).await, + MediaCollection::MovieListing(_) | MediaCollection::Movie(_) => { + self.parse_movie_listing(media_collection).await + } + MediaCollection::MusicVideo(_) => self.parse_music_video(media_collection).await, + MediaCollection::Concert(_) => self.parse_concert(media_collection).await, + } + } + + async fn parse_series(&self, media_collection: MediaCollection) -> Result { + let series_empty = self.check_pattern_count_empty(Scope::Series); + let season_empty = self.check_pattern_count_empty(Scope::Season); + let episode_empty = self.check_pattern_count_empty(Scope::Episode); + let stream_empty = self.check_pattern_count_empty(Scope::Stream) + && self.check_pattern_count_empty(Scope::Subtitle); + + let mut tree: Vec<(Season, Vec<(Episode, Vec)>)> = vec![]; + + let series = if !series_empty { + let series = match &media_collection { + MediaCollection::Series(series) => series.clone(), + MediaCollection::Season(season) => season.series().await?, + MediaCollection::Episode(episode) => episode.series().await?, + _ => panic!(), + }; + if !self.filter_options.check_series(&series) { + return Ok("".to_string()); + } + series + } else { + Series::default() + }; + if !season_empty || !episode_empty || !stream_empty { + let tmp_seasons = match &media_collection { + MediaCollection::Series(series) => series.seasons().await?, + MediaCollection::Season(season) => vec![season.clone()], + MediaCollection::Episode(_) => vec![], + _ => panic!(), + }; + let mut seasons = vec![]; + for mut season in tmp_seasons { + if self + .filter_options + .audio + .iter() + .any(|a| season.audio_locales.contains(a)) + { + seasons.push(season.clone()) + } + seasons.extend(season.version(self.filter_options.audio.clone()).await?); + } + tree.extend( + self.filter_options + .filter_seasons(seasons) + .into_iter() + .map(|s| (s, vec![])), + ) + } else { + tree.push((Season::default(), vec![])) + } + if !episode_empty || !stream_empty { + match &media_collection { + MediaCollection::Episode(episode) => { + let mut episodes = vec![]; + if self.filter_options.audio.contains(&episode.audio_locale) { + episodes.push(episode.clone()) + } + episodes.extend( + episode + .clone() + .version(self.filter_options.audio.clone()) + .await?, + ); + + tree.push(( + Season::default(), + episodes + .into_iter() + .filter(|e| self.filter_options.audio.contains(&e.audio_locale)) + .map(|e| (e, vec![])) + .collect(), + )) + } + _ => { + for (season, episodes) in tree.iter_mut() { + episodes.extend( + self.filter_options + .filter_episodes(season.episodes().await?) + .into_iter() + .map(|e| (e, vec![])), + ) + } + } + }; + } else { + for (_, episodes) in tree.iter_mut() { + episodes.push((Episode::default(), vec![])) + } + } + if !stream_empty { + for (_, episodes) in tree.iter_mut() { + for (episode, streams) in episodes { + streams.push(episode.streams().await?) + } + } + } else { + for (_, episodes) in tree.iter_mut() { + for (_, streams) in episodes { + streams.push(Stream::default()) + } + } + } + + let mut output = vec![]; + let series_map = self.serializable_to_json_map(FormatSeries::from(&series)); + for (season, episodes) in tree { + let season_map = self.serializable_to_json_map(FormatSeason::from(&season)); + for (episode, streams) in episodes { + let episode_map = self.serializable_to_json_map(FormatEpisode::from(&episode)); + for mut stream in streams { + let stream_map = self.serializable_to_json_map(FormatStream::from(&stream)); + if stream.subtitles.is_empty() { + if !self.check_pattern_count_empty(Scope::Subtitle) { + continue; + } + stream + .subtitles + .insert(Locale::Custom("".to_string()), Subtitle::default()); + } + for subtitle in self + .filter_options + .filter_subtitles(stream.subtitles.into_values().collect()) + { + let subtitle_map = + self.serializable_to_json_map(FormatSubtitle::from(&subtitle)); + let replace_map = HashMap::from([ + (Scope::Series, &series_map), + (Scope::Season, &season_map), + (Scope::Episode, &episode_map), + (Scope::Stream, &stream_map), + (Scope::Subtitle, &subtitle_map), + ]); + output.push(self.replace(replace_map)) + } + } + } + } + + Ok(output.join("\n")) + } + + async fn parse_movie_listing(&self, media_collection: MediaCollection) -> Result { + let movie_listing_empty = self.check_pattern_count_empty(Scope::MovieListing); + let movie_empty = self.check_pattern_count_empty(Scope::Movie); + let stream_empty = self.check_pattern_count_empty(Scope::Stream); + + let mut tree: Vec<(Movie, Vec)> = vec![]; + + let movie_listing = if !movie_listing_empty { + let movie_listing = match &media_collection { + MediaCollection::MovieListing(movie_listing) => movie_listing.clone(), + MediaCollection::Movie(movie) => movie.movie_listing().await?, + _ => panic!(), + }; + if !self.filter_options.check_movie_listing(&movie_listing) { + return Ok("".to_string()); + } + movie_listing + } else { + MovieListing::default() + }; + if !movie_empty || !stream_empty { + let movies = match &media_collection { + MediaCollection::MovieListing(movie_listing) => movie_listing.movies().await?, + MediaCollection::Movie(movie) => vec![movie.clone()], + _ => panic!(), + }; + tree.extend(movies.into_iter().map(|m| (m, vec![]))) + } + if !stream_empty { + for (movie, streams) in tree.iter_mut() { + streams.push(movie.streams().await?) + } + } else { + for (_, streams) in tree.iter_mut() { + streams.push(Stream::default()) + } + } + + let mut output = vec![]; + let movie_listing_map = + self.serializable_to_json_map(FormatMovieListing::from(&movie_listing)); + for (movie, streams) in tree { + let movie_map = self.serializable_to_json_map(FormatMovie::from(&movie)); + for mut stream in streams { + let stream_map = self.serializable_to_json_map(FormatStream::from(&stream)); + if stream.subtitles.is_empty() { + if !self.check_pattern_count_empty(Scope::Subtitle) { + continue; + } + stream + .subtitles + .insert(Locale::Custom("".to_string()), Subtitle::default()); + } + for subtitle in self + .filter_options + .filter_subtitles(stream.subtitles.into_values().collect()) + { + let subtitle_map = + self.serializable_to_json_map(FormatSubtitle::from(&subtitle)); + let replace_map = HashMap::from([ + (Scope::MovieListing, &movie_listing_map), + (Scope::Movie, &movie_map), + (Scope::Stream, &stream_map), + (Scope::Subtitle, &subtitle_map), + ]); + output.push(self.replace(replace_map)) + } + } + } + + Ok(output.join("\n")) + } + + async fn parse_music_video(&self, media_collection: MediaCollection) -> Result { + let music_video_empty = self.check_pattern_count_empty(Scope::MusicVideo); + let stream_empty = self.check_pattern_count_empty(Scope::Stream); + + let music_video = if !music_video_empty { + match &media_collection { + MediaCollection::MusicVideo(music_video) => music_video.clone(), + _ => panic!(), + } + } else { + MusicVideo::default() + }; + let mut stream = if !stream_empty { + match &media_collection { + MediaCollection::MusicVideo(music_video) => music_video.streams().await?, + _ => panic!(), + } + } else { + Stream::default() + }; + + let mut output = vec![]; + let music_video_map = self.serializable_to_json_map(FormatMusicVideo::from(&music_video)); + let stream_map = self.serializable_to_json_map(FormatStream::from(&stream)); + if stream.subtitles.is_empty() { + if !self.check_pattern_count_empty(Scope::Subtitle) { + return Ok("".to_string()); + } + stream + .subtitles + .insert(Locale::Custom("".to_string()), Subtitle::default()); + } + for subtitle in self + .filter_options + .filter_subtitles(stream.subtitles.into_values().collect()) + { + let subtitle_map = self.serializable_to_json_map(FormatSubtitle::from(&subtitle)); + let replace_map = HashMap::from([ + (Scope::MusicVideo, &music_video_map), + (Scope::Stream, &stream_map), + (Scope::Subtitle, &subtitle_map), + ]); + output.push(self.replace(replace_map)) + } + + Ok(output.join("\n")) + } + + async fn parse_concert(&self, media_collection: MediaCollection) -> Result { + let concert_empty = self.check_pattern_count_empty(Scope::Concert); + let stream_empty = self.check_pattern_count_empty(Scope::Stream); + + let concert = if !concert_empty { + match &media_collection { + MediaCollection::Concert(concert) => concert.clone(), + _ => panic!(), + } + } else { + Concert::default() + }; + let mut stream = if !stream_empty { + match &media_collection { + MediaCollection::Concert(concert) => concert.streams().await?, + _ => panic!(), + } + } else { + Stream::default() + }; + + let mut output = vec![]; + let concert_map = self.serializable_to_json_map(FormatConcert::from(&concert)); + let stream_map = self.serializable_to_json_map(FormatStream::from(&stream)); + if stream.subtitles.is_empty() { + if !self.check_pattern_count_empty(Scope::Subtitle) { + return Ok("".to_string()); + } + stream + .subtitles + .insert(Locale::Custom("".to_string()), Subtitle::default()); + } + for subtitle in self + .filter_options + .filter_subtitles(stream.subtitles.into_values().collect()) + { + let subtitle_map = self.serializable_to_json_map(FormatSubtitle::from(&subtitle)); + let replace_map = HashMap::from([ + (Scope::MusicVideo, &concert_map), + (Scope::Stream, &stream_map), + (Scope::Subtitle, &subtitle_map), + ]); + output.push(self.replace(replace_map)) + } + + Ok(output.join("\n")) + } + + fn serializable_to_json_map(&self, s: S) -> Map { + serde_json::from_value(serde_json::to_value(s).unwrap()).unwrap() + } + + fn replace(&self, values: HashMap>) -> String { + let mut output = self.input.clone(); + let mut offset = 0; + for (range, scope, field) in &self.pattern { + let item = + serde_plain::to_string(values.get(scope).unwrap().get(field.as_str()).unwrap()) + .unwrap(); + let start = (range.start as i32 + offset) as usize; + let end = (range.end as i32 + offset) as usize; + output.replace_range(start..end, &item); + offset += item.len() as i32 - range.len() as i32; + } + + output + } +} diff --git a/crunchy-cli-core/src/search/mod.rs b/crunchy-cli-core/src/search/mod.rs new file mode 100644 index 0000000..839c844 --- /dev/null +++ b/crunchy-cli-core/src/search/mod.rs @@ -0,0 +1,5 @@ +mod command; +mod filter; +mod format; + +pub use command::Search; diff --git a/crunchy-cli-core/src/utils/parse.rs b/crunchy-cli-core/src/utils/parse.rs index fbcba20..1bf9364 100644 --- a/crunchy-cli-core/src/utils/parse.rs +++ b/crunchy-cli-core/src/utils/parse.rs @@ -8,7 +8,7 @@ use regex::Regex; /// If a struct instance equals the [`Default::default()`] it's considered that no find is applied. /// If `from_*` is [`None`] they're set to [`u32::MIN`]. /// If `to_*` is [`None`] they're set to [`u32::MAX`]. -#[derive(Debug)] +#[derive(Debug, Default)] pub struct InnerUrlFilter { from_episode: Option, to_episode: Option, @@ -16,11 +16,19 @@ pub struct InnerUrlFilter { to_season: Option, } -#[derive(Debug, Default)] +#[derive(Debug)] pub struct UrlFilter { inner: Vec, } +impl Default for UrlFilter { + fn default() -> Self { + Self { + inner: vec![InnerUrlFilter::default()], + } + } +} + impl UrlFilter { pub fn is_season_valid(&self, season: u32) -> bool { self.inner.iter().any(|f| { From e9b4837f448f74628480e8991ffc5455c09d1163 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 19 Jun 2023 17:23:52 +0200 Subject: [PATCH 025/272] Clean up search a bit --- crunchy-cli-core/src/search/format.rs | 297 +++++++++++--------------- 1 file changed, 119 insertions(+), 178 deletions(-) diff --git a/crunchy-cli-core/src/search/format.rs b/crunchy-cli-core/src/search/format.rs index 946bfd5..195b82b 100644 --- a/crunchy-cli-core/src/search/format.rs +++ b/crunchy-cli-core/src/search/format.rs @@ -178,6 +178,29 @@ enum Scope { Subtitle, } +macro_rules! must_match_if_true { + ($condition:expr => $media_collection:ident | $field:pat => $expr:expr) => { + if $condition { + match &$media_collection { + $field => Some($expr), + _ => panic!(), + } + } else { + None + } + }; +} + +macro_rules! self_and_versions { + ($var:expr => $audio:expr) => { + { + let mut items = vec![$var.clone()]; + items.extend($var.clone().version($audio).await?); + items + } + }; +} + pub struct Format { pattern: Vec<(Range, Scope, String)>, pattern_count: HashMap, @@ -191,44 +214,29 @@ impl Format { let mut pattern = vec![]; let mut pattern_count = HashMap::new(); - let field_check = HashMap::from([ - ( - Scope::Series, - serde_json::to_value(FormatSeries::default()).unwrap(), - ), - ( - Scope::Season, - serde_json::to_value(FormatSeason::default()).unwrap(), - ), - ( - Scope::Episode, - serde_json::to_value(FormatEpisode::default()).unwrap(), - ), - ( - Scope::MovieListing, - serde_json::to_value(FormatMovieListing::default()).unwrap(), - ), - ( - Scope::Movie, - serde_json::to_value(FormatMovie::default()).unwrap(), - ), - ( - Scope::MusicVideo, - serde_json::to_value(FormatMusicVideo::default()).unwrap(), - ), - ( - Scope::Concert, - serde_json::to_value(FormatConcert::default()).unwrap(), - ), - ( - Scope::Stream, - serde_json::to_value(FormatStream::default()).unwrap(), - ), - ( - Scope::Subtitle, - serde_json::to_value(FormatSubtitle::default()).unwrap(), - ), - ]); + macro_rules! generate_field_check { + ($($scope:expr => $struct_:ident)+) => { + HashMap::from([ + $( + ( + $scope, + serde_json::from_value::>(serde_json::to_value($struct_::default()).unwrap()).unwrap() + ) + ),+ + ]) + }; + } + let field_check = generate_field_check!( + Scope::Series => FormatSeries + Scope::Season => FormatSeason + Scope::Episode => FormatEpisode + Scope::MovieListing => FormatMovieListing + Scope::Movie => FormatMovie + Scope::MusicVideo => FormatMusicVideo + Scope::Concert => FormatConcert + Scope::Stream => FormatStream + Scope::Subtitle => FormatSubtitle + ); for capture in scope_regex.captures_iter(&input) { let full = capture.get(0).unwrap(); @@ -251,8 +259,6 @@ impl Format { if field_check .get(&format_pattern_scope) .unwrap() - .as_object() - .unwrap() .get(field) .is_none() { @@ -323,16 +329,8 @@ impl Format { _ => panic!(), }; let mut seasons = vec![]; - for mut season in tmp_seasons { - if self - .filter_options - .audio - .iter() - .any(|a| season.audio_locales.contains(a)) - { - seasons.push(season.clone()) - } - seasons.extend(season.version(self.filter_options.audio.clone()).await?); + for season in tmp_seasons { + seasons.extend(self_and_versions!(season => self.filter_options.audio.clone())) } tree.extend( self.filter_options @@ -346,17 +344,7 @@ impl Format { if !episode_empty || !stream_empty { match &media_collection { MediaCollection::Episode(episode) => { - let mut episodes = vec![]; - if self.filter_options.audio.contains(&episode.audio_locale) { - episodes.push(episode.clone()) - } - episodes.extend( - episode - .clone() - .version(self.filter_options.audio.clone()) - .await?, - ); - + let episodes = self_and_versions!(episode => self.filter_options.audio.clone()); tree.push(( Season::default(), episodes @@ -402,31 +390,21 @@ impl Format { let season_map = self.serializable_to_json_map(FormatSeason::from(&season)); for (episode, streams) in episodes { let episode_map = self.serializable_to_json_map(FormatEpisode::from(&episode)); - for mut stream in streams { + for stream in streams { let stream_map = self.serializable_to_json_map(FormatStream::from(&stream)); - if stream.subtitles.is_empty() { - if !self.check_pattern_count_empty(Scope::Subtitle) { - continue; - } - stream - .subtitles - .insert(Locale::Custom("".to_string()), Subtitle::default()); - } - for subtitle in self - .filter_options - .filter_subtitles(stream.subtitles.into_values().collect()) - { - let subtitle_map = - self.serializable_to_json_map(FormatSubtitle::from(&subtitle)); - let replace_map = HashMap::from([ - (Scope::Series, &series_map), - (Scope::Season, &season_map), - (Scope::Episode, &episode_map), - (Scope::Stream, &stream_map), - (Scope::Subtitle, &subtitle_map), - ]); - output.push(self.replace(replace_map)) - } + + output.push( + self.replace_all( + HashMap::from([ + (Scope::Series, &series_map), + (Scope::Season, &season_map), + (Scope::Episode, &episode_map), + (Scope::Stream, &stream_map), + ]), + stream, + ) + .unwrap_or_default(), + ) } } } @@ -477,30 +455,20 @@ impl Format { self.serializable_to_json_map(FormatMovieListing::from(&movie_listing)); for (movie, streams) in tree { let movie_map = self.serializable_to_json_map(FormatMovie::from(&movie)); - for mut stream in streams { + for stream in streams { let stream_map = self.serializable_to_json_map(FormatStream::from(&stream)); - if stream.subtitles.is_empty() { - if !self.check_pattern_count_empty(Scope::Subtitle) { - continue; - } - stream - .subtitles - .insert(Locale::Custom("".to_string()), Subtitle::default()); - } - for subtitle in self - .filter_options - .filter_subtitles(stream.subtitles.into_values().collect()) - { - let subtitle_map = - self.serializable_to_json_map(FormatSubtitle::from(&subtitle)); - let replace_map = HashMap::from([ - (Scope::MovieListing, &movie_listing_map), - (Scope::Movie, &movie_map), - (Scope::Stream, &stream_map), - (Scope::Subtitle, &subtitle_map), - ]); - output.push(self.replace(replace_map)) - } + + output.push( + self.replace_all( + HashMap::from([ + (Scope::MovieListing, &movie_listing_map), + (Scope::Movie, &movie_map), + (Scope::Stream, &stream_map), + ]), + stream, + ) + .unwrap_or_default(), + ) } } @@ -511,100 +479,73 @@ impl Format { let music_video_empty = self.check_pattern_count_empty(Scope::MusicVideo); let stream_empty = self.check_pattern_count_empty(Scope::Stream); - let music_video = if !music_video_empty { - match &media_collection { - MediaCollection::MusicVideo(music_video) => music_video.clone(), - _ => panic!(), - } - } else { - MusicVideo::default() - }; - let mut stream = if !stream_empty { - match &media_collection { - MediaCollection::MusicVideo(music_video) => music_video.streams().await?, - _ => panic!(), - } - } else { - Stream::default() - }; + let music_video = must_match_if_true!(!music_video_empty => media_collection|MediaCollection::MusicVideo(music_video) => music_video.clone()).unwrap_or_default(); + let stream = must_match_if_true!(!stream_empty => media_collection|MediaCollection::MusicVideo(music_video) => music_video.streams().await?).unwrap_or_default(); - let mut output = vec![]; let music_video_map = self.serializable_to_json_map(FormatMusicVideo::from(&music_video)); let stream_map = self.serializable_to_json_map(FormatStream::from(&stream)); - if stream.subtitles.is_empty() { - if !self.check_pattern_count_empty(Scope::Subtitle) { - return Ok("".to_string()); - } - stream - .subtitles - .insert(Locale::Custom("".to_string()), Subtitle::default()); - } - for subtitle in self - .filter_options - .filter_subtitles(stream.subtitles.into_values().collect()) - { - let subtitle_map = self.serializable_to_json_map(FormatSubtitle::from(&subtitle)); - let replace_map = HashMap::from([ - (Scope::MusicVideo, &music_video_map), - (Scope::Stream, &stream_map), - (Scope::Subtitle, &subtitle_map), - ]); - output.push(self.replace(replace_map)) - } - Ok(output.join("\n")) + let output = self + .replace_all( + HashMap::from([ + (Scope::MusicVideo, &music_video_map), + (Scope::Stream, &stream_map), + ]), + stream, + ) + .unwrap_or_default(); + Ok(output) } async fn parse_concert(&self, media_collection: MediaCollection) -> Result { let concert_empty = self.check_pattern_count_empty(Scope::Concert); let stream_empty = self.check_pattern_count_empty(Scope::Stream); - let concert = if !concert_empty { - match &media_collection { - MediaCollection::Concert(concert) => concert.clone(), - _ => panic!(), - } - } else { - Concert::default() - }; - let mut stream = if !stream_empty { - match &media_collection { - MediaCollection::Concert(concert) => concert.streams().await?, - _ => panic!(), - } - } else { - Stream::default() - }; + let concert = must_match_if_true!(!concert_empty => media_collection|MediaCollection::Concert(concert) => concert.clone()).unwrap_or_default(); + let stream = must_match_if_true!(!stream_empty => media_collection|MediaCollection::Concert(concert) => concert.streams().await?).unwrap_or_default(); - let mut output = vec![]; let concert_map = self.serializable_to_json_map(FormatConcert::from(&concert)); let stream_map = self.serializable_to_json_map(FormatStream::from(&stream)); + + let output = self + .replace_all( + HashMap::from([(Scope::Concert, &concert_map), (Scope::Stream, &stream_map)]), + stream, + ) + .unwrap_or_default(); + Ok(output) + } + + fn serializable_to_json_map(&self, s: S) -> Map { + serde_json::from_value(serde_json::to_value(s).unwrap()).unwrap() + } + + fn replace_all( + &self, + values: HashMap>, + mut stream: Stream, + ) -> Option { if stream.subtitles.is_empty() { if !self.check_pattern_count_empty(Scope::Subtitle) { - return Ok("".to_string()); + return None; } stream .subtitles .insert(Locale::Custom("".to_string()), Subtitle::default()); } - for subtitle in self + let subtitles = self .filter_options - .filter_subtitles(stream.subtitles.into_values().collect()) - { + .filter_subtitles(stream.subtitles.into_values().collect()); + + let mut output = vec![]; + for subtitle in subtitles { let subtitle_map = self.serializable_to_json_map(FormatSubtitle::from(&subtitle)); - let replace_map = HashMap::from([ - (Scope::MusicVideo, &concert_map), - (Scope::Stream, &stream_map), - (Scope::Subtitle, &subtitle_map), - ]); - output.push(self.replace(replace_map)) + let mut tmp_values = values.clone(); + tmp_values.insert(Scope::Subtitle, &subtitle_map); + output.push(self.replace(tmp_values)) } - Ok(output.join("\n")) - } - - fn serializable_to_json_map(&self, s: S) -> Map { - serde_json::from_value(serde_json::to_value(s).unwrap()).unwrap() + Some(output.join("\n")) } fn replace(&self, values: HashMap>) -> String { From 26ca3ca65c70edf0ea024113ac3b7f361e3be755 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 19 Jun 2023 17:25:57 +0200 Subject: [PATCH 026/272] Remove usage of deprecated functions --- crunchy-cli-core/src/utils/format.rs | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index 2f546df..ca7df94 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -5,7 +5,7 @@ use anyhow::Result; use chrono::Duration; use crunchyroll_rs::media::{Resolution, Stream, Subtitle, VariantData}; use crunchyroll_rs::{Concert, Episode, Locale, MediaCollection, Movie, MusicVideo}; -use log::{debug, info, warn}; +use log::{debug, info}; use std::cmp::Ordering; use std::collections::BTreeMap; use std::path::{Path, PathBuf}; @@ -126,24 +126,8 @@ impl SingleFormat { pub async fn stream(&self) -> Result { let stream = match &self.source { - MediaCollection::Episode(e) => { - if let Ok(stream) = e.legacy_streams().await { - stream - } else { - let stream = e.streams().await?; - warn!("Failed to get stream via legacy endpoint"); - stream - } - } - MediaCollection::Movie(m) => { - if let Ok(stream) = m.legacy_streams().await { - stream - } else { - let stream = m.streams().await?; - warn!("Failed to get stream via legacy endpoint"); - stream - } - } + MediaCollection::Episode(e) => e.streams().await?, + MediaCollection::Movie(m) => m.streams().await?, MediaCollection::MusicVideo(mv) => mv.streams().await?, MediaCollection::Concert(c) => c.streams().await?, _ => unreachable!(), From 0b044ba27e3012370f5ecfc5954e99e41b0af066 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 19 Jun 2023 17:45:54 +0200 Subject: [PATCH 027/272] Check search scopes before replacing --- crunchy-cli-core/src/search/format.rs | 66 +++++++++++++++++++++------ 1 file changed, 51 insertions(+), 15 deletions(-) diff --git a/crunchy-cli-core/src/search/format.rs b/crunchy-cli-core/src/search/format.rs index 195b82b..6273895 100644 --- a/crunchy-cli-core/src/search/format.rs +++ b/crunchy-cli-core/src/search/format.rs @@ -165,7 +165,7 @@ impl From<&Subtitle> for FormatSubtitle { } } -#[derive(Clone, Eq, PartialEq, Hash)] +#[derive(Clone, Debug, Eq, PartialEq, Hash)] enum Scope { Series, Season, @@ -192,13 +192,11 @@ macro_rules! must_match_if_true { } macro_rules! self_and_versions { - ($var:expr => $audio:expr) => { - { - let mut items = vec![$var.clone()]; - items.extend($var.clone().version($audio).await?); - items - } - }; + ($var:expr => $audio:expr) => {{ + let mut items = vec![$var.clone()]; + items.extend($var.clone().version($audio).await?); + items + }}; } pub struct Format { @@ -281,20 +279,41 @@ impl Format { }) } - fn check_pattern_count_empty(&self, scope: Scope) -> bool { - self.pattern_count.get(&scope).cloned().unwrap_or_default() == 0 - } - pub async fn parse(&self, media_collection: MediaCollection) -> Result { match &media_collection { MediaCollection::Series(_) | MediaCollection::Season(_) - | MediaCollection::Episode(_) => self.parse_series(media_collection).await, + | MediaCollection::Episode(_) => { + self.check_scopes(vec![ + Scope::Series, + Scope::Season, + Scope::Episode, + Scope::Stream, + Scope::Subtitle, + ])?; + + self.parse_series(media_collection).await + } MediaCollection::MovieListing(_) | MediaCollection::Movie(_) => { + self.check_scopes(vec![ + Scope::MovieListing, + Scope::Movie, + Scope::Stream, + Scope::Subtitle, + ])?; + self.parse_movie_listing(media_collection).await } - MediaCollection::MusicVideo(_) => self.parse_music_video(media_collection).await, - MediaCollection::Concert(_) => self.parse_concert(media_collection).await, + MediaCollection::MusicVideo(_) => { + self.check_scopes(vec![Scope::MusicVideo, Scope::Stream, Scope::Subtitle])?; + + self.parse_music_video(media_collection).await + } + MediaCollection::Concert(_) => { + self.check_scopes(vec![Scope::Concert, Scope::Stream, Scope::Subtitle])?; + + self.parse_concert(media_collection).await + } } } @@ -520,6 +539,23 @@ impl Format { serde_json::from_value(serde_json::to_value(s).unwrap()).unwrap() } + fn check_pattern_count_empty(&self, scope: Scope) -> bool { + self.pattern_count.get(&scope).cloned().unwrap_or_default() == 0 + } + + fn check_scopes(&self, available_scopes: Vec) -> Result<()> { + for (_, scope, field) in self.pattern.iter() { + if !available_scopes.contains(scope) { + bail!( + "'{}.{}' is not a valid keyword", + format!("{:?}", scope).to_lowercase(), + field + ) + } + } + Ok(()) + } + fn replace_all( &self, values: HashMap>, From 4e4a4355f55a27f94827bfc93d6c8ac9ac2ecae1 Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 20 Jun 2023 00:06:09 +0200 Subject: [PATCH 028/272] Add more search replace fields --- crunchy-cli-core/src/search/command.rs | 25 ++++++++++++++++-- crunchy-cli-core/src/search/format.rs | 36 ++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/crunchy-cli-core/src/search/command.rs b/crunchy-cli-core/src/search/command.rs index 442dea5..ac82d8c 100644 --- a/crunchy-cli-core/src/search/command.rs +++ b/crunchy-cli-core/src/search/command.rs @@ -10,7 +10,10 @@ use crunchyroll_rs::{Episode, Locale, MediaCollection, MovieListing, MusicVideo, #[derive(Debug, clap::Parser)] pub struct Search { - #[arg(help = "Audio languages to include")] + #[arg(help = format!("Audio languages to include. \ + Available languages are: {}", Locale::all().into_iter().map(|l| l.to_string()).collect::>().join(", ")))] + #[arg(long_help = format!("Audio languages to include. \ + Available languages are:\n {}", Locale::all().into_iter().map(|l| format!("{:<6} → {}", l.to_string(), l.to_human_readable())).collect::>().join("\n ")))] #[arg(long, default_values_t = vec![crate::utils::locale::system_locale()])] audio: Vec, @@ -41,37 +44,55 @@ pub struct Search { /// For example, if you want to get the title of an episode, you can use `Title {{episode.title}}` and `{{episode.title}}` will be replaced with the episode title /// /// See the following list for all keywords and their meaning: + /// series.id → Series id /// series.title → Series title /// series.description → Series description + /// series.release_year → Series release year /// + /// season.id → Season id /// season.title → Season title /// season.description → Season description /// season.number → Season number + /// season.episodes → Number of episodes the season has /// + /// episode.id → Episode id /// episode.title → Episode title /// episode.description → Episode description /// episode.locale → Episode locale/language /// episode.number → Episode number /// episode.sequence_number → Episode number. This number is unique unlike `episode.number` which sometimes can be duplicated + /// episode.duration → Episode duration in milliseconds + /// episode.air_date → Episode air date as unix timestamp + /// episode.premium_only → If the episode is only available with Crunchyroll premium /// + /// movie_listing.id → Movie listing id /// movie_listing.title → Movie listing title /// movie_listing.description → Movie listing description /// + /// movie.id → Movie id /// movie.title → Movie title /// movie.description → Movie description + /// movie.duration → Movie duration in milliseconds + /// movie.premium_only → If the movie is only available with Crunchyroll premium /// + /// music_video.id → Music video id /// music_video.title → Music video title /// music_video.description → Music video description + /// music_video.duration → Music video duration in milliseconds + /// music_video.premium_only → If the music video is only available with Crunchyroll premium /// + /// concert.id → Concert id /// concert.title → Concert title /// concert.description → Concert description + /// concert.duration → Concert duration in milliseconds + /// concert.premium_only → If the concert is only available with Crunchyroll premium /// /// stream.locale → Stream locale/language /// stream.dash_url → Stream url in DASH format /// stream.hls_url → Stream url in HLS format /// /// subtitle.locale → Subtitle locale/language - /// subtitle.url → Subtitle url + /// subtitle.url → Url to the subtitle #[arg(short, long, verbatim_doc_comment)] #[arg(default_value = "S{{season.number}}E{{episode.number}} - {{episode.title}}")] output: String, diff --git a/crunchy-cli-core/src/search/format.rs b/crunchy-cli-core/src/search/format.rs index 6273895..cfdba3a 100644 --- a/crunchy-cli-core/src/search/format.rs +++ b/crunchy-cli-core/src/search/format.rs @@ -12,59 +12,76 @@ use std::ops::Range; #[derive(Default, Serialize)] struct FormatSeries { + pub id: String, pub title: String, pub description: String, + pub release_year: u32, } impl From<&Series> for FormatSeries { fn from(value: &Series) -> Self { Self { + id: value.id.clone(), title: value.title.clone(), description: value.description.clone(), + release_year: value.series_launch_year.unwrap_or_default(), } } } #[derive(Default, Serialize)] struct FormatSeason { + pub id: String, pub title: String, pub description: String, pub number: u32, + pub episodes: u32, } impl From<&Season> for FormatSeason { fn from(value: &Season) -> Self { Self { + id: value.id.clone(), title: value.title.clone(), description: value.description.clone(), number: value.season_number, + episodes: value.number_of_episodes, } } } #[derive(Default, Serialize)] struct FormatEpisode { + pub id: String, pub title: String, pub description: String, pub locale: Locale, pub number: u32, pub sequence_number: f32, + pub duration: i64, + pub air_date: i64, + pub premium_only: bool, } impl From<&Episode> for FormatEpisode { fn from(value: &Episode) -> Self { Self { + id: value.id.clone(), title: value.title.clone(), description: value.description.clone(), locale: value.audio_locale.clone(), number: value.episode_number, sequence_number: value.sequence_number, + duration: value.duration.num_milliseconds(), + air_date: value.episode_air_date.timestamp(), + premium_only: value.is_premium_only, } } } #[derive(Default, Serialize)] struct FormatMovieListing { + pub id: String, pub title: String, pub description: String, } @@ -72,6 +89,7 @@ struct FormatMovieListing { impl From<&MovieListing> for FormatMovieListing { fn from(value: &MovieListing) -> Self { Self { + id: value.id.clone(), title: value.title.clone(), description: value.description.clone(), } @@ -80,45 +98,63 @@ impl From<&MovieListing> for FormatMovieListing { #[derive(Default, Serialize)] struct FormatMovie { + pub id: String, pub title: String, pub description: String, + pub duration: i64, + pub premium_only: bool, } impl From<&Movie> for FormatMovie { fn from(value: &Movie) -> Self { Self { + id: value.id.clone(), title: value.title.clone(), description: value.description.clone(), + duration: value.duration.num_milliseconds(), + premium_only: value.is_premium_only, } } } #[derive(Default, Serialize)] struct FormatMusicVideo { + pub id: String, pub title: String, pub description: String, + pub duration: i64, + pub premium_only: bool, } impl From<&MusicVideo> for FormatMusicVideo { fn from(value: &MusicVideo) -> Self { Self { + id: value.id.clone(), title: value.title.clone(), description: value.description.clone(), + duration: value.duration.num_milliseconds(), + premium_only: value.is_premium_only, } } } #[derive(Default, Serialize)] struct FormatConcert { + pub id: String, pub title: String, pub description: String, + pub duration: i64, + pub premium_only: bool, } impl From<&Concert> for FormatConcert { fn from(value: &Concert) -> Self { Self { + id: value.id.clone(), title: value.title.clone(), description: value.description.clone(), + duration: value.duration.num_milliseconds(), + premium_only: value.is_premium_only, } } } From 0cd647fb14ec48da1cab70122770c53b527b50b7 Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 20 Jun 2023 00:09:35 +0200 Subject: [PATCH 029/272] Add search documentation --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index a3cbc9a..44756e7 100644 --- a/README.md +++ b/README.md @@ -242,6 +242,31 @@ $ crunchy archive -o "[S{season_number}E{episode_number}] {title}.mkv" https://w # Output file: '[S01E01] Secret of the Dragon Ball.mkv' ``` +### Search + +**Supported urls/input** +- Single episode (with [episode filtering](#episode-filtering)) + ```shell + $ crunchy search https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome + ``` +- Series (with [episode filtering](#episode-filtering)) + ```shell + $ crunchy search https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + ``` +- Search input + ```shell + $ crunchy search "darling in the franxx" + ``` + +**Options** +- Audio + + Set the audio language to search via the `--audio` flag. Can be used multiple times. + ```shell + $ crunchy search --audio en-US https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + ``` + Default is your system locale. + ### Episode filtering Filters patterns can be used to download a specific range of episodes from a single series. From f7af9835263457ff5e69611fe2a1a597fbb0fb82 Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 20 Jun 2023 00:19:59 +0200 Subject: [PATCH 030/272] Remove search --filter-subtitles flag --- crunchy-cli-core/src/search/command.rs | 5 ----- crunchy-cli-core/src/search/filter.rs | 9 --------- crunchy-cli-core/src/search/format.rs | 5 +---- 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/crunchy-cli-core/src/search/command.rs b/crunchy-cli-core/src/search/command.rs index ac82d8c..e81ef8d 100644 --- a/crunchy-cli-core/src/search/command.rs +++ b/crunchy-cli-core/src/search/command.rs @@ -17,10 +17,6 @@ pub struct Search { #[arg(long, default_values_t = vec![crate::utils::locale::system_locale()])] audio: Vec, - #[arg(help = "Filter the locale/language of subtitles according to the value of `--audio`")] - #[arg(long, default_value_t = false)] - filter_subtitles: bool, - #[arg(help = "Limit of search top search results")] #[arg(long, default_value_t = 5)] search_top_results_limit: u32, @@ -144,7 +140,6 @@ impl Execute for Search { for (media_collection, url_filter) in input { let filter_options = FilterOptions { audio: self.audio.clone(), - filter_subtitles: self.filter_subtitles, url_filter, }; diff --git a/crunchy-cli-core/src/search/filter.rs b/crunchy-cli-core/src/search/filter.rs index 6a8e4ee..0b31823 100644 --- a/crunchy-cli-core/src/search/filter.rs +++ b/crunchy-cli-core/src/search/filter.rs @@ -1,10 +1,8 @@ use crate::utils::parse::UrlFilter; -use crunchyroll_rs::media::Subtitle; use crunchyroll_rs::{Episode, Locale, MovieListing, Season, Series}; pub struct FilterOptions { pub audio: Vec, - pub filter_subtitles: bool, pub url_filter: UrlFilter, } @@ -40,13 +38,6 @@ impl FilterOptions { ) } - pub fn filter_subtitles(&self, mut subtitles: Vec) -> Vec { - if self.filter_subtitles { - subtitles.retain(|s| self.check_audio_language(&vec![s.locale.clone()])) - } - subtitles - } - fn check_audio_language(&self, audio: &Vec) -> bool { if !self.audio.is_empty() { return self.audio.iter().any(|a| audio.contains(a)); diff --git a/crunchy-cli-core/src/search/format.rs b/crunchy-cli-core/src/search/format.rs index cfdba3a..6769c4c 100644 --- a/crunchy-cli-core/src/search/format.rs +++ b/crunchy-cli-core/src/search/format.rs @@ -605,12 +605,9 @@ impl Format { .subtitles .insert(Locale::Custom("".to_string()), Subtitle::default()); } - let subtitles = self - .filter_options - .filter_subtitles(stream.subtitles.into_values().collect()); let mut output = vec![]; - for subtitle in subtitles { + for (_, subtitle) in stream.subtitles { let subtitle_map = self.serializable_to_json_map(FormatSubtitle::from(&subtitle)); let mut tmp_values = values.clone(); tmp_values.insert(Scope::Subtitle, &subtitle_map); From 2ebc76a0dfe952ae7e5828a5a30d1f46ccfb79a2 Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 20 Jun 2023 00:33:31 +0200 Subject: [PATCH 031/272] Change search README documentation position --- README.md | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 44756e7..ca87732 100644 --- a/README.md +++ b/README.md @@ -219,28 +219,6 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any $ crunchy archive --default-subtitle en-US https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` Default is none. - -### Output Template Options - -You can use various template options to change how the filename is processed. The following tags are available: - -- `{title}` → Title of the video -- `{series_name}` → Name of the series -- `{season_name}` → Name of the season -- `{audio}` → Audio language of the video -- `{resolution}` → Resolution of the video -- `{season_number}` → Number of the season -- `{episode_number}` → Number of the episode -- `{relative_episode_number}` → Number of the episode relative to its season -- `{series_id}` → ID of the series -- `{season_id}` → ID of the season -- `{episode_id}` → ID of the episode - -Example: -```shell -$ crunchy archive -o "[S{season_number}E{episode_number}] {title}.mkv" https://www.crunchyroll.com/series/G8DHV7W21/dragon-ball -# Output file: '[S01E01] Secret of the Dragon Ball.mkv' -``` ### Search @@ -267,6 +245,28 @@ $ crunchy archive -o "[S{season_number}E{episode_number}] {title}.mkv" https://w ``` Default is your system locale. +### Output Template Options + +You can use various template options to change how the filename is processed. The following tags are available: + +- `{title}` → Title of the video +- `{series_name}` → Name of the series +- `{season_name}` → Name of the season +- `{audio}` → Audio language of the video +- `{resolution}` → Resolution of the video +- `{season_number}` → Number of the season +- `{episode_number}` → Number of the episode +- `{relative_episode_number}` → Number of the episode relative to its season +- `{series_id}` → ID of the series +- `{season_id}` → ID of the season +- `{episode_id}` → ID of the episode + +Example: +```shell +$ crunchy archive -o "[S{season_number}E{episode_number}] {title}.mkv" https://www.crunchyroll.com/series/G8DHV7W21/dragon-ball +# Output file: '[S01E01] Secret of the Dragon Ball.mkv' +``` + ### Episode filtering Filters patterns can be used to download a specific range of episodes from a single series. From 0ef4980ab3a529d11da0add7180f94d1f4c5d6dc Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 20 Jun 2023 00:35:37 +0200 Subject: [PATCH 032/272] Update dependencies and version --- Cargo.lock | 119 ++++++++++++++++++------------------ Cargo.toml | 2 +- crunchy-cli-core/Cargo.lock | 82 ++++++++++++++----------- crunchy-cli-core/Cargo.toml | 8 +-- 4 files changed, 111 insertions(+), 100 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5fde41d..4a77d79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aes" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" dependencies = [ "cfg-if", "cipher", @@ -201,9 +201,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.2" +version = "4.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "401a4694d2bf92537b6867d94de48c4842089645fdcdf6c71865b175d836e9c2" +checksum = "80672091db20273a15cf9fdd4e47ed43b5091ec9841bf4c6145c9dfbbcae09ed" dependencies = [ "clap_builder", "clap_derive", @@ -212,9 +212,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.1" +version = "4.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72394f3339a76daf211e57d4bcb374410f3965dcc606dd0e03738c7888766980" +checksum = "c1458a1df40e1e2afebb7ab60ce55c1fa8f431146205aa5f4887e0b111c27636" dependencies = [ "anstream", "anstyle", @@ -286,23 +286,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.21", + "time 0.3.22", "version_check", ] [[package]] name = "cookie_store" -version = "0.16.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e4b6aa369f41f5faa04bb80c9b1f4216ea81646ed6124d76ba5c49a7aafd9cd" +checksum = "d606d0fba62e13cf04db20536c05cb7f13673c161cb47a47a82b9b9e7d3f1daa" dependencies = [ "cookie", "idna 0.2.3", "log", "publicsuffix", "serde", + "serde_derive", "serde_json", - "time 0.3.21", + "time 0.3.22", "url", ] @@ -324,16 +325,16 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" dependencies = [ "libc", ] [[package]] name = "crunchy-cli" -version = "3.0.0-dev.13" +version = "3.0.0-dev.14" dependencies = [ "chrono", "clap", @@ -345,7 +346,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.0.0-dev.13" +version = "3.0.0-dev.14" dependencies = [ "anyhow", "async-trait", @@ -468,9 +469,9 @@ dependencies = [ [[package]] name = "dash-mpd" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306d758462ad461116dfd0680c824691449974c6ab697464a3ccdad925dde7c0" +checksum = "8b97b7a11cc6dcf0c803554cbd7f7d8dfef99c598e6a310403bb5699d9a94076" dependencies = [ "base64", "base64-serde", @@ -825,9 +826,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.56" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -972,9 +973,9 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "js-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -999,9 +1000,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "log" -version = "0.4.18" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "m3u8-rs" @@ -1201,9 +1202,9 @@ checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794" [[package]] name = "proc-macro2" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ "unicode-ident", ] @@ -1357,9 +1358,9 @@ checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" [[package]] name = "rustix" -version = "0.37.19" +version = "0.37.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" dependencies = [ "bitflags", "errno", @@ -1371,9 +1372,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.1" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e" +checksum = "e32ca28af694bc1bbf399c33a516dbdf1c90090b8ab23c2bc24f834aa2247f5f" dependencies = [ "log", "ring", @@ -1460,18 +1461,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.163" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.163" +version = "1.0.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" +checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", @@ -1480,9 +1481,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.96" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" dependencies = [ "itoa", "ryu", @@ -1523,7 +1524,7 @@ dependencies = [ "serde", "serde_json", "serde_with_macros", - "time 0.3.21", + "time 0.3.22", ] [[package]] @@ -1615,15 +1616,16 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.5.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" dependencies = [ + "autocfg", "cfg-if", "fastrand", "redox_syscall 0.3.5", "rustix", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -1669,9 +1671,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.21" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" +checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" dependencies = [ "itoa", "serde", @@ -1749,9 +1751,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0d409377ff5b1e3ca6437aa86c1eb7d40c134bfec254e44c830defa92669db5" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ "rustls", "tokio", @@ -1885,11 +1887,10 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -1907,9 +1908,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1917,9 +1918,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", @@ -1932,9 +1933,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.36" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ "cfg-if", "js-sys", @@ -1944,9 +1945,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1954,9 +1955,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", @@ -1967,15 +1968,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "web-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/Cargo.toml b/Cargo.toml index 4273955..beddc9e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.0.0-dev.13" +version = "3.0.0-dev.14" edition = "2021" [dependencies] diff --git a/crunchy-cli-core/Cargo.lock b/crunchy-cli-core/Cargo.lock index c5b7300..e794609 100644 --- a/crunchy-cli-core/Cargo.lock +++ b/crunchy-cli-core/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "aes" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" dependencies = [ "cfg-if", "cipher", @@ -201,9 +201,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.3" +version = "4.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8f255e4b8027970e78db75e78831229c9815fdbfa67eb1a1b777a62e24b4a0" +checksum = "80672091db20273a15cf9fdd4e47ed43b5091ec9841bf4c6145c9dfbbcae09ed" dependencies = [ "clap_builder", "clap_derive", @@ -212,9 +212,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.3" +version = "4.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd4f3c17c83b0ba34ffbc4f8bbd74f079413f747f84a6f89292f138057e36ab" +checksum = "c1458a1df40e1e2afebb7ab60ce55c1fa8f431146205aa5f4887e0b111c27636" dependencies = [ "anstream", "anstyle", @@ -273,15 +273,16 @@ dependencies = [ [[package]] name = "cookie_store" -version = "0.16.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e4b6aa369f41f5faa04bb80c9b1f4216ea81646ed6124d76ba5c49a7aafd9cd" +checksum = "d606d0fba62e13cf04db20536c05cb7f13673c161cb47a47a82b9b9e7d3f1daa" dependencies = [ "cookie", "idna 0.2.3", "log", "publicsuffix", "serde", + "serde_derive", "serde_json", "time 0.3.22", "url", @@ -305,16 +306,16 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" dependencies = [ "libc", ] [[package]] name = "crunchy-cli-core" -version = "3.0.0-dev.13" +version = "3.0.0-dev.14" dependencies = [ "anyhow", "async-trait", @@ -334,6 +335,7 @@ dependencies = [ "sanitize-filename", "serde", "serde_json", + "serde_plain", "shlex", "sys-locale", "tempfile", @@ -940,9 +942,9 @@ checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "js-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -1319,9 +1321,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.19" +version = "0.37.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" dependencies = [ "bitflags", "errno", @@ -1333,9 +1335,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.1" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e" +checksum = "e32ca28af694bc1bbf399c33a516dbdf1c90090b8ab23c2bc24f834aa2247f5f" dependencies = [ "log", "ring", @@ -1442,15 +1444,24 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.96" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" dependencies = [ "itoa", "ryu", "serde", ] +[[package]] +name = "serde_plain" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6018081315db179d0ce57b1fe4b62a12a0028c9cf9bbef868c9cf477b3c34ae" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1839,11 +1850,10 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -1861,9 +1871,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1871,9 +1881,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", @@ -1886,9 +1896,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.36" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d1985d03709c53167ce907ff394f5316aa22cb4e12761295c5dc57dacb6297e" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ "cfg-if", "js-sys", @@ -1898,9 +1908,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1908,9 +1918,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", @@ -1921,15 +1931,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "web-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 5cadd08..10b69fe 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -1,16 +1,16 @@ [package] name = "crunchy-cli-core" authors = ["Crunchy Labs Maintainers"] -version = "3.0.0-dev.13" +version = "3.0.0-dev.14" edition = "2021" [dependencies] anyhow = "1.0" async-trait = "0.1" -clap = { version = "4.2", features = ["derive", "string"] } +clap = { version = "4.3", features = ["derive", "string"] } chrono = "0.4" crunchyroll-rs = { version = "0.3.6", features = ["dash-stream"] } -ctrlc = "3.2" +ctrlc = "3.4" dirs = "5.0" derive_setters = "0.1" fs2 = "0.4" @@ -25,7 +25,7 @@ serde = "1.0" serde_json = "1.0" serde_plain = "1.0" shlex = "1.1" -tempfile = "3.5" +tempfile = "3.6" terminal_size = "0.2" tokio = { version = "1.28", features = ["macros", "rt-multi-thread", "time"] } sys-locale = "0.3" From 5b8a4b9969715ae4b60121300aea354ac13deec5 Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 20 Jun 2023 00:53:12 +0200 Subject: [PATCH 033/272] Add simple search command description --- crunchy-cli-core/src/archive/command.rs | 1 - crunchy-cli-core/src/search/command.rs | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 9af14fb..bb2f30d 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -22,7 +22,6 @@ use std::path::PathBuf; #[derive(Clone, Debug, clap::Parser)] #[clap(about = "Archive a video")] #[command(arg_required_else_help(true))] -#[command()] pub struct Archive { #[arg(help = format!("Audio languages. Can be used multiple times. \ Available languages are: {}", Locale::all().into_iter().map(|l| l.to_string()).collect::>().join(", ")))] diff --git a/crunchy-cli-core/src/search/command.rs b/crunchy-cli-core/src/search/command.rs index e81ef8d..0159c05 100644 --- a/crunchy-cli-core/src/search/command.rs +++ b/crunchy-cli-core/src/search/command.rs @@ -9,6 +9,8 @@ use crunchyroll_rs::search::QueryResults; use crunchyroll_rs::{Episode, Locale, MediaCollection, MovieListing, MusicVideo, Series}; #[derive(Debug, clap::Parser)] +#[clap(about = "Search in videos")] +#[command(arg_required_else_help(true))] pub struct Search { #[arg(help = format!("Audio languages to include. \ Available languages are: {}", Locale::all().into_iter().map(|l| l.to_string()).collect::>().join(", ")))] From f4682e0f290406cb938b3db8f355396dfb9c3bd8 Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 20 Jun 2023 00:53:19 +0200 Subject: [PATCH 034/272] Add search command to man pages --- build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/build.rs b/build.rs index 1e4d71f..7056c67 100644 --- a/build.rs +++ b/build.rs @@ -100,6 +100,7 @@ fn generate_manpages(out_dir: PathBuf) -> std::io::Result<()> { generate_command_manpage(crunchy_cli_core::Archive::command(), &out_dir, "archive")?; generate_command_manpage(crunchy_cli_core::Download::command(), &out_dir, "download")?; generate_command_manpage(crunchy_cli_core::Login::command(), &out_dir, "login")?; + generate_command_manpage(crunchy_cli_core::Search::command(), &out_dir, "search")?; Ok(()) } From d75c04fbb6c93d0ed6dd4ea85f383b774e956532 Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 23 Jun 2023 15:28:09 +0200 Subject: [PATCH 035/272] Download all seasons if season number is duplicated --- crunchy-cli-core/src/archive/filter.rs | 20 +++++++-- crunchy-cli-core/src/utils/format.rs | 58 ++++++++++++++++++++------ 2 files changed, 61 insertions(+), 17 deletions(-) diff --git a/crunchy-cli-core/src/archive/filter.rs b/crunchy-cli-core/src/archive/filter.rs index 514b540..b181ae6 100644 --- a/crunchy-cli-core/src/archive/filter.rs +++ b/crunchy-cli-core/src/archive/filter.rs @@ -18,6 +18,7 @@ pub(crate) struct ArchiveFilter { archive: Archive, season_episode_count: HashMap>, season_subtitles_missing: Vec, + season_sorting: Vec, visited: Visited, } @@ -28,6 +29,7 @@ impl ArchiveFilter { archive, season_episode_count: HashMap::new(), season_subtitles_missing: vec![], + season_sorting: vec![], visited: Visited::None, } } @@ -129,6 +131,7 @@ impl Filter for ArchiveFilter { let mut episodes = vec![]; for season in seasons { + self.season_sorting.push(season.id.clone()); let season_locale = season .audio_locales .get(0) @@ -296,15 +299,24 @@ impl Filter for ArchiveFilter { let mut single_format_collection = SingleFormatCollection::new(); - let mut sorted: BTreeMap<(u32, String), Self::T> = BTreeMap::new(); + let mut pre_sorted: BTreeMap<(String, String), Self::T> = BTreeMap::new(); for data in flatten_input { - sorted - .entry((data.season_number, data.sequence_number.to_string())) + pre_sorted + .entry((data.season_id.clone(), data.sequence_number.to_string())) .or_insert(vec![]) .push(data) } - for data in sorted.into_values() { + let mut sorted: Vec<((String, String), Self::T)> = pre_sorted.into_iter().collect(); + sorted.sort_by(|((a, _), _), ((b, _), _)| { + self.season_sorting + .iter() + .position(|p| p == a) + .unwrap() + .cmp(&self.season_sorting.iter().position(|p| p == b).unwrap()) + }); + + for (_, data) in sorted { single_format_collection.add_single_formats(data) } diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index ca7df94..c67386d 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -173,8 +173,42 @@ impl PartialEq for SingleFormatCollectionEpisodeKey { } impl Eq for SingleFormatCollectionEpisodeKey {} +struct SingleFormatCollectionSeasonKey((u32, String)); + +impl PartialOrd for SingleFormatCollectionSeasonKey { + fn partial_cmp(&self, other: &Self) -> Option { + let mut cmp = self.0 .0.partial_cmp(&other.0 .0); + if let Some(ordering) = cmp { + if matches!(ordering, Ordering::Equal) && self.0 .1 != other.0 .1 { + // first come first serve + cmp = Some(Ordering::Greater) + } + } + cmp + } +} +impl Ord for SingleFormatCollectionSeasonKey { + fn cmp(&self, other: &Self) -> Ordering { + let mut cmp = self.0 .0.cmp(&other.0 .0); + if matches!(cmp, Ordering::Equal) && self.0 .1 != other.0 .1 { + // first come first serve + cmp = Ordering::Greater + } + cmp + } +} +impl PartialEq for SingleFormatCollectionSeasonKey { + fn eq(&self, other: &Self) -> bool { + self.0.eq(&other.0) + } +} +impl Eq for SingleFormatCollectionSeasonKey {} + pub struct SingleFormatCollection( - BTreeMap>>, + BTreeMap< + SingleFormatCollectionSeasonKey, + BTreeMap>, + >, ); impl SingleFormatCollection { @@ -189,7 +223,10 @@ impl SingleFormatCollection { pub fn add_single_formats(&mut self, single_formats: Vec) { let format = single_formats.first().unwrap(); self.0 - .entry(format.season_number) + .entry(SingleFormatCollectionSeasonKey(( + format.season_number, + format.season_id.clone(), + ))) .or_insert(BTreeMap::new()) .insert( SingleFormatCollectionEpisodeKey(format.sequence_number), @@ -199,18 +236,13 @@ impl SingleFormatCollection { pub fn full_visual_output(&self) { debug!("Series has {} seasons", self.0.len()); - for (season_number, episodes) in &self.0 { + for (season_key, episodes) in &self.0 { + let first_episode = episodes.first_key_value().unwrap().1.first().unwrap(); info!( - "{} Season {}", - episodes - .first_key_value() - .unwrap() - .1 - .first() - .unwrap() - .series_name - .clone(), - season_number + "{} Season {} ({})", + first_episode.series_name.clone(), + season_key.0 .0, + first_episode.season_title.clone(), ); for (i, (_, formats)) in episodes.iter().enumerate() { let format = formats.first().unwrap(); From fc44b8af8a08df8a87fcac08fc8ccf07c59468e9 Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 23 Jun 2023 17:19:16 +0200 Subject: [PATCH 036/272] Add option to select seasons when season number is duplicated (#199) --- Cargo.lock | 28 +++--- crunchy-cli-core/Cargo.toml | 2 +- crunchy-cli-core/src/archive/command.rs | 6 +- crunchy-cli-core/src/archive/filter.rs | 46 +++++++++- crunchy-cli-core/src/download/command.rs | 6 +- crunchy-cli-core/src/download/filter.rs | 90 ++++++++++++------- crunchy-cli-core/src/lib.rs | 4 + .../src/utils/interactive_select.rs | 73 +++++++++++++++ crunchy-cli-core/src/utils/log.rs | 23 ++++- crunchy-cli-core/src/utils/mod.rs | 1 + 10 files changed, 227 insertions(+), 52 deletions(-) create mode 100644 crunchy-cli-core/src/utils/interactive_select.rs diff --git a/Cargo.lock b/Cargo.lock index 4a77d79..dedc0ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -355,6 +355,7 @@ dependencies = [ "crunchyroll-rs", "ctrlc", "derive_setters", + "dialoguer", "dirs", "fs2", "indicatif", @@ -370,7 +371,6 @@ dependencies = [ "shlex", "sys-locale", "tempfile", - "terminal_size", "tokio", ] @@ -501,6 +501,16 @@ dependencies = [ "syn", ] +[[package]] +name = "dialoguer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59c6f2989294b9a498d3ad5491a79c6deb604617378e1cdc4bfc1c1361fe2f87" +dependencies = [ + "console", + "shell-words", +] + [[package]] name = "dirs" version = "5.0.1" @@ -1539,6 +1549,12 @@ dependencies = [ "syn", ] +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + [[package]] name = "shlex" version = "1.1.0" @@ -1628,16 +1644,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "terminal_size" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" -dependencies = [ - "rustix", - "windows-sys 0.48.0", -] - [[package]] name = "thiserror" version = "1.0.40" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 10b69fe..cf2b7c3 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -11,6 +11,7 @@ clap = { version = "4.3", features = ["derive", "string"] } chrono = "0.4" crunchyroll-rs = { version = "0.3.6", features = ["dash-stream"] } ctrlc = "3.4" +dialoguer = { version = "0.10", default-features = false } dirs = "5.0" derive_setters = "0.1" fs2 = "0.4" @@ -26,7 +27,6 @@ serde_json = "1.0" serde_plain = "1.0" shlex = "1.1" tempfile = "3.6" -terminal_size = "0.2" tokio = { version = "1.28", features = ["macros", "rt-multi-thread", "time"] } sys-locale = "0.3" diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index bb2f30d..9a2ee21 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -98,6 +98,10 @@ pub struct Archive { #[arg(long, default_value_t = false)] pub(crate) skip_existing: bool, + #[arg(help = "Skip any interactive input")] + #[arg(short, long, default_value_t = false)] + pub(crate) yes: bool, + #[arg(help = "Crunchyroll series url(s)")] pub(crate) urls: Vec, } @@ -149,7 +153,7 @@ 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 = ArchiveFilter::new(url_filter, self.clone()) + let single_format_collection = ArchiveFilter::new(url_filter, self.clone(), !self.yes) .visit(media_collection) .await?; diff --git a/crunchy-cli-core/src/archive/filter.rs b/crunchy-cli-core/src/archive/filter.rs index b181ae6..d6593e5 100644 --- a/crunchy-cli-core/src/archive/filter.rs +++ b/crunchy-cli-core/src/archive/filter.rs @@ -1,10 +1,11 @@ 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::UrlFilter; use anyhow::Result; use crunchyroll_rs::{Concert, Episode, Locale, Movie, MovieListing, MusicVideo, Season, Series}; -use log::warn; +use log::{info, warn}; use std::collections::{BTreeMap, HashMap}; enum Visited { @@ -16,6 +17,7 @@ enum Visited { pub(crate) struct ArchiveFilter { url_filter: UrlFilter, archive: Archive, + interactive_input: bool, season_episode_count: HashMap>, season_subtitles_missing: Vec, season_sorting: Vec, @@ -23,10 +25,11 @@ pub(crate) struct ArchiveFilter { } impl ArchiveFilter { - pub(crate) fn new(url_filter: UrlFilter, archive: Archive) -> Self { + pub(crate) fn new(url_filter: UrlFilter, archive: Archive, interactive_input: bool) -> Self { Self { url_filter, archive, + interactive_input, season_episode_count: HashMap::new(), season_subtitles_missing: vec![], season_sorting: vec![], @@ -71,7 +74,44 @@ impl Filter for ArchiveFilter { } self.visited = Visited::Series } - Ok(series.seasons().await?) + + 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.len() > 0 { + 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> { diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index 644e4e5..0167f49 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -73,6 +73,10 @@ pub struct Download { #[arg(long, default_value_t = false)] pub(crate) skip_existing: bool, + #[arg(help = "Skip any interactive input")] + #[arg(short, long, default_value_t = false)] + pub(crate) yes: bool, + #[arg(help = "Url(s) to Crunchyroll episodes or series")] pub(crate) urls: Vec, } @@ -119,7 +123,7 @@ impl Execute for Download { for (i, (media_collection, url_filter)) in parsed_urls.into_iter().enumerate() { let progress_handler = progress!("Fetching series details"); - let single_format_collection = DownloadFilter::new(url_filter, self.clone()) + let single_format_collection = DownloadFilter::new(url_filter, self.clone(), !self.yes) .visit(media_collection) .await?; diff --git a/crunchy-cli-core/src/download/filter.rs b/crunchy-cli-core/src/download/filter.rs index f6a4a2e..b04aef8 100644 --- a/crunchy-cli-core/src/download/filter.rs +++ b/crunchy-cli-core/src/download/filter.rs @@ -1,24 +1,27 @@ use crate::download::Download; use crate::utils::filter::Filter; use crate::utils::format::{Format, SingleFormat, SingleFormatCollection}; +use crate::utils::interactive_select::{check_for_duplicated_seasons, get_duplicated_seasons}; use crate::utils::parse::UrlFilter; use anyhow::{bail, Result}; use crunchyroll_rs::{Concert, Episode, Movie, MovieListing, MusicVideo, Season, Series}; -use log::{error, warn}; +use log::{error, info, warn}; use std::collections::HashMap; pub(crate) struct DownloadFilter { url_filter: UrlFilter, download: Download, + interactive_input: bool, season_episode_count: HashMap>, season_subtitles_missing: Vec, } impl DownloadFilter { - pub(crate) fn new(url_filter: UrlFilter, download: Download) -> Self { + pub(crate) fn new(url_filter: UrlFilter, download: Download, interactive_input: bool) -> Self { Self { url_filter, download, + interactive_input, season_episode_count: HashMap::new(), season_subtitles_missing: vec![], } @@ -43,42 +46,61 @@ impl Filter for DownloadFilter { } } - let seasons = series.seasons().await?; + let mut seasons = vec![]; + for mut season in series.seasons().await? { + if !self.url_filter.is_season_valid(season.season_number) { + continue; + } + + if !season + .audio_locales + .iter() + .any(|l| l == &self.download.audio) + { + if season + .available_versions() + .await? + .iter() + .any(|l| l == &self.download.audio) + { + season = season + .version(vec![self.download.audio.clone()]) + .await? + .remove(0) + } else { + error!( + "Season {} - '{}' is not available with {} audio", + season.season_number, + season.title, + self.download.audio.clone(), + ); + continue; + } + } + + seasons.push(season) + } + + let duplicated_seasons = get_duplicated_seasons(&seasons); + if duplicated_seasons.len() > 0 { + 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![]); - } - - if !season - .audio_locales - .iter() - .any(|l| l == &self.download.audio) - { - if season - .available_versions() - .await? - .iter() - .any(|l| l == &self.download.audio) - { - season = season - .version(vec![self.download.audio.clone()]) - .await? - .remove(0) - } else { - error!( - "Season {} - '{}' is not available with {} audio", - season.season_number, - season.title, - self.download.audio.clone(), - ); - return Ok(vec![]); - } - } - + async fn visit_season(&mut self, season: Season) -> Result> { let mut episodes = season.episodes().await?; if Format::has_relative_episodes_fmt(&self.download.output) { diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index 4de5826..7cb68ce 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -18,6 +18,7 @@ mod search; mod utils; pub use archive::Archive; +use dialoguer::console::Term; pub use download::Download; pub use login::Login; pub use search::Search; @@ -168,6 +169,9 @@ pub async fn cli_entrypoint() { } } } + // when pressing ctrl-c while interactively choosing seasons the cursor stays hidden, this + // line shows it again + let _ = Term::stdout().show_cursor(); std::process::exit(1) }) .unwrap(); diff --git a/crunchy-cli-core/src/utils/interactive_select.rs b/crunchy-cli-core/src/utils/interactive_select.rs new file mode 100644 index 0000000..85116e6 --- /dev/null +++ b/crunchy-cli-core/src/utils/interactive_select.rs @@ -0,0 +1,73 @@ +use crate::utils::log::progress_pause; +use crunchyroll_rs::Season; +use dialoguer::console::Term; +use dialoguer::MultiSelect; +use std::collections::BTreeMap; + +pub fn get_duplicated_seasons(seasons: &Vec) -> Vec { + let mut season_number_counter = BTreeMap::::new(); + for season in seasons { + season_number_counter + .entry(season.season_number) + .and_modify(|c| *c += 1) + .or_default(); + } + season_number_counter + .into_iter() + .filter_map(|(k, v)| if v > 0 { Some(k) } else { None }) + .collect() +} + +pub fn check_for_duplicated_seasons(seasons: &mut Vec) { + let mut as_map = BTreeMap::new(); + for season in seasons.iter() { + as_map + .entry(season.season_number) + .or_insert(vec![]) + .push(season) + } + + let duplicates: Vec<&Season> = as_map + .into_values() + .filter(|s| s.len() > 1) + .flatten() + .collect(); + progress_pause!(); + let _ = Term::stdout().clear_line(); + let keep = select( + "Duplicated seasons were found. Select the one you want to download (space to select/deselect; enter to continue)", + duplicates + .iter() + .map(|s| format!("Season {} ({})", s.season_number, s.title)) + .collect(), + ); + progress_pause!(); + + let mut remove_ids = vec![]; + for (i, duplicate) in duplicates.into_iter().enumerate() { + if !keep.contains(&i) { + remove_ids.push(duplicate.id.clone()) + } + } + + seasons.retain(|s| !remove_ids.contains(&s.id)); +} + +pub fn select(prompt: &str, input: Vec) -> Vec { + if input.is_empty() { + return vec![]; + } + + let def: Vec = (0..input.len()).map(|_| true).collect(); + + let selection = MultiSelect::new() + .with_prompt(prompt) + .items(&input[..]) + .defaults(&def[..]) + .clear(false) + .report(false) + .interact_on(&Term::stdout()) + .unwrap_or_default(); + + selection +} diff --git a/crunchy-cli-core/src/utils/log.rs b/crunchy-cli-core/src/utils/log.rs index 37bc5a9..c74b73d 100644 --- a/crunchy-cli-core/src/utils/log.rs +++ b/crunchy-cli-core/src/utils/log.rs @@ -1,4 +1,4 @@ -use indicatif::{ProgressBar, ProgressStyle}; +use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle}; use log::{ info, set_boxed_logger, set_max_level, Level, LevelFilter, Log, Metadata, Record, SetLoggerError, @@ -37,6 +37,15 @@ macro_rules! progress { } pub(crate) use progress; +macro_rules! progress_pause { + () => { + { + log::info!(target: "progress_pause", "") + } + } +} +pub(crate) use progress_pause; + macro_rules! tab_info { ($($arg:tt)+) => { if log::max_level() == log::LevelFilter::Debug { @@ -62,6 +71,7 @@ impl Log for CliLogger { fn log(&self, record: &Record) { if !self.enabled(record.metadata()) || (record.target() != "progress" + && record.target() != "progress_pause" && record.target() != "progress_end" && !record.target().starts_with("crunchy_cli")) { @@ -75,6 +85,16 @@ impl Log for CliLogger { match record.target() { "progress" => self.progress(record, false), + "progress_pause" => { + let progress = self.progress.lock().unwrap(); + if let Some(p) = &*progress { + p.set_draw_target(if p.is_hidden() { + ProgressDrawTarget::stdout() + } else { + ProgressDrawTarget::hidden() + }) + } + } "progress_end" => self.progress(record, true), _ => { if self.progress.lock().unwrap().is_some() { @@ -158,6 +178,7 @@ impl CliLogger { .unwrap() .tick_strings(&["—", "\\", "|", "/", finish_str]), ); + pb.set_draw_target(ProgressDrawTarget::stdout()); pb.enable_steady_tick(Duration::from_millis(200)); pb.set_message(msg); *progress = Some(pb) diff --git a/crunchy-cli-core/src/utils/mod.rs b/crunchy-cli-core/src/utils/mod.rs index c991cd8..d46cc33 100644 --- a/crunchy-cli-core/src/utils/mod.rs +++ b/crunchy-cli-core/src/utils/mod.rs @@ -4,6 +4,7 @@ pub mod download; pub mod ffmpeg; pub mod filter; pub mod format; +pub mod interactive_select; pub mod locale; pub mod log; pub mod os; From 75b6e7b4523444cb3efdd2f400de1db661859992 Mon Sep 17 00:00:00 2001 From: bytedream Date: Sat, 24 Jun 2023 12:57:22 +0200 Subject: [PATCH 037/272] Add long flag options to -v and -q (--verbose and --quiet) --- crunchy-cli-core/src/lib.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index 7cb68ce..5aef69a 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -90,27 +90,27 @@ enum Command { #[derive(Debug, Parser)] struct Verbosity { #[arg(help = "Verbose output")] - #[arg(short)] - v: bool, + #[arg(short, long)] + verbose: bool, #[arg(help = "Quiet output. Does not print anything unless it's a error")] #[arg( long_help = "Quiet output. Does not print anything unless it's a error. Can be helpful if you pipe the output to stdout" )] - #[arg(short)] - q: bool, + #[arg(short, long)] + quiet: bool, } pub async fn cli_entrypoint() { let mut cli: Cli = Cli::parse(); if let Some(verbosity) = &cli.verbosity { - if verbosity.v as u8 + verbosity.q as u8 > 1 { + if verbosity.verbose as u8 + verbosity.quiet as u8 > 1 { eprintln!("Output cannot be verbose ('-v') and quiet ('-q') at the same time"); std::process::exit(1) - } else if verbosity.v { + } else if verbosity.verbose { CliLogger::init(LevelFilter::Debug).unwrap() - } else if verbosity.q { + } else if verbosity.quiet { CliLogger::init(LevelFilter::Error).unwrap() } } else { From 618d2206a2c40d1ddf5bea4c1cfa8f5894560c2f Mon Sep 17 00:00:00 2001 From: bytedream Date: Sat, 24 Jun 2023 13:05:30 +0200 Subject: [PATCH 038/272] Hide interactive output when -q flag is set --- crunchy-cli-core/src/lib.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index 5aef69a..982aa17 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -120,8 +120,20 @@ pub async fn cli_entrypoint() { debug!("cli input: {:?}", cli); match &mut cli.command { - Command::Archive(archive) => pre_check_executor(archive).await, - Command::Download(download) => pre_check_executor(download).await, + Command::Archive(archive) => { + // prevent interactive select to be shown when output should be quiet + if cli.verbosity.is_some() && cli.verbosity.as_ref().unwrap().quiet { + archive.yes = true; + } + pre_check_executor(archive).await + } + Command::Download(download) => { + // prevent interactive select to be shown when output should be quiet + if cli.verbosity.is_some() && cli.verbosity.as_ref().unwrap().quiet { + download.yes = true; + } + pre_check_executor(download).await + } Command::Login(login) => { if login.remove { if let Some(session_file) = login::session_file_path() { From 0234d46bf9377ce63311fba00383d1e9dfa86741 Mon Sep 17 00:00:00 2001 From: bytedream Date: Sun, 25 Jun 2023 17:47:40 +0200 Subject: [PATCH 039/272] Fix duplicated download with archive --- crunchy-cli-core/src/archive/filter.rs | 89 +++++++++++++++++++------- crunchy-cli-core/src/utils/format.rs | 6 ++ 2 files changed, 73 insertions(+), 22 deletions(-) diff --git a/crunchy-cli-core/src/archive/filter.rs b/crunchy-cli-core/src/archive/filter.rs index d6593e5..38fed32 100644 --- a/crunchy-cli-core/src/archive/filter.rs +++ b/crunchy-cli-core/src/archive/filter.rs @@ -79,15 +79,15 @@ impl Filter for ArchiveFilter { let mut remove_ids = vec![]; for season in seasons.iter_mut() { if !self.url_filter.is_season_valid(season.season_number) - && !season + || (!season .audio_locales .iter() .any(|l| self.archive.audio.contains(l)) - && !season - .available_versions() - .await? - .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()); } @@ -172,20 +172,44 @@ impl Filter for ArchiveFilter { let mut episodes = vec![]; for season in seasons { self.season_sorting.push(season.id.clone()); - let season_locale = season - .audio_locales - .get(0) - .cloned() - .unwrap_or(Locale::ja_JP); + let season_locale = if season.audio_locales.len() < 2 { + Some( + season + .audio_locales + .get(0) + .cloned() + .unwrap_or(Locale::ja_JP), + ) + } else { + None + }; let mut eps = season.episodes().await?; let before_len = eps.len(); - eps.retain(|e| e.audio_locale == season_locale); - if eps.len() != before_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.len() == 0 { if matches!(self.visited, Visited::Series) { warn!( "Season {} is not available with {} audio", - season.season_number, season_locale + season.season_number, + season_locale.unwrap_or(Locale::ja_JP) ) } } else { @@ -193,7 +217,7 @@ impl Filter for ArchiveFilter { warn!( "Season {} is only available with {} audio until episode {} ({})", season.season_number, - season_locale, + season_locale.unwrap_or(Locale::ja_JP), last_episode.episode_number, last_episode.title ) @@ -339,24 +363,45 @@ impl Filter for ArchiveFilter { let mut single_format_collection = SingleFormatCollection::new(); - let mut pre_sorted: BTreeMap<(String, String), Self::T> = BTreeMap::new(); + let mut pre_sorted: BTreeMap = BTreeMap::new(); for data in flatten_input { pre_sorted - .entry((data.season_id.clone(), data.sequence_number.to_string())) + .entry(data.identifier.clone()) .or_insert(vec![]) .push(data) } - let mut sorted: Vec<((String, String), Self::T)> = pre_sorted.into_iter().collect(); - sorted.sort_by(|((a, _), _), ((b, _), _)| { + let mut sorted: Vec<(String, Self::T)> = pre_sorted.into_iter().collect(); + sorted.sort_by(|(_, a), (_, b)| { self.season_sorting .iter() - .position(|p| p == a) + .position(|p| p == &a.first().unwrap().season_id) .unwrap() - .cmp(&self.season_sorting.iter().position(|p| p == b).unwrap()) + .cmp( + &self + .season_sorting + .iter() + .position(|p| p == &b.first().unwrap().season_id) + .unwrap(), + ) }); - for (_, data) in sorted { + for (_, mut data) in sorted { + data.sort_by(|a, b| { + self.archive + .audio + .iter() + .position(|p| p == &a.audio) + .unwrap_or(usize::MAX) + .cmp( + &self + .archive + .audio + .iter() + .position(|p| p == &b.audio) + .unwrap_or(usize::MAX), + ) + }); single_format_collection.add_single_formats(data) } diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index c67386d..16d268e 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -12,6 +12,8 @@ use std::path::{Path, PathBuf}; #[derive(Clone)] pub struct SingleFormat { + pub identifier: String, + pub title: String, pub description: String, @@ -42,6 +44,7 @@ impl SingleFormat { relative_episode_number: Option, ) -> Self { Self { + identifier: episode.identifier.clone(), title: episode.title.clone(), description: episode.description.clone(), audio: episode.audio_locale.clone(), @@ -66,6 +69,7 @@ impl SingleFormat { pub fn new_from_movie(movie: Movie, subtitles: Vec) -> Self { Self { + identifier: movie.id.clone(), title: movie.title.clone(), description: movie.description.clone(), audio: Locale::ja_JP, @@ -86,6 +90,7 @@ impl SingleFormat { pub fn new_from_music_video(music_video: MusicVideo) -> Self { Self { + identifier: music_video.id.clone(), title: music_video.title.clone(), description: music_video.description.clone(), audio: Locale::ja_JP, @@ -106,6 +111,7 @@ impl SingleFormat { pub fn new_from_concert(concert: Concert) -> Self { Self { + identifier: concert.id.clone(), title: concert.title.clone(), description: concert.description.clone(), audio: Locale::ja_JP, From f40dc0dd1c63b695cdc2b75adef3db6320439309 Mon Sep 17 00:00:00 2001 From: Bastian Venz Date: Mon, 26 Jun 2023 17:59:55 +0200 Subject: [PATCH 040/272] Update crunchyroll-rs to 0.3.7 (#220) --- Cargo.lock | 188 +--------------------- crunchy-cli-core/Cargo.lock | 216 +++----------------------- crunchy-cli-core/Cargo.toml | 2 +- crunchy-cli-core/src/search/format.rs | 8 +- crunchy-cli-core/src/utils/format.rs | 8 +- 5 files changed, 34 insertions(+), 388 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dedc0ff..7a724a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -307,16 +307,6 @@ dependencies = [ "url", ] -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -376,9 +366,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "510ab662065c5ff28678e66fc1ad243727044642f2dd02a5bbadc12aa2717779" +checksum = "921f8aefa462be97067128bad89e273d3808320bf4a3c9d5be368e2cc9878c50" dependencies = [ "aes", "async-trait", @@ -403,9 +393,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs-internal" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a1e71fd50850102f81e439c08ffcb69ae98b64d4eb292c359a33ac2253aaa91" +checksum = "d1700be68ab7e7098ac1b9ced729d92d66743c8a2697047284b5b73af0f8b328" dependencies = [ "darling", "quote", @@ -589,21 +579,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.0" @@ -644,12 +619,6 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" -[[package]] -name = "futures-io" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" - [[package]] name = "futures-sink" version = "0.3.28" @@ -669,9 +638,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-core", - "futures-io", "futures-task", - "memchr", "pin-project-lite", "pin-utils", "slab", @@ -821,19 +788,6 @@ dependencies = [ "tokio-rustls", ] -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - [[package]] name = "iana-time-zone" version = "0.1.57" @@ -1059,24 +1013,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "nix" version = "0.26.2" @@ -1130,50 +1066,6 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" -[[package]] -name = "openssl" -version = "0.10.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "option-ext" version = "0.2.0" @@ -1198,12 +1090,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - [[package]] name = "portable-atomic" version = "1.3.3" @@ -1318,12 +1204,10 @@ dependencies = [ "http-body", "hyper", "hyper-rustls", - "hyper-tls", "ipnet", "js-sys", "log", "mime", - "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -1333,7 +1217,6 @@ dependencies = [ "serde_json", "serde_urlencoded", "tokio", - "tokio-native-tls", "tokio-rustls", "tokio-socks", "tower-service", @@ -1427,15 +1310,6 @@ dependencies = [ "regex", ] -[[package]] -name = "schannel" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" -dependencies = [ - "windows-sys 0.42.0", -] - [[package]] name = "sct" version = "0.7.0" @@ -1446,29 +1320,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "security-framework" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "serde" version = "1.0.164" @@ -1745,16 +1596,6 @@ dependencies = [ "syn", ] -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.24.1" @@ -1879,12 +1720,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.4" @@ -2047,21 +1882,6 @@ dependencies = [ "windows-targets 0.48.0", ] -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-sys" version = "0.45.0" diff --git a/crunchy-cli-core/Cargo.lock b/crunchy-cli-core/Cargo.lock index e794609..48bd37e 100644 --- a/crunchy-cli-core/Cargo.lock +++ b/crunchy-cli-core/Cargo.lock @@ -288,16 +288,6 @@ dependencies = [ "url", ] -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -324,6 +314,7 @@ dependencies = [ "crunchyroll-rs", "ctrlc", "derive_setters", + "dialoguer", "dirs", "fs2", "indicatif", @@ -339,15 +330,14 @@ dependencies = [ "shlex", "sys-locale", "tempfile", - "terminal_size", "tokio", ] [[package]] name = "crunchyroll-rs" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "510ab662065c5ff28678e66fc1ad243727044642f2dd02a5bbadc12aa2717779" +checksum = "921f8aefa462be97067128bad89e273d3808320bf4a3c9d5be368e2cc9878c50" dependencies = [ "aes", "async-trait", @@ -372,9 +362,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs-internal" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a1e71fd50850102f81e439c08ffcb69ae98b64d4eb292c359a33ac2253aaa91" +checksum = "d1700be68ab7e7098ac1b9ced729d92d66743c8a2697047284b5b73af0f8b328" dependencies = [ "darling", "quote", @@ -470,6 +460,16 @@ dependencies = [ "syn", ] +[[package]] +name = "dialoguer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59c6f2989294b9a498d3ad5491a79c6deb604617378e1cdc4bfc1c1361fe2f87" +dependencies = [ + "console", + "shell-words", +] + [[package]] name = "dirs" version = "5.0.1" @@ -548,21 +548,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.0" @@ -603,12 +588,6 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" -[[package]] -name = "futures-io" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" - [[package]] name = "futures-sink" version = "0.3.28" @@ -628,9 +607,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-core", - "futures-io", "futures-task", - "memchr", "pin-project-lite", "pin-utils", "slab", @@ -780,19 +757,6 @@ dependencies = [ "tokio-rustls", ] -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - [[package]] name = "iana-time-zone" version = "0.1.57" @@ -1018,24 +982,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "nix" version = "0.26.2" @@ -1089,50 +1035,6 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" -[[package]] -name = "openssl" -version = "0.10.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.88" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "option-ext" version = "0.2.0" @@ -1157,12 +1059,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - [[package]] name = "portable-atomic" version = "1.3.3" @@ -1277,12 +1173,10 @@ dependencies = [ "http-body", "hyper", "hyper-rustls", - "hyper-tls", "ipnet", "js-sys", "log", "mime", - "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -1292,7 +1186,6 @@ dependencies = [ "serde_json", "serde_urlencoded", "tokio", - "tokio-native-tls", "tokio-rustls", "tokio-socks", "tower-service", @@ -1380,15 +1273,6 @@ dependencies = [ "regex", ] -[[package]] -name = "schannel" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" -dependencies = [ - "windows-sys 0.42.0", -] - [[package]] name = "sct" version = "0.7.0" @@ -1399,29 +1283,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "security-framework" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "serde" version = "1.0.164" @@ -1502,6 +1363,12 @@ dependencies = [ "syn", ] +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + [[package]] name = "shlex" version = "1.1.0" @@ -1591,16 +1458,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "terminal_size" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" -dependencies = [ - "rustix", - "windows-sys 0.48.0", -] - [[package]] name = "thiserror" version = "1.0.40" @@ -1702,16 +1559,6 @@ dependencies = [ "syn", ] -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.24.1" @@ -1836,12 +1683,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.4" @@ -2004,21 +1845,6 @@ dependencies = [ "windows-targets 0.48.0", ] -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-sys" version = "0.45.0" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index cf2b7c3..27e3846 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -9,7 +9,7 @@ anyhow = "1.0" async-trait = "0.1" clap = { version = "4.3", features = ["derive", "string"] } chrono = "0.4" -crunchyroll-rs = { version = "0.3.6", features = ["dash-stream"] } +crunchyroll-rs = { version = "0.3.7", features = ["dash-stream"] } ctrlc = "3.4" dialoguer = { version = "0.10", default-features = false } dirs = "5.0" diff --git a/crunchy-cli-core/src/search/format.rs b/crunchy-cli-core/src/search/format.rs index 6769c4c..3574597 100644 --- a/crunchy-cli-core/src/search/format.rs +++ b/crunchy-cli-core/src/search/format.rs @@ -428,7 +428,7 @@ impl Format { if !stream_empty { for (_, episodes) in tree.iter_mut() { for (episode, streams) in episodes { - streams.push(episode.streams().await?) + streams.push(episode.stream().await?) } } } else { @@ -497,7 +497,7 @@ impl Format { } if !stream_empty { for (movie, streams) in tree.iter_mut() { - streams.push(movie.streams().await?) + streams.push(movie.stream().await?) } } else { for (_, streams) in tree.iter_mut() { @@ -535,7 +535,7 @@ impl Format { let stream_empty = self.check_pattern_count_empty(Scope::Stream); let music_video = must_match_if_true!(!music_video_empty => media_collection|MediaCollection::MusicVideo(music_video) => music_video.clone()).unwrap_or_default(); - let stream = must_match_if_true!(!stream_empty => media_collection|MediaCollection::MusicVideo(music_video) => music_video.streams().await?).unwrap_or_default(); + let stream = must_match_if_true!(!stream_empty => media_collection|MediaCollection::MusicVideo(music_video) => music_video.stream().await?).unwrap_or_default(); let music_video_map = self.serializable_to_json_map(FormatMusicVideo::from(&music_video)); let stream_map = self.serializable_to_json_map(FormatStream::from(&stream)); @@ -557,7 +557,7 @@ impl Format { let stream_empty = self.check_pattern_count_empty(Scope::Stream); let concert = must_match_if_true!(!concert_empty => media_collection|MediaCollection::Concert(concert) => concert.clone()).unwrap_or_default(); - let stream = must_match_if_true!(!stream_empty => media_collection|MediaCollection::Concert(concert) => concert.streams().await?).unwrap_or_default(); + let stream = must_match_if_true!(!stream_empty => media_collection|MediaCollection::Concert(concert) => concert.stream().await?).unwrap_or_default(); let concert_map = self.serializable_to_json_map(FormatConcert::from(&concert)); let stream_map = self.serializable_to_json_map(FormatStream::from(&stream)); diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index 16d268e..0b0f46e 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -132,10 +132,10 @@ impl SingleFormat { pub async fn stream(&self) -> Result { let stream = match &self.source { - MediaCollection::Episode(e) => e.streams().await?, - MediaCollection::Movie(m) => m.streams().await?, - MediaCollection::MusicVideo(mv) => mv.streams().await?, - MediaCollection::Concert(c) => c.streams().await?, + MediaCollection::Episode(e) => e.stream().await?, + MediaCollection::Movie(m) => m.stream().await?, + MediaCollection::MusicVideo(mv) => mv.stream().await?, + MediaCollection::Concert(c) => c.stream().await?, _ => unreachable!(), }; Ok(stream) From af8a88a7927f330b51b805d58adfa717013a59a8 Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 5 Jul 2023 01:57:56 +0200 Subject: [PATCH 041/272] Add option to force subtitle burn with download (#221) --- crunchy-cli-core/src/download/command.rs | 11 +++- crunchy-cli-core/src/utils/download.rs | 74 +++++++++++++----------- 2 files changed, 50 insertions(+), 35 deletions(-) diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index 0167f49..ac1e391 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -77,6 +77,10 @@ pub struct Download { #[arg(short, long, default_value_t = false)] pub(crate) yes: bool, + #[arg(help = "Force subtitles to be always burnt-in")] + #[arg(long, default_value_t = false)] + pub(crate) force_hardsub: bool, + #[arg(help = "Url(s) to Crunchyroll episodes or series")] pub(crate) urls: Vec, } @@ -98,8 +102,10 @@ impl Execute for Download { if self.subtitle.is_some() { if let Some(ext) = Path::new(&self.output).extension() { - if ext.to_string_lossy() != "mp4" { - warn!("Detected a non mp4 output container. Adding subtitles may take a while") + if self.force_hardsub { + warn!("Hardsubs are forced. Adding subtitles may take a while") + } else if !["mkv", "mov", "mp4"].contains(&ext.to_string_lossy().as_ref()) { + warn!("Detected a container which does not support softsubs. Adding subtitles may take a while") } } } @@ -137,6 +143,7 @@ impl Execute for Download { let download_builder = DownloadBuilder::new() .default_subtitle(self.subtitle.clone()) + .force_hardsub(self.force_hardsub) .output_format(if is_special_file(&self.output) || self.output == "-" { Some("mpegts".to_string()) } else { diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index dcfcf0a..1e1b207 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -47,6 +47,7 @@ pub struct DownloadBuilder { output_format: Option, audio_sort: Option>, subtitle_sort: Option>, + force_hardsub: bool, } impl DownloadBuilder { @@ -57,6 +58,7 @@ impl DownloadBuilder { output_format: None, audio_sort: None, subtitle_sort: None, + force_hardsub: false, } } @@ -68,6 +70,8 @@ impl DownloadBuilder { audio_sort: self.audio_sort, subtitle_sort: self.subtitle_sort, + force_hardsub: self.force_hardsub, + formats: vec![], } } @@ -92,6 +96,8 @@ pub struct Downloader { audio_sort: Option>, subtitle_sort: Option>, + force_hardsub: bool, + formats: Vec, } @@ -255,8 +261,9 @@ impl Downloader { // this formats are supporting embedding subtitles into the video container instead of // burning it into the video stream directly - let container_supports_softsubs = - ["mkv", "mov", "mp4"].contains(&dst.extension().unwrap_or_default().to_str().unwrap()); + let container_supports_softsubs = !self.force_hardsub + && ["mkv", "mov", "mp4"] + .contains(&dst.extension().unwrap_or_default().to_str().unwrap()); if container_supports_softsubs { for (i, meta) in subtitles.iter().enumerate() { @@ -290,38 +297,39 @@ impl Downloader { .iter() .position(|m| m.language == default_subtitle) { - match dst.extension().unwrap_or_default().to_str().unwrap() { - "mkv" => (), - "mov" | "mp4" => output_presets.extend([ - "-movflags".to_string(), - "faststart".to_string(), - "-c:s".to_string(), - "mov_text".to_string(), - ]), - _ => { - // remove '-c:v copy' and '-c:a copy' from output presets as its causes issues with - // burning subs into the video - let mut last = String::new(); - let mut remove_count = 0; - for (i, s) in output_presets.clone().iter().enumerate() { - if (last == "-c:v" || last == "-c:a") && s == "copy" { - // remove last - output_presets.remove(i - remove_count - 1); - remove_count += 1; - output_presets.remove(i - remove_count); - remove_count += 1; - } - last = s.clone(); - } - - output_presets.extend([ - "-vf".to_string(), - format!( - "ass={}", - subtitles.get(position).unwrap().path.to_str().unwrap() - ), - ]) + if container_supports_softsubs { + match dst.extension().unwrap_or_default().to_str().unwrap() { + "mov" | "mp4" => output_presets.extend([ + "-movflags".to_string(), + "faststart".to_string(), + "-c:s".to_string(), + "mov_text".to_string(), + ]), + _ => (), } + } else { + // remove '-c:v copy' and '-c:a copy' from output presets as its causes issues with + // burning subs into the video + let mut last = String::new(); + let mut remove_count = 0; + for (i, s) in output_presets.clone().iter().enumerate() { + if (last == "-c:v" || last == "-c:a") && s == "copy" { + // remove last + output_presets.remove(i - remove_count - 1); + remove_count += 1; + output_presets.remove(i - remove_count); + remove_count += 1; + } + last = s.clone(); + } + + output_presets.extend([ + "-vf".to_string(), + format!( + "ass={}", + subtitles.get(position).unwrap().path.to_str().unwrap() + ), + ]) } } From 1fe8746dda317f117b878a6c18c583b416737993 Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 5 Jul 2023 16:01:55 +0200 Subject: [PATCH 042/272] Add support for old url scheme (#224) --- crunchy-cli-core/src/utils/parse.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/crunchy-cli-core/src/utils/parse.rs b/crunchy-cli-core/src/utils/parse.rs index 1bf9364..f85d8c2 100644 --- a/crunchy-cli-core/src/utils/parse.rs +++ b/crunchy-cli-core/src/utils/parse.rs @@ -130,6 +130,20 @@ pub async fn parse_url( UrlFilter::default() }; + // check if the url is the old series/episode scheme which still occurs in some places (like the + // rss) + let old_url_regex = Regex::new(r"https?://(www\.)?crunchyroll\.com/.+").unwrap(); + if old_url_regex.is_match(&url) { + debug!("Detected maybe old url"); + // replace the 'http' prefix with 'https' as https is not supported by the reqwest client + if url.starts_with("http://") { + url.replace_range(0..4, "https") + } + // the old url redirects to the new url. request the old url, follow the redirects and + // extract the final url + url = crunchy.client().get(&url).send().await?.url().to_string() + } + let parsed_url = crunchyroll_rs::parse_url(url).map_or(Err(anyhow!("Invalid url")), Ok)?; debug!("Url type: {:?}", parsed_url); let media_collection = match parsed_url { From 751735477cdac22edddcbf74dac059f2d996d73d Mon Sep 17 00:00:00 2001 From: bytedream Date: Sat, 8 Jul 2023 16:36:35 +0200 Subject: [PATCH 043/272] Update dependencies --- Cargo.lock | 312 ++++++++++++++++++++++++------------ Cargo.toml | 2 +- crunchy-cli-core/Cargo.lock | 308 +++++++++++++++++++++++------------ crunchy-cli-core/Cargo.toml | 8 +- crunchy-cli-core/src/lib.rs | 14 +- 5 files changed, 423 insertions(+), 221 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7a724a7..cc02df5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aes" version = "0.8.3" @@ -54,15 +69,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" [[package]] name = "anstyle-parse" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" dependencies = [ "utf8parse", ] @@ -94,9 +109,9 @@ checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" dependencies = [ "proc-macro2", "quote", @@ -109,6 +124,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.21.2" @@ -131,6 +161,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + [[package]] name = "block-padding" version = "0.3.3" @@ -201,9 +237,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.4" +version = "4.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80672091db20273a15cf9fdd4e47ed43b5091ec9841bf4c6145c9dfbbcae09ed" +checksum = "1640e5cc7fb47dbb8338fd471b105e7ed6c3cb2aeb00c2e067127ffd3764a05d" dependencies = [ "clap_builder", "clap_derive", @@ -212,22 +248,21 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.4" +version = "4.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1458a1df40e1e2afebb7ab60ce55c1fa8f431146205aa5f4887e0b111c27636" +checksum = "98c59138d527eeaf9b53f35a77fcc1fad9d883116070c63d5de1c7dc7b00c72b" dependencies = [ "anstream", "anstyle", - "bitflags", "clap_lex", "strsim", ] [[package]] name = "clap_complete" -version = "4.3.1" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6b5c519bab3ea61843a7923d074b04245624bb84a64a8c150f5deb014e388b" +checksum = "5fc443334c81a804575546c5a8a79b4913b50e28d69232903604cada1de817ce" dependencies = [ "clap", ] @@ -315,9 +350,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] @@ -366,9 +401,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs" -version = "0.3.7" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "921f8aefa462be97067128bad89e273d3808320bf4a3c9d5be368e2cc9878c50" +checksum = "3be9aa4589c26829667cc6f32f7238b93cdc0c6c130b295b3714df7ea6c28ef1" dependencies = [ "aes", "async-trait", @@ -388,14 +423,14 @@ dependencies = [ "serde_urlencoded", "smart-default", "tokio", - "webpki-roots 0.23.1", + "webpki-roots 0.24.0", ] [[package]] name = "crunchyroll-rs-internal" -version = "0.3.7" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1700be68ab7e7098ac1b9ced729d92d66743c8a2697047284b5b73af0f8b328" +checksum = "b718f70c2825f2310e2301295a3a66f1723bbdd39f6cfbe6148df00556e9c75e" dependencies = [ "darling", "quote", @@ -459,9 +494,9 @@ dependencies = [ [[package]] name = "dash-mpd" -version = "0.9.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b97b7a11cc6dcf0c803554cbd7f7d8dfef99c598e6a310403bb5699d9a94076" +checksum = "ef11db94edb7974469f90fe64eaa95b3a2b36fdd5f72420717f7ee56a1922988" dependencies = [ "base64", "base64-serde", @@ -619,6 +654,17 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-sink" version = "0.3.28" @@ -638,6 +684,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-core", + "futures-macro", "futures-task", "pin-project-lite", "pin-utils", @@ -666,10 +713,16 @@ dependencies = [ ] [[package]] -name = "h2" -version = "0.3.19" +name = "gimli" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + +[[package]] +name = "h2" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" dependencies = [ "bytes", "fnv", @@ -698,18 +751,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.2.6" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "hex" @@ -753,9 +797,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.26" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", @@ -777,10 +821,11 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ + "futures-util", "http", "hyper", "rustls", @@ -897,26 +942,25 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.1", + "hermit-abi", "libc", "windows-sys 0.48.0", ] [[package]] name = "ipnet" -version = "2.7.2" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] name = "is-terminal" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "hermit-abi 0.3.1", - "io-lifetimes", - "rustix", + "hermit-abi", + "rustix 0.38.3", "windows-sys 0.48.0", ] @@ -931,9 +975,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" [[package]] name = "js-sys" @@ -952,9 +996,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.146" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "linux-raw-sys" @@ -962,6 +1006,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +[[package]] +name = "linux-raw-sys" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" + [[package]] name = "log" version = "0.4.19" @@ -1002,6 +1052,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.8" @@ -1019,7 +1078,7 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", "static_assertions", @@ -1046,11 +1105,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "libc", ] @@ -1060,6 +1119,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +[[package]] +name = "object" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.18.0" @@ -1080,9 +1148,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" [[package]] name = "pin-utils" @@ -1098,9 +1166,9 @@ checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794" [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" dependencies = [ "unicode-ident", ] @@ -1123,9 +1191,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.28.2" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce5e73202a820a31f8a0ee32ada5e21029c81fd9e3ebf668a40832e4219d9d1" +checksum = "81b9228215d82c7b61490fec1de287136b5de6f5700f6e58ea9ad61a7964ca51" dependencies = [ "memchr", "serde", @@ -1133,9 +1201,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ "proc-macro2", ] @@ -1146,7 +1214,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1155,7 +1223,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1171,9 +1239,21 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.4" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d3daa6976cffb758ec878f108ba0e062a45b2d6ca3a2cca965338855476caf" dependencies = [ "aho-corasick", "memchr", @@ -1182,9 +1262,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846" [[package]] name = "reqwest" @@ -1250,24 +1330,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" [[package]] -name = "rustix" -version = "0.37.20" +name = "rustc-demangle" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.37.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", - "linux-raw-sys", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac5ffa1efe7548069688cd7028f32591853cd7b5b756d41bcffd2353e4fc75b4" +dependencies = [ + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys 0.4.3", "windows-sys 0.48.0", ] [[package]] name = "rustls" -version = "0.21.2" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e32ca28af694bc1bbf399c33a516dbdf1c90090b8ab23c2bc24f834aa2247f5f" +checksum = "b19faa85ecb5197342b54f987b142fb3e30d0c90da40f80ef4fa9a726e6676ed" dependencies = [ "log", "ring", @@ -1277,18 +1376,18 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ "base64", ] [[package]] name = "rustls-webpki" -version = "0.100.1" +version = "0.101.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +checksum = "15f36a6828982f422756984e47912a7a51dcbc2a197aa791158f8ca61cd8204e" dependencies = [ "ring", "untrusted", @@ -1296,9 +1395,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" [[package]] name = "sanitize-filename" @@ -1322,18 +1421,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.164" +version = "1.0.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "7daf513456463b42aa1d94cff7e0c24d682b429f020b9afa4f5ba5c40a22b237" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "b69b106b68bc8054f0e974e70d19984040f8a5cf9215ca82626ea4853f82c4b9" dependencies = [ "proc-macro2", "quote", @@ -1342,9 +1441,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.97" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" +checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" dependencies = [ "itoa", "ryu", @@ -1462,9 +1561,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.18" +version = "2.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" dependencies = [ "proc-macro2", "quote", @@ -1491,24 +1590,24 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix", + "rustix 0.37.23", "windows-sys 0.48.0", ] [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" dependencies = [ "proc-macro2", "quote", @@ -1570,11 +1669,12 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.2" +version = "1.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" dependencies = [ "autocfg", + "backtrace", "bytes", "libc", "mio", @@ -1678,9 +1778,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" [[package]] name = "unicode-normalization" @@ -1844,9 +1944,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.23.1" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" +checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" dependencies = [ "rustls-webpki", ] @@ -1879,7 +1979,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.1", ] [[package]] @@ -1897,7 +1997,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.1", ] [[package]] @@ -1917,9 +2017,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ "windows_aarch64_gnullvm 0.48.0", "windows_aarch64_msvc 0.48.0", diff --git a/Cargo.toml b/Cargo.toml index beddc9e..4deb9d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ version = "3.0.0-dev.14" edition = "2021" [dependencies] -tokio = { version = "1.28", features = ["macros", "rt-multi-thread", "time"], default-features = false } +tokio = { version = "1.29", features = ["macros", "rt-multi-thread", "time"], default-features = false } crunchy-cli-core = { path = "./crunchy-cli-core" } diff --git a/crunchy-cli-core/Cargo.lock b/crunchy-cli-core/Cargo.lock index 48bd37e..5f9347b 100644 --- a/crunchy-cli-core/Cargo.lock +++ b/crunchy-cli-core/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aes" version = "0.8.3" @@ -54,15 +69,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" [[package]] name = "anstyle-parse" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" dependencies = [ "utf8parse", ] @@ -94,9 +109,9 @@ checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" dependencies = [ "proc-macro2", "quote", @@ -109,6 +124,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base64" version = "0.21.2" @@ -131,6 +161,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + [[package]] name = "block-padding" version = "0.3.3" @@ -201,9 +237,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.4" +version = "4.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80672091db20273a15cf9fdd4e47ed43b5091ec9841bf4c6145c9dfbbcae09ed" +checksum = "1640e5cc7fb47dbb8338fd471b105e7ed6c3cb2aeb00c2e067127ffd3764a05d" dependencies = [ "clap_builder", "clap_derive", @@ -212,13 +248,12 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.4" +version = "4.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1458a1df40e1e2afebb7ab60ce55c1fa8f431146205aa5f4887e0b111c27636" +checksum = "98c59138d527eeaf9b53f35a77fcc1fad9d883116070c63d5de1c7dc7b00c72b" dependencies = [ "anstream", "anstyle", - "bitflags", "clap_lex", "strsim", ] @@ -296,9 +331,9 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] @@ -335,9 +370,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs" -version = "0.3.7" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "921f8aefa462be97067128bad89e273d3808320bf4a3c9d5be368e2cc9878c50" +checksum = "3be9aa4589c26829667cc6f32f7238b93cdc0c6c130b295b3714df7ea6c28ef1" dependencies = [ "aes", "async-trait", @@ -357,14 +392,14 @@ dependencies = [ "serde_urlencoded", "smart-default", "tokio", - "webpki-roots 0.23.1", + "webpki-roots 0.24.0", ] [[package]] name = "crunchyroll-rs-internal" -version = "0.3.7" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1700be68ab7e7098ac1b9ced729d92d66743c8a2697047284b5b73af0f8b328" +checksum = "b718f70c2825f2310e2301295a3a66f1723bbdd39f6cfbe6148df00556e9c75e" dependencies = [ "darling", "quote", @@ -428,9 +463,9 @@ dependencies = [ [[package]] name = "dash-mpd" -version = "0.9.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b97b7a11cc6dcf0c803554cbd7f7d8dfef99c598e6a310403bb5699d9a94076" +checksum = "ef11db94edb7974469f90fe64eaa95b3a2b36fdd5f72420717f7ee56a1922988" dependencies = [ "base64", "base64-serde", @@ -588,6 +623,17 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-sink" version = "0.3.28" @@ -607,6 +653,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-core", + "futures-macro", "futures-task", "pin-project-lite", "pin-utils", @@ -635,10 +682,16 @@ dependencies = [ ] [[package]] -name = "h2" -version = "0.3.19" +name = "gimli" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + +[[package]] +name = "h2" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" dependencies = [ "bytes", "fnv", @@ -667,18 +720,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.2.6" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "hex" @@ -722,9 +766,9 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.26" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", @@ -746,10 +790,11 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7" +checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ + "futures-util", "http", "hyper", "rustls", @@ -866,26 +911,25 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.1", + "hermit-abi", "libc", "windows-sys 0.48.0", ] [[package]] name = "ipnet" -version = "2.7.2" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" [[package]] name = "is-terminal" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "hermit-abi 0.3.1", - "io-lifetimes", - "rustix", + "hermit-abi", + "rustix 0.38.3", "windows-sys 0.48.0", ] @@ -900,9 +944,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" [[package]] name = "js-sys" @@ -921,9 +965,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.146" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "linux-raw-sys" @@ -931,6 +975,12 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +[[package]] +name = "linux-raw-sys" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" + [[package]] name = "log" version = "0.4.19" @@ -971,6 +1021,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.8" @@ -988,7 +1047,7 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", "static_assertions", @@ -1015,11 +1074,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "libc", ] @@ -1029,6 +1088,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +[[package]] +name = "object" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.18.0" @@ -1049,9 +1117,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" [[package]] name = "pin-utils" @@ -1067,9 +1135,9 @@ checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794" [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" dependencies = [ "unicode-ident", ] @@ -1092,9 +1160,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.28.2" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce5e73202a820a31f8a0ee32ada5e21029c81fd9e3ebf668a40832e4219d9d1" +checksum = "81b9228215d82c7b61490fec1de287136b5de6f5700f6e58ea9ad61a7964ca51" dependencies = [ "memchr", "serde", @@ -1102,9 +1170,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ "proc-macro2", ] @@ -1115,7 +1183,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1124,7 +1192,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1140,9 +1208,21 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.4" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d3daa6976cffb758ec878f108ba0e062a45b2d6ca3a2cca965338855476caf" dependencies = [ "aho-corasick", "memchr", @@ -1151,9 +1231,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846" [[package]] name = "reqwest" @@ -1213,24 +1293,43 @@ dependencies = [ ] [[package]] -name = "rustix" -version = "0.37.20" +name = "rustc-demangle" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustix" +version = "0.37.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno", "io-lifetimes", "libc", - "linux-raw-sys", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac5ffa1efe7548069688cd7028f32591853cd7b5b756d41bcffd2353e4fc75b4" +dependencies = [ + "bitflags 2.3.3", + "errno", + "libc", + "linux-raw-sys 0.4.3", "windows-sys 0.48.0", ] [[package]] name = "rustls" -version = "0.21.2" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e32ca28af694bc1bbf399c33a516dbdf1c90090b8ab23c2bc24f834aa2247f5f" +checksum = "b19faa85ecb5197342b54f987b142fb3e30d0c90da40f80ef4fa9a726e6676ed" dependencies = [ "log", "ring", @@ -1240,18 +1339,18 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ "base64", ] [[package]] name = "rustls-webpki" -version = "0.100.1" +version = "0.101.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +checksum = "15f36a6828982f422756984e47912a7a51dcbc2a197aa791158f8ca61cd8204e" dependencies = [ "ring", "untrusted", @@ -1259,9 +1358,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" [[package]] name = "sanitize-filename" @@ -1285,18 +1384,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.164" +version = "1.0.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "7daf513456463b42aa1d94cff7e0c24d682b429f020b9afa4f5ba5c40a22b237" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "b69b106b68bc8054f0e974e70d19984040f8a5cf9215ca82626ea4853f82c4b9" dependencies = [ "proc-macro2", "quote", @@ -1305,9 +1404,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.97" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" +checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" dependencies = [ "itoa", "ryu", @@ -1425,9 +1524,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.18" +version = "2.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" dependencies = [ "proc-macro2", "quote", @@ -1454,24 +1553,24 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix", + "rustix 0.37.23", "windows-sys 0.48.0", ] [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" dependencies = [ "proc-macro2", "quote", @@ -1533,11 +1632,12 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.2" +version = "1.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" dependencies = [ "autocfg", + "backtrace", "bytes", "libc", "mio", @@ -1641,9 +1741,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" [[package]] name = "unicode-normalization" @@ -1807,9 +1907,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.23.1" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" +checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" dependencies = [ "rustls-webpki", ] @@ -1842,7 +1942,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.1", ] [[package]] @@ -1860,7 +1960,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.1", ] [[package]] @@ -1880,9 +1980,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ "windows_aarch64_gnullvm 0.48.0", "windows_aarch64_msvc 0.48.0", diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 27e3846..2ba5322 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -9,7 +9,7 @@ anyhow = "1.0" async-trait = "0.1" clap = { version = "4.3", features = ["derive", "string"] } chrono = "0.4" -crunchyroll-rs = { version = "0.3.7", features = ["dash-stream"] } +crunchyroll-rs = { version = "0.4.0", features = ["dash-stream"] } ctrlc = "3.4" dialoguer = { version = "0.10", default-features = false } dirs = "5.0" @@ -18,8 +18,8 @@ fs2 = "0.4" indicatif = "0.17" lazy_static = "1.4" log = { version = "0.4", features = ["std"] } -num_cpus = "1.15" -regex = "1.8" +num_cpus = "1.16" +regex = "1.9" reqwest = { version = "0.11", default-features = false, features = ["socks"] } sanitize-filename = "0.4" serde = "1.0" @@ -27,7 +27,7 @@ serde_json = "1.0" serde_plain = "1.0" shlex = "1.1" tempfile = "3.6" -tokio = { version = "1.28", features = ["macros", "rt-multi-thread", "time"] } +tokio = { version = "1.29", features = ["macros", "rt-multi-thread", "time"] } sys-locale = "0.3" [build-dependencies] diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index 982aa17..fbfb409 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -264,13 +264,15 @@ async fn crunchyroll_session(cli: &mut Cli) -> Result { lang }; - let mut client_builder = CrunchyrollBuilder::predefined_client_builder(); - if let Some(proxy) = &cli.proxy { - client_builder = client_builder.proxy(proxy.clone()) - } - + let proxy = cli.proxy.clone(); let mut builder = Crunchyroll::builder() - .client(client_builder.build()?) + .client_builder(move || { + let mut client_builder = CrunchyrollBuilder::predefined_client_builder(); + if let Some(proxy) = &proxy { + client_builder = client_builder.proxy(proxy.clone()) + } + client_builder + }) .locale(locale) .stabilization_locales(cli.experimental_fixes) .stabilization_season_number(cli.experimental_fixes); From 49de7bbba93f96968ecb9d009d44499e8b930bfc Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 12 Jul 2023 21:15:01 +0200 Subject: [PATCH 044/272] Add progress indicator for subtitle download --- crunchy-cli-core/src/utils/download.rs | 67 ++++++++++++++++++-------- crunchy-cli-core/src/utils/log.rs | 2 +- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index 1e1b207..f50570a 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -204,21 +204,50 @@ impl Downloader { }, }) } - let len = get_video_length(&video_path)?; - for (subtitle, not_cc) in format.subtitles.iter() { - let subtitle_path = self.download_subtitle(subtitle.clone(), len).await?; - let mut subtitle_title = subtitle.locale.to_human_readable(); - if !not_cc { - subtitle_title += " (CC)" + if !format.subtitles.is_empty() { + #[cfg(not(windows))] + let pb = ProgressBar::new_spinner() + .with_style( + ProgressStyle::with_template( + format!( + ":: {:<1$} {{msg}} {{spinner}}", + "Downloading subtitles", fmt_space + ) + .as_str(), + ) + .unwrap() + .tick_strings(&["—", "\\", "|", "/", ""]), + ) + .with_finish(ProgressFinish::Abandon); + pb.enable_steady_tick(Duration::from_millis(100)); + + let len = get_video_length(&video_path)?; + for (subtitle, not_cc) in format.subtitles.iter() { + let mut progress_message = pb.message(); + if !progress_message.is_empty() { + progress_message += ", " + } + progress_message += &subtitle.locale.to_string(); + let mut subtitle_title = subtitle.locale.to_human_readable(); + + if !not_cc { + progress_message += " (CC)"; + subtitle_title += " (CC)" + } + if i != 0 { + progress_message += &format!(" [Video: #{}]", i + 1); + subtitle_title += &format!(" [Video: #{}]", i + 1) + } + + pb.set_message(progress_message); + + let subtitle_path = self.download_subtitle(subtitle.clone(), len).await?; + subtitles.push(FFmpegMeta { + path: subtitle_path, + language: subtitle.locale.clone(), + title: subtitle_title, + }) } - if i != 0 { - subtitle_title += &format!(" [Video: #{}]", i + 1) - } - subtitles.push(FFmpegMeta { - path: subtitle_path, - language: subtitle.locale.clone(), - title: subtitle_title, - }) } videos.push(FFmpegMeta { path: video_path, @@ -454,7 +483,7 @@ impl Downloader { let tempfile = tempfile(".mp4")?; let (mut file, path) = tempfile.into_parts(); - download_segments(ctx, &mut file, Some(message), variant_data).await?; + download_segments(ctx, &mut file, message, variant_data).await?; Ok(path) } @@ -468,7 +497,7 @@ impl Downloader { let tempfile = tempfile(".m4a")?; let (mut file, path) = tempfile.into_parts(); - download_segments(ctx, &mut file, Some(message), variant_data).await?; + download_segments(ctx, &mut file, message, variant_data).await?; Ok(path) } @@ -494,7 +523,7 @@ impl Downloader { pub async fn download_segments( ctx: &Context, writer: &mut impl Write, - message: Option, + message: String, variant_data: &VariantData, ) -> Result<()> { let segments = variant_data.segments().await?; @@ -509,12 +538,12 @@ pub async fn download_segments( let progress = ProgressBar::new(estimated_file_size) .with_style( ProgressStyle::with_template( - ":: {msg}{bytes:>10} {bytes_per_sec:>12} [{wide_bar}] {percent:>3}%", + ":: {msg} {bytes:>10} {bytes_per_sec:>12} [{wide_bar}] {percent:>3}%", ) .unwrap() .progress_chars("##-"), ) - .with_message(message.map(|m| m + " ").unwrap_or_default()) + .with_message(message) .with_finish(ProgressFinish::Abandon); Some(progress) } else { diff --git a/crunchy-cli-core/src/utils/log.rs b/crunchy-cli-core/src/utils/log.rs index c74b73d..6650e58 100644 --- a/crunchy-cli-core/src/utils/log.rs +++ b/crunchy-cli-core/src/utils/log.rs @@ -169,7 +169,7 @@ impl CliLogger { let finish_str = "✔"; #[cfg(windows)] // windows does not support all unicode characters by default in their consoles, so - // we're using this (square root?) symbol instead. microsoft. + // we're using this (square root) symbol instead. microsoft. let finish_str = "√"; let pb = ProgressBar::new_spinner(); From 513353890da7c0b8494ccdfcebf41b87c8d1e59b Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 12 Jul 2023 21:34:49 +0200 Subject: [PATCH 045/272] Respect debug output when showing subtitle download spinner --- crunchy-cli-core/src/utils/download.rs | 61 ++++++++++++++++---------- 1 file changed, 39 insertions(+), 22 deletions(-) diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index f50570a..4531c69 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -205,43 +205,60 @@ impl Downloader { }) } if !format.subtitles.is_empty() { - #[cfg(not(windows))] - let pb = ProgressBar::new_spinner() - .with_style( - ProgressStyle::with_template( - format!( - ":: {:<1$} {{msg}} {{spinner}}", - "Downloading subtitles", fmt_space + let progress_spinner = if log::max_level() == LevelFilter::Info { + let progress_spinner = ProgressBar::new_spinner() + .with_style( + ProgressStyle::with_template( + format!( + ":: {:<1$} {{msg}} {{spinner}}", + "Downloading subtitles", fmt_space + ) + .as_str(), ) - .as_str(), + .unwrap() + .tick_strings(&["—", "\\", "|", "/", ""]), ) - .unwrap() - .tick_strings(&["—", "\\", "|", "/", ""]), - ) - .with_finish(ProgressFinish::Abandon); - pb.enable_steady_tick(Duration::from_millis(100)); + .with_finish(ProgressFinish::Abandon); + progress_spinner.enable_steady_tick(Duration::from_millis(100)); + Some(progress_spinner) + } else { + None + }; let len = get_video_length(&video_path)?; for (subtitle, not_cc) in format.subtitles.iter() { - let mut progress_message = pb.message(); - if !progress_message.is_empty() { - progress_message += ", " + if let Some(pb) = &progress_spinner { + let mut progress_message = pb.message(); + if !progress_message.is_empty() { + progress_message += ", " + } + progress_message += &subtitle.locale.to_string(); + if !not_cc { + progress_message += " (CC)"; + } + if i != 0 { + progress_message += &format!(" [Video: #{}]", i + 1); + } + pb.set_message(progress_message) } - progress_message += &subtitle.locale.to_string(); - let mut subtitle_title = subtitle.locale.to_human_readable(); + let mut subtitle_title = subtitle.locale.to_human_readable(); if !not_cc { - progress_message += " (CC)"; subtitle_title += " (CC)" } if i != 0 { - progress_message += &format!(" [Video: #{}]", i + 1); subtitle_title += &format!(" [Video: #{}]", i + 1) } - pb.set_message(progress_message); - let subtitle_path = self.download_subtitle(subtitle.clone(), len).await?; + debug!( + "Downloaded {} subtitles{}{}", + subtitle.locale, + (!not_cc).then_some(" (cc)").unwrap_or_default(), + (i != 0) + .then_some(format!(" for video {}", i)) + .unwrap_or_default() + ); subtitles.push(FFmpegMeta { path: subtitle_path, language: subtitle.locale.clone(), From 9ad27102fc14a0044fd2ded48453e831b3369655 Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 12 Jul 2023 21:59:41 +0200 Subject: [PATCH 046/272] Fix missing identifier on newer simulcast titles (#227) --- crunchy-cli-core/src/utils/format.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index 0b0f46e..d975042 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -44,7 +44,18 @@ impl SingleFormat { relative_episode_number: Option, ) -> Self { Self { - identifier: episode.identifier.clone(), + identifier: if episode.identifier.is_empty() { + // crunchyroll sometimes leafs the identifier field empty so we have to build it + // ourself. it's not 100% save that the identifier which is built here is the same + // as if crunchyroll would deliver it (because the variables used here may also be + // wrong delivered by crunchy), but it's the best thing i can do at the moment + format!( + "{}|S{}|E{}", + episode.series_id, episode.season_number, episode.sequence_number + ) + } else { + episode.identifier.clone() + }, title: episode.title.clone(), description: episode.description.clone(), audio: episode.audio_locale.clone(), From 850aa7a969768992820d8a9142ed01ccb27adec8 Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 13 Jul 2023 13:51:02 +0200 Subject: [PATCH 047/272] Use config file to store sessions --- Cargo.lock | 82 ++++++++++++++++++++++++++- crunchy-cli-core/Cargo.toml | 1 + crunchy-cli-core/src/lib.rs | 44 +++++++------- crunchy-cli-core/src/login/command.rs | 33 +++-------- crunchy-cli-core/src/login/mod.rs | 2 +- crunchy-cli-core/src/utils/config.rs | 59 +++++++++++++++++++ crunchy-cli-core/src/utils/context.rs | 2 + crunchy-cli-core/src/utils/mod.rs | 1 + 8 files changed, 177 insertions(+), 47 deletions(-) create mode 100644 crunchy-cli-core/src/utils/config.rs diff --git a/Cargo.lock b/Cargo.lock index cc02df5..7468e73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -397,6 +397,7 @@ dependencies = [ "sys-locale", "tempfile", "tokio", + "toml", ] [[package]] @@ -578,6 +579,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "equivalent" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" + [[package]] name = "errno" version = "0.3.1" @@ -730,7 +737,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.3", "slab", "tokio", "tokio-util", @@ -743,6 +750,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "heck" version = "0.4.1" @@ -900,10 +913,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", "serde", ] +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + [[package]] name = "indicatif" version = "0.17.5" @@ -1459,6 +1482,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1480,7 +1512,7 @@ dependencies = [ "base64", "chrono", "hex", - "indexmap", + "indexmap 1.9.3", "serde", "serde_json", "serde_with_macros", @@ -1732,6 +1764,41 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +dependencies = [ + "indexmap 2.0.0", + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" +dependencies = [ + "indexmap 2.0.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower-service" version = "0.3.2" @@ -2114,6 +2181,15 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "winnow" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.10.1" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 2ba5322..32c2ec4 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -27,6 +27,7 @@ serde_json = "1.0" serde_plain = "1.0" shlex = "1.1" tempfile = "3.6" +toml = { version = "0.7", features = ["display", "parse", "preserve_order"] } tokio = { version = "1.29", features = ["macros", "rt-multi-thread", "time"] } sys-locale = "0.3" diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index fbfb409..303d38e 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -17,6 +17,7 @@ mod login; mod search; mod utils; +use crate::utils::config::{Auth, Config}; pub use archive::Archive; use dialoguer::console::Term; pub use download::Download; @@ -136,8 +137,20 @@ pub async fn cli_entrypoint() { } Command::Login(login) => { if login.remove { - if let Some(session_file) = login::session_file_path() { - let _ = fs::remove_file(session_file); + match Config::load() { + Ok(config) => { + if let Some(mut c) = config { + c.auth = None; + if let Err(e) = c.write() { + error!("{}", e); + std::process::exit(1) + } + } + } + Err(e) => { + error!("{}", e); + std::process::exit(1) + } } return; } else { @@ -226,11 +239,12 @@ async fn execute_executor(executor: impl Execute, ctx: Context) { } async fn create_ctx(cli: &mut Cli) -> Result { - let crunchy = crunchyroll_session(cli).await?; - Ok(Context { crunchy }) + let mut config = Config::load()?.unwrap_or_default(); + let crunchy = crunchyroll_session(cli, &mut config).await?; + Ok(Context { crunchy, config }) } -async fn crunchyroll_session(cli: &mut Cli) -> Result { +async fn crunchyroll_session(cli: &mut Cli, config: &mut Config) -> Result { let supported_langs = vec![ Locale::ar_ME, Locale::de_DE, @@ -293,20 +307,12 @@ async fn crunchyroll_session(cli: &mut Cli) -> Result { let progress_handler = progress!("Logging in"); if root_login_methods_count + login_login_methods_count == 0 { - if let Some(login_file_path) = login::session_file_path() { - if login_file_path.exists() { - let session = fs::read_to_string(login_file_path)?; - if let Some((token_type, token)) = session.split_once(':') { - match token_type { - "refresh_token" => { - return Ok(builder.login_with_refresh_token(token).await?) - } - "etp_rt" => return Ok(builder.login_with_etp_rt(token).await?), - _ => (), - } - } - bail!("Could not read stored session ('{}')", session) - } + if let Some(auth) = &config.auth { + return match auth { + Auth::RefreshToken { token } => Ok(builder.login_with_refresh_token(token).await?), + Auth::EtpRt { token } => Ok(builder.login_with_etp_rt(token).await?), + Auth::Anonymous => Ok(builder.login_anonymously().await?), + }; } bail!("Please use a login method ('--credentials', '--etp-rt' or '--anonymous')") } else if root_login_methods_count + login_login_methods_count > 1 { diff --git a/crunchy-cli-core/src/login/command.rs b/crunchy-cli-core/src/login/command.rs index ab16e06..076e1b7 100644 --- a/crunchy-cli-core/src/login/command.rs +++ b/crunchy-cli-core/src/login/command.rs @@ -1,11 +1,9 @@ +use crate::utils::config::Auth; use crate::utils::context::Context; use crate::Execute; -use anyhow::bail; use anyhow::Result; use clap::Parser; use crunchyroll_rs::crunchyroll::SessionToken; -use std::fs; -use std::path::PathBuf; #[derive(Debug, clap::Parser)] #[clap(about = "Save your login credentials persistent on disk")] @@ -19,23 +17,14 @@ pub struct Login { #[async_trait::async_trait(?Send)] impl Execute for Login { - async fn execute(self, ctx: Context) -> Result<()> { - if let Some(login_file_path) = session_file_path() { - fs::create_dir_all(login_file_path.parent().unwrap())?; - - match ctx.crunchy.session_token().await { - SessionToken::RefreshToken(refresh_token) => Ok(fs::write( - login_file_path, - format!("refresh_token:{}", refresh_token), - )?), - SessionToken::EtpRt(etp_rt) => { - Ok(fs::write(login_file_path, format!("etp_rt:{}", etp_rt))?) - } - SessionToken::Anonymous => bail!("Anonymous login cannot be saved"), - } - } else { - bail!("Cannot find config path") - } + async fn execute(self, mut ctx: Context) -> Result<()> { + let auth = match ctx.crunchy.session_token().await { + SessionToken::RefreshToken(token) => Auth::RefreshToken { token }, + SessionToken::EtpRt(token) => Auth::EtpRt { token }, + SessionToken::Anonymous => Auth::Anonymous, + }; + ctx.config.auth = Some(auth); + Ok(ctx.config.write()?) } } @@ -56,7 +45,3 @@ pub struct LoginMethod { #[arg(long, default_value_t = false)] pub anonymous: bool, } - -pub fn session_file_path() -> Option { - dirs::config_dir().map(|config_dir| config_dir.join("crunchy-cli").join("session")) -} diff --git a/crunchy-cli-core/src/login/mod.rs b/crunchy-cli-core/src/login/mod.rs index 8c1220a..8c79d61 100644 --- a/crunchy-cli-core/src/login/mod.rs +++ b/crunchy-cli-core/src/login/mod.rs @@ -1,3 +1,3 @@ mod command; -pub use command::{session_file_path, Login, LoginMethod}; +pub use command::{Login, LoginMethod}; diff --git a/crunchy-cli-core/src/utils/config.rs b/crunchy-cli-core/src/utils/config.rs new file mode 100644 index 0000000..3206ca8 --- /dev/null +++ b/crunchy-cli-core/src/utils/config.rs @@ -0,0 +1,59 @@ +use anyhow::{bail, Result}; +use serde::{Deserialize, Serialize}; +use std::fs; +use std::path::PathBuf; + +#[derive(Deserialize, Serialize)] +#[serde(rename_all = "snake_case")] +#[serde(tag = "method")] +pub enum Auth { + RefreshToken { token: String }, + EtpRt { token: String }, + Anonymous, +} + +#[derive(Default, Deserialize, Serialize)] +pub struct Config { + pub auth: Option, +} + +impl Config { + pub fn load() -> Result> { + let path = Config::assert_config_file_path(true)?; + + if let Some(p) = path { + if p.exists() { + let content = fs::read_to_string(p)?; + return Ok(Some(toml::from_str(&content)?)); + } + } + Ok(None) + } + + pub fn write(&self) -> Result<()> { + let path = Config::assert_config_file_path(false)?.unwrap(); + Ok(fs::write(path, toml::to_string(self)?)?) + } + + pub fn config_file_path() -> Option { + dirs::config_dir().map(|config_dir| config_dir.join("crunchy-cli.conf")) + } + + fn assert_config_file_path(ignore_non_existing_config_dir: bool) -> Result> { + let Some(path) = Config::config_file_path() else { + if ignore_non_existing_config_dir { + return Ok(None) + } + bail!("Cannot find config directory") + }; + + if path.exists() && path.is_dir() { + bail!( + "Config path ({}) is a directory (must be a normal file)", + path.to_string_lossy() + ) + } + + Ok(Some(path)) + } +} diff --git a/crunchy-cli-core/src/utils/context.rs b/crunchy-cli-core/src/utils/context.rs index f8df024..3e9af73 100644 --- a/crunchy-cli-core/src/utils/context.rs +++ b/crunchy-cli-core/src/utils/context.rs @@ -1,5 +1,7 @@ +use crate::utils::config::Config; use crunchyroll_rs::Crunchyroll; pub struct Context { pub crunchy: Crunchyroll, + pub config: Config, } diff --git a/crunchy-cli-core/src/utils/mod.rs b/crunchy-cli-core/src/utils/mod.rs index d46cc33..510eeec 100644 --- a/crunchy-cli-core/src/utils/mod.rs +++ b/crunchy-cli-core/src/utils/mod.rs @@ -1,4 +1,5 @@ pub mod clap; +pub mod config; pub mod context; pub mod download; pub mod ffmpeg; From 6b768879786047d4bdc46efb4c658c297c1c2327 Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 13 Jul 2023 14:08:11 +0200 Subject: [PATCH 048/272] Fix error when using etp-rt or anonymous flag after login command --- crunchy-cli-core/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index 303d38e..8595f62 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -335,9 +335,9 @@ async fn crunchyroll_session(cli: &mut Cli, config: &mut Config) -> Result Date: Thu, 13 Jul 2023 14:09:18 +0200 Subject: [PATCH 049/272] Add info output that login command saved the session --- crunchy-cli-core/src/login/command.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/login/command.rs b/crunchy-cli-core/src/login/command.rs index 076e1b7..f7994e5 100644 --- a/crunchy-cli-core/src/login/command.rs +++ b/crunchy-cli-core/src/login/command.rs @@ -4,6 +4,7 @@ use crate::Execute; use anyhow::Result; use clap::Parser; use crunchyroll_rs::crunchyroll::SessionToken; +use log::info; #[derive(Debug, clap::Parser)] #[clap(about = "Save your login credentials persistent on disk")] @@ -24,7 +25,11 @@ impl Execute for Login { SessionToken::Anonymous => Auth::Anonymous, }; ctx.config.auth = Some(auth); - Ok(ctx.config.write()?) + ctx.config.write()?; + + info!("Saved login"); + + Ok(()) } } From dd2033d32311bb6f8243b1d5f4f43dc3d017614a Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 13 Jul 2023 16:07:05 +0200 Subject: [PATCH 050/272] Revert "Use config file to store sessions" This reverts commit 850aa7a9 --- Cargo.lock | 82 +-------------------------- crunchy-cli-core/Cargo.toml | 1 - crunchy-cli-core/src/lib.rs | 44 +++++++------- crunchy-cli-core/src/login/command.rs | 36 ++++++++---- crunchy-cli-core/src/login/mod.rs | 2 +- crunchy-cli-core/src/utils/config.rs | 59 ------------------- crunchy-cli-core/src/utils/context.rs | 2 - crunchy-cli-core/src/utils/mod.rs | 1 - 8 files changed, 48 insertions(+), 179 deletions(-) delete mode 100644 crunchy-cli-core/src/utils/config.rs diff --git a/Cargo.lock b/Cargo.lock index 7468e73..cc02df5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -397,7 +397,6 @@ dependencies = [ "sys-locale", "tempfile", "tokio", - "toml", ] [[package]] @@ -579,12 +578,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "equivalent" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" - [[package]] name = "errno" version = "0.3.1" @@ -737,7 +730,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap", "slab", "tokio", "tokio-util", @@ -750,12 +743,6 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -[[package]] -name = "hashbrown" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" - [[package]] name = "heck" version = "0.4.1" @@ -913,20 +900,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown 0.12.3", + "hashbrown", "serde", ] -[[package]] -name = "indexmap" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" -dependencies = [ - "equivalent", - "hashbrown 0.14.0", -] - [[package]] name = "indicatif" version = "0.17.5" @@ -1482,15 +1459,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_spanned" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" -dependencies = [ - "serde", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1512,7 +1480,7 @@ dependencies = [ "base64", "chrono", "hex", - "indexmap 1.9.3", + "indexmap", "serde", "serde_json", "serde_with_macros", @@ -1764,41 +1732,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "toml" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" -dependencies = [ - "indexmap 2.0.0", - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.19.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" -dependencies = [ - "indexmap 2.0.0", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", -] - [[package]] name = "tower-service" version = "0.3.2" @@ -2181,15 +2114,6 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" -[[package]] -name = "winnow" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529" -dependencies = [ - "memchr", -] - [[package]] name = "winreg" version = "0.10.1" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 32c2ec4..2ba5322 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -27,7 +27,6 @@ serde_json = "1.0" serde_plain = "1.0" shlex = "1.1" tempfile = "3.6" -toml = { version = "0.7", features = ["display", "parse", "preserve_order"] } tokio = { version = "1.29", features = ["macros", "rt-multi-thread", "time"] } sys-locale = "0.3" diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index 8595f62..c85df85 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -17,7 +17,6 @@ mod login; mod search; mod utils; -use crate::utils::config::{Auth, Config}; pub use archive::Archive; use dialoguer::console::Term; pub use download::Download; @@ -137,20 +136,8 @@ pub async fn cli_entrypoint() { } Command::Login(login) => { if login.remove { - match Config::load() { - Ok(config) => { - if let Some(mut c) = config { - c.auth = None; - if let Err(e) = c.write() { - error!("{}", e); - std::process::exit(1) - } - } - } - Err(e) => { - error!("{}", e); - std::process::exit(1) - } + if let Some(session_file) = login::session_file_path() { + let _ = fs::remove_file(session_file); } return; } else { @@ -239,12 +226,11 @@ async fn execute_executor(executor: impl Execute, ctx: Context) { } async fn create_ctx(cli: &mut Cli) -> Result { - let mut config = Config::load()?.unwrap_or_default(); - let crunchy = crunchyroll_session(cli, &mut config).await?; - Ok(Context { crunchy, config }) + let crunchy = crunchyroll_session(cli).await?; + Ok(Context { crunchy }) } -async fn crunchyroll_session(cli: &mut Cli, config: &mut Config) -> Result { +async fn crunchyroll_session(cli: &mut Cli) -> Result { let supported_langs = vec![ Locale::ar_ME, Locale::de_DE, @@ -307,12 +293,20 @@ async fn crunchyroll_session(cli: &mut Cli, config: &mut Config) -> Result Ok(builder.login_with_refresh_token(token).await?), - Auth::EtpRt { token } => Ok(builder.login_with_etp_rt(token).await?), - Auth::Anonymous => Ok(builder.login_anonymously().await?), - }; + if let Some(login_file_path) = login::session_file_path() { + if login_file_path.exists() { + let session = fs::read_to_string(login_file_path)?; + if let Some((token_type, token)) = session.split_once(':') { + match token_type { + "refresh_token" => { + return Ok(builder.login_with_refresh_token(token).await?) + } + "etp_rt" => return Ok(builder.login_with_etp_rt(token).await?), + _ => (), + } + } + bail!("Could not read stored session ('{}')", session) + } } bail!("Please use a login method ('--credentials', '--etp-rt' or '--anonymous')") } else if root_login_methods_count + login_login_methods_count > 1 { diff --git a/crunchy-cli-core/src/login/command.rs b/crunchy-cli-core/src/login/command.rs index f7994e5..f5099d7 100644 --- a/crunchy-cli-core/src/login/command.rs +++ b/crunchy-cli-core/src/login/command.rs @@ -1,10 +1,12 @@ -use crate::utils::config::Auth; use crate::utils::context::Context; use crate::Execute; +use anyhow::bail; use anyhow::Result; use clap::Parser; use crunchyroll_rs::crunchyroll::SessionToken; use log::info; +use std::fs; +use std::path::PathBuf; #[derive(Debug, clap::Parser)] #[clap(about = "Save your login credentials persistent on disk")] @@ -18,18 +20,26 @@ pub struct Login { #[async_trait::async_trait(?Send)] impl Execute for Login { - async fn execute(self, mut ctx: Context) -> Result<()> { - let auth = match ctx.crunchy.session_token().await { - SessionToken::RefreshToken(token) => Auth::RefreshToken { token }, - SessionToken::EtpRt(token) => Auth::EtpRt { token }, - SessionToken::Anonymous => Auth::Anonymous, - }; - ctx.config.auth = Some(auth); - ctx.config.write()?; + async fn execute(self, ctx: Context) -> Result<()> { + if let Some(login_file_path) = session_file_path() { + fs::create_dir_all(login_file_path.parent().unwrap())?; - info!("Saved login"); + match ctx.crunchy.session_token().await { + SessionToken::RefreshToken(refresh_token) => { + fs::write(login_file_path, format!("refresh_token:{}", refresh_token))? + } + SessionToken::EtpRt(etp_rt) => { + fs::write(login_file_path, format!("etp_rt:{}", etp_rt))? + } + SessionToken::Anonymous => bail!("Anonymous login cannot be saved"), + } - Ok(()) + info!("Saved login"); + + Ok(()) + } else { + bail!("Cannot find config path") + } } } @@ -50,3 +60,7 @@ pub struct LoginMethod { #[arg(long, default_value_t = false)] pub anonymous: bool, } + +pub fn session_file_path() -> Option { + dirs::config_dir().map(|config_dir| config_dir.join("crunchy-cli").join("session")) +} diff --git a/crunchy-cli-core/src/login/mod.rs b/crunchy-cli-core/src/login/mod.rs index 8c79d61..8c1220a 100644 --- a/crunchy-cli-core/src/login/mod.rs +++ b/crunchy-cli-core/src/login/mod.rs @@ -1,3 +1,3 @@ mod command; -pub use command::{Login, LoginMethod}; +pub use command::{session_file_path, Login, LoginMethod}; diff --git a/crunchy-cli-core/src/utils/config.rs b/crunchy-cli-core/src/utils/config.rs deleted file mode 100644 index 3206ca8..0000000 --- a/crunchy-cli-core/src/utils/config.rs +++ /dev/null @@ -1,59 +0,0 @@ -use anyhow::{bail, Result}; -use serde::{Deserialize, Serialize}; -use std::fs; -use std::path::PathBuf; - -#[derive(Deserialize, Serialize)] -#[serde(rename_all = "snake_case")] -#[serde(tag = "method")] -pub enum Auth { - RefreshToken { token: String }, - EtpRt { token: String }, - Anonymous, -} - -#[derive(Default, Deserialize, Serialize)] -pub struct Config { - pub auth: Option, -} - -impl Config { - pub fn load() -> Result> { - let path = Config::assert_config_file_path(true)?; - - if let Some(p) = path { - if p.exists() { - let content = fs::read_to_string(p)?; - return Ok(Some(toml::from_str(&content)?)); - } - } - Ok(None) - } - - pub fn write(&self) -> Result<()> { - let path = Config::assert_config_file_path(false)?.unwrap(); - Ok(fs::write(path, toml::to_string(self)?)?) - } - - pub fn config_file_path() -> Option { - dirs::config_dir().map(|config_dir| config_dir.join("crunchy-cli.conf")) - } - - fn assert_config_file_path(ignore_non_existing_config_dir: bool) -> Result> { - let Some(path) = Config::config_file_path() else { - if ignore_non_existing_config_dir { - return Ok(None) - } - bail!("Cannot find config directory") - }; - - if path.exists() && path.is_dir() { - bail!( - "Config path ({}) is a directory (must be a normal file)", - path.to_string_lossy() - ) - } - - Ok(Some(path)) - } -} diff --git a/crunchy-cli-core/src/utils/context.rs b/crunchy-cli-core/src/utils/context.rs index 3e9af73..f8df024 100644 --- a/crunchy-cli-core/src/utils/context.rs +++ b/crunchy-cli-core/src/utils/context.rs @@ -1,7 +1,5 @@ -use crate::utils::config::Config; use crunchyroll_rs::Crunchyroll; pub struct Context { pub crunchy: Crunchyroll, - pub config: Config, } diff --git a/crunchy-cli-core/src/utils/mod.rs b/crunchy-cli-core/src/utils/mod.rs index 510eeec..d46cc33 100644 --- a/crunchy-cli-core/src/utils/mod.rs +++ b/crunchy-cli-core/src/utils/mod.rs @@ -1,5 +1,4 @@ pub mod clap; -pub mod config; pub mod context; pub mod download; pub mod ffmpeg; From 566422cb06255c3af85ab3c3ac204d26f42633f0 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 17 Jul 2023 14:32:10 +0200 Subject: [PATCH 051/272] Update dependencies --- Cargo.lock | 112 ++++++++++++++++++------------------ crunchy-cli-core/Cargo.lock | 112 ++++++++++++++++++------------------ crunchy-cli-core/Cargo.toml | 2 +- crunchy-cli-core/src/lib.rs | 17 +++--- 4 files changed, 121 insertions(+), 122 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc02df5..042c0f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -103,9 +103,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" [[package]] name = "async-trait" @@ -237,9 +237,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.11" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1640e5cc7fb47dbb8338fd471b105e7ed6c3cb2aeb00c2e067127ffd3764a05d" +checksum = "3eab9e8ceb9afdade1ab3f0fd8dbce5b1b2f468ad653baf10e771781b2b67b73" dependencies = [ "clap_builder", "clap_derive", @@ -248,9 +248,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.11" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c59138d527eeaf9b53f35a77fcc1fad9d883116070c63d5de1c7dc7b00c72b" +checksum = "9f2763db829349bf00cfc06251268865ed4363b93a943174f638daf3ecdba2cd" dependencies = [ "anstream", "anstyle", @@ -269,9 +269,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.3.2" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" dependencies = [ "heck", "proc-macro2", @@ -321,7 +321,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.22", + "time 0.3.23", "version_check", ] @@ -338,7 +338,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "time 0.3.22", + "time 0.3.23", "url", ] @@ -401,9 +401,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be9aa4589c26829667cc6f32f7238b93cdc0c6c130b295b3714df7ea6c28ef1" +checksum = "a1fc76ad1ab97992a987dd2a5fadfa4e90fc69d337704f42b7eeb30f7fda1eb1" dependencies = [ "aes", "async-trait", @@ -428,9 +428,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs-internal" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b718f70c2825f2310e2301295a3a66f1723bbdd39f6cfbe6148df00556e9c75e" +checksum = "2f9581dc7276f1c327dcaa91fa6d3b3f09c46018dc5a0d7815be3f8027780a07" dependencies = [ "darling", "quote", @@ -459,9 +459,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", @@ -469,9 +469,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", @@ -483,9 +483,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", @@ -494,9 +494,9 @@ dependencies = [ [[package]] name = "dash-mpd" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef11db94edb7974469f90fe64eaa95b3a2b36fdd5f72420717f7ee56a1922988" +checksum = "58b55cd4a2bd4b541906e88adbd2242bda9a697517f638c844fa47fb56fe2f17" dependencies = [ "base64", "base64-serde", @@ -960,7 +960,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.3", + "rustix 0.38.4", "windows-sys 0.48.0", ] @@ -975,9 +975,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" @@ -1160,15 +1160,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "portable-atomic" -version = "1.3.3" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794" +checksum = "edc55135a600d700580e406b4de0d59cb9ad25e344a3a091a97ded2622ec4ec6" [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -1201,9 +1201,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.29" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" dependencies = [ "proc-macro2", ] @@ -1251,9 +1251,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83d3daa6976cffb758ec878f108ba0e062a45b2d6ca3a2cca965338855476caf" +checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" dependencies = [ "aho-corasick", "memchr", @@ -1262,9 +1262,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "reqwest" @@ -1351,9 +1351,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.3" +version = "0.38.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac5ffa1efe7548069688cd7028f32591853cd7b5b756d41bcffd2353e4fc75b4" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" dependencies = [ "bitflags 2.3.3", "errno", @@ -1364,9 +1364,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.3" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b19faa85ecb5197342b54f987b142fb3e30d0c90da40f80ef4fa9a726e6676ed" +checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36" dependencies = [ "log", "ring", @@ -1395,9 +1395,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "sanitize-filename" @@ -1421,18 +1421,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.167" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daf513456463b42aa1d94cff7e0c24d682b429f020b9afa4f5ba5c40a22b237" +checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.167" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69b106b68bc8054f0e974e70d19984040f8a5cf9215ca82626ea4853f82c4b9" +checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" dependencies = [ "proc-macro2", "quote", @@ -1441,9 +1441,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.100" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" +checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" dependencies = [ "itoa", "ryu", @@ -1484,7 +1484,7 @@ dependencies = [ "serde", "serde_json", "serde_with_macros", - "time 0.3.22", + "time 0.3.23", ] [[package]] @@ -1561,9 +1561,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.23" +version = "2.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" +checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" dependencies = [ "proc-macro2", "quote", @@ -1627,9 +1627,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" dependencies = [ "itoa", "serde", @@ -1645,9 +1645,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" dependencies = [ "time-core", ] @@ -1778,9 +1778,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-normalization" diff --git a/crunchy-cli-core/Cargo.lock b/crunchy-cli-core/Cargo.lock index 5f9347b..f8e0970 100644 --- a/crunchy-cli-core/Cargo.lock +++ b/crunchy-cli-core/Cargo.lock @@ -103,9 +103,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" [[package]] name = "async-trait" @@ -237,9 +237,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.11" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1640e5cc7fb47dbb8338fd471b105e7ed6c3cb2aeb00c2e067127ffd3764a05d" +checksum = "3eab9e8ceb9afdade1ab3f0fd8dbce5b1b2f468ad653baf10e771781b2b67b73" dependencies = [ "clap_builder", "clap_derive", @@ -248,9 +248,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.11" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c59138d527eeaf9b53f35a77fcc1fad9d883116070c63d5de1c7dc7b00c72b" +checksum = "9f2763db829349bf00cfc06251268865ed4363b93a943174f638daf3ecdba2cd" dependencies = [ "anstream", "anstyle", @@ -260,9 +260,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.3.2" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" dependencies = [ "heck", "proc-macro2", @@ -302,7 +302,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.22", + "time 0.3.23", "version_check", ] @@ -319,7 +319,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "time 0.3.22", + "time 0.3.23", "url", ] @@ -370,9 +370,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be9aa4589c26829667cc6f32f7238b93cdc0c6c130b295b3714df7ea6c28ef1" +checksum = "a1fc76ad1ab97992a987dd2a5fadfa4e90fc69d337704f42b7eeb30f7fda1eb1" dependencies = [ "aes", "async-trait", @@ -397,9 +397,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs-internal" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b718f70c2825f2310e2301295a3a66f1723bbdd39f6cfbe6148df00556e9c75e" +checksum = "2f9581dc7276f1c327dcaa91fa6d3b3f09c46018dc5a0d7815be3f8027780a07" dependencies = [ "darling", "quote", @@ -428,9 +428,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", @@ -438,9 +438,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", @@ -452,9 +452,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", @@ -463,9 +463,9 @@ dependencies = [ [[package]] name = "dash-mpd" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef11db94edb7974469f90fe64eaa95b3a2b36fdd5f72420717f7ee56a1922988" +checksum = "58b55cd4a2bd4b541906e88adbd2242bda9a697517f638c844fa47fb56fe2f17" dependencies = [ "base64", "base64-serde", @@ -929,7 +929,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.3", + "rustix 0.38.4", "windows-sys 0.48.0", ] @@ -944,9 +944,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" @@ -1129,15 +1129,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "portable-atomic" -version = "1.3.3" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794" +checksum = "edc55135a600d700580e406b4de0d59cb9ad25e344a3a091a97ded2622ec4ec6" [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -1170,9 +1170,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.29" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" dependencies = [ "proc-macro2", ] @@ -1220,9 +1220,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83d3daa6976cffb758ec878f108ba0e062a45b2d6ca3a2cca965338855476caf" +checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" dependencies = [ "aho-corasick", "memchr", @@ -1231,9 +1231,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "reqwest" @@ -1314,9 +1314,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.3" +version = "0.38.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac5ffa1efe7548069688cd7028f32591853cd7b5b756d41bcffd2353e4fc75b4" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" dependencies = [ "bitflags 2.3.3", "errno", @@ -1327,9 +1327,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.3" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b19faa85ecb5197342b54f987b142fb3e30d0c90da40f80ef4fa9a726e6676ed" +checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36" dependencies = [ "log", "ring", @@ -1358,9 +1358,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "sanitize-filename" @@ -1384,18 +1384,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.167" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daf513456463b42aa1d94cff7e0c24d682b429f020b9afa4f5ba5c40a22b237" +checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.167" +version = "1.0.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69b106b68bc8054f0e974e70d19984040f8a5cf9215ca82626ea4853f82c4b9" +checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" dependencies = [ "proc-macro2", "quote", @@ -1404,9 +1404,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.100" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" +checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" dependencies = [ "itoa", "ryu", @@ -1447,7 +1447,7 @@ dependencies = [ "serde", "serde_json", "serde_with_macros", - "time 0.3.22", + "time 0.3.23", ] [[package]] @@ -1524,9 +1524,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.23" +version = "2.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" +checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" dependencies = [ "proc-macro2", "quote", @@ -1590,9 +1590,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" dependencies = [ "itoa", "serde", @@ -1608,9 +1608,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" dependencies = [ "time-core", ] @@ -1741,9 +1741,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-normalization" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 2ba5322..c35787e 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -9,7 +9,7 @@ anyhow = "1.0" async-trait = "0.1" clap = { version = "4.3", features = ["derive", "string"] } chrono = "0.4" -crunchyroll-rs = { version = "0.4.0", features = ["dash-stream"] } +crunchyroll-rs = { version = "0.5.0", features = ["dash-stream"] } ctrlc = "3.4" dialoguer = { version = "0.10", default-features = false } dirs = "5.0" diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index c85df85..2b11f81 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -264,22 +264,21 @@ async fn crunchyroll_session(cli: &mut Cli) -> Result { lang }; - let proxy = cli.proxy.clone(); let mut builder = Crunchyroll::builder() - .client_builder(move || { - let mut client_builder = CrunchyrollBuilder::predefined_client_builder(); - if let Some(proxy) = &proxy { - client_builder = client_builder.proxy(proxy.clone()) - } - client_builder - }) .locale(locale) .stabilization_locales(cli.experimental_fixes) .stabilization_season_number(cli.experimental_fixes); - if let Command::Download(download) = &cli.command { builder = builder.preferred_audio_locale(download.audio.clone()) } + if let Some(p) = &cli.proxy { + builder = builder.client( + CrunchyrollBuilder::predefined_client_builder() + .proxy(p.clone()) + .build() + .unwrap(), + ) + } let root_login_methods_count = cli.login_method.credentials.is_some() as u8 + cli.login_method.etp_rt.is_some() as u8 From 4ec9a0d309dab8904dc2fcc00b8d847eca153a88 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 17 Jul 2023 16:08:54 +0200 Subject: [PATCH 052/272] Add native-tls/openssl tls backend for linux --- Cargo.lock | 167 ++++++++++++++++++++++++++++++++++++ crunchy-cli-core/Cargo.toml | 6 ++ crunchy-cli-core/src/lib.rs | 35 +++++++- 3 files changed, 207 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 042c0f0..e0b4ab4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -342,6 +342,16 @@ dependencies = [ "url", ] +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -614,6 +624,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.0" @@ -833,6 +858,19 @@ dependencies = [ "tokio-rustls", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "iana-time-zone" version = "0.1.57" @@ -1072,6 +1110,24 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "nix" version = "0.26.2" @@ -1134,6 +1190,60 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "openssl" +version = "0.10.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-src" +version = "111.26.0+1.1.1u" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efc62c9f12b22b8f5208c23a7200a442b2e5999f8bdf80233852122b5a4f6f37" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -1158,6 +1268,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + [[package]] name = "portable-atomic" version = "1.4.1" @@ -1284,10 +1400,12 @@ dependencies = [ "http-body", "hyper", "hyper-rustls", + "hyper-tls", "ipnet", "js-sys", "log", "mime", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -1297,6 +1415,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "tokio", + "tokio-native-tls", "tokio-rustls", "tokio-socks", "tower-service", @@ -1409,6 +1528,15 @@ dependencies = [ "regex", ] +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "sct" version = "0.7.0" @@ -1419,6 +1547,29 @@ dependencies = [ "untrusted", ] +[[package]] +name = "security-framework" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.171" @@ -1696,6 +1847,16 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.24.1" @@ -1820,6 +1981,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index c35787e..5f8f4bc 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -30,5 +30,11 @@ tempfile = "3.6" tokio = { version = "1.29", features = ["macros", "rt-multi-thread", "time"] } sys-locale = "0.3" +[target.'cfg(target_os = "linux")'.dependencies] +reqwest = { version = "0.11", default-features = false, features = ["socks", "native-tls-alpn", "native-tls-vendored"] } + +[target.'cfg(not(target_os = "linux"))'.dependencies] +reqwest = { version = "0.11", default-features = false, features = ["socks"] } + [build-dependencies] chrono = "0.4" diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index 2b11f81..7d0fbfa 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -8,7 +8,7 @@ use crunchyroll_rs::crunchyroll::CrunchyrollBuilder; use crunchyroll_rs::error::CrunchyrollError; use crunchyroll_rs::{Crunchyroll, Locale}; use log::{debug, error, warn, LevelFilter}; -use reqwest::Proxy; +use reqwest::{Client, ClientBuilder, Proxy, StatusCode}; use std::{env, fs}; mod archive; @@ -264,8 +264,19 @@ async fn crunchyroll_session(cli: &mut Cli) -> Result { lang }; + let proxy = cli.proxy.clone(); let mut builder = Crunchyroll::builder() .locale(locale) + .client( + get_client(|| { + if let Some(p) = &proxy { + CrunchyrollBuilder::predefined_client_builder().proxy(p.clone()) + } else { + CrunchyrollBuilder::predefined_client_builder() + } + }) + .await?, + ) .stabilization_locales(cli.experimental_fixes) .stabilization_season_number(cli.experimental_fixes); if let Command::Download(download) = &cli.command { @@ -340,3 +351,25 @@ async fn crunchyroll_session(cli: &mut Cli) -> Result { Ok(crunchy) } + +#[cfg(target_os = "linux")] +async fn get_client ClientBuilder>(f: F) -> Result { + let client = f().build().unwrap(); + if client + .get("https://www.crunchyroll.com") + .send() + .await? + .status() + != StatusCode::FORBIDDEN + { + return Ok(client); + } + + debug!("rustls tls backend probably triggered the cloudflare bot check, using openssl instead"); + Ok(f().use_native_tls().build().unwrap()) +} + +#[cfg(not(target_os = "linux"))] +async fn get_client ClientBuilder>(f: F) -> Result { + Ok(f().build().unwrap()) +} From dc6bc0d9516e8d7bb19d1f8a02189987a4c53643 Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 20 Jul 2023 13:46:09 +0200 Subject: [PATCH 053/272] Add openssl tls backend for all platforms --- Cargo.lock | 18 +++- Cargo.toml | 6 ++ crunchy-cli-core/Cargo.lock | 179 ++++++++++++++++++++++++++++++++++++ crunchy-cli-core/Cargo.toml | 12 ++- crunchy-cli-core/src/lib.rs | 47 +++------- 5 files changed, 221 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e0b4ab4..34b7d0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -396,6 +396,7 @@ dependencies = [ "indicatif", "lazy_static", "log", + "native-tls 0.2.11 (git+https://github.com/crunchy-labs/rust-not-so-native-tls.git)", "num_cpus", "regex", "reqwest", @@ -866,7 +867,7 @@ checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", "hyper", - "native-tls", + "native-tls 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio", "tokio-native-tls", ] @@ -1128,6 +1129,17 @@ dependencies = [ "tempfile", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git#bdedf02f48372efeccdf4323920c21bb1a044788" +dependencies = [ + "log", + "openssl", + "openssl-probe", + "openssl-sys", +] + [[package]] name = "nix" version = "0.26.2" @@ -1405,7 +1417,7 @@ dependencies = [ "js-sys", "log", "mime", - "native-tls", + "native-tls 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell", "percent-encoding", "pin-project-lite", @@ -1853,7 +1865,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ - "native-tls", + "native-tls 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index 4deb9d7..cab33ae 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,12 @@ authors = ["Crunchy Labs Maintainers"] version = "3.0.0-dev.14" edition = "2021" +[features] +default = ["openssl-static"] + +openssl = ["crunchy-cli-core/openssl"] +openssl-static = ["crunchy-cli-core/openssl-static"] + [dependencies] tokio = { version = "1.29", features = ["macros", "rt-multi-thread", "time"], default-features = false } diff --git a/crunchy-cli-core/Cargo.lock b/crunchy-cli-core/Cargo.lock index f8e0970..6297bf2 100644 --- a/crunchy-cli-core/Cargo.lock +++ b/crunchy-cli-core/Cargo.lock @@ -323,6 +323,16 @@ dependencies = [ "url", ] +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -355,6 +365,7 @@ dependencies = [ "indicatif", "lazy_static", "log", + "native-tls 0.2.11 (git+https://github.com/crunchy-labs/rust-not-so-native-tls.git)", "num_cpus", "regex", "reqwest", @@ -583,6 +594,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.0" @@ -802,6 +828,19 @@ dependencies = [ "tokio-rustls", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio", + "tokio-native-tls", +] + [[package]] name = "iana-time-zone" version = "0.1.57" @@ -1041,6 +1080,35 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git#bdedf02f48372efeccdf4323920c21bb1a044788" +dependencies = [ + "log", + "openssl", + "openssl-probe", + "openssl-sys", +] + [[package]] name = "nix" version = "0.26.2" @@ -1103,6 +1171,60 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "openssl" +version = "0.10.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-src" +version = "111.26.0+1.1.1u" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efc62c9f12b22b8f5208c23a7200a442b2e5999f8bdf80233852122b5a4f6f37" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -1127,6 +1249,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + [[package]] name = "portable-atomic" version = "1.4.1" @@ -1253,10 +1381,12 @@ dependencies = [ "http-body", "hyper", "hyper-rustls", + "hyper-tls", "ipnet", "js-sys", "log", "mime", + "native-tls 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "once_cell", "percent-encoding", "pin-project-lite", @@ -1266,6 +1396,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "tokio", + "tokio-native-tls", "tokio-rustls", "tokio-socks", "tower-service", @@ -1372,6 +1503,15 @@ dependencies = [ "regex", ] +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "sct" version = "0.7.0" @@ -1382,6 +1522,29 @@ dependencies = [ "untrusted", ] +[[package]] +name = "security-framework" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.171" @@ -1659,6 +1822,16 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.24.1" @@ -1783,6 +1956,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 5f8f4bc..522a4bd 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -4,6 +4,10 @@ authors = ["Crunchy Labs Maintainers"] version = "3.0.0-dev.14" edition = "2021" +[features] +openssl = ["dep:native-tls", "reqwest/native-tls"] +openssl-static = ["dep:native-tls", "native-tls?/vendored", "reqwest/native-tls-vendored"] + [dependencies] anyhow = "1.0" async-trait = "0.1" @@ -30,11 +34,9 @@ tempfile = "3.6" tokio = { version = "1.29", features = ["macros", "rt-multi-thread", "time"] } sys-locale = "0.3" -[target.'cfg(target_os = "linux")'.dependencies] -reqwest = { version = "0.11", default-features = false, features = ["socks", "native-tls-alpn", "native-tls-vendored"] } - -[target.'cfg(not(target_os = "linux"))'.dependencies] -reqwest = { version = "0.11", default-features = false, features = ["socks"] } +# fork of the `native-tls` crate which uses 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", optional = true } [build-dependencies] chrono = "0.4" diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index 7d0fbfa..9132204 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -8,7 +8,7 @@ use crunchyroll_rs::crunchyroll::CrunchyrollBuilder; use crunchyroll_rs::error::CrunchyrollError; use crunchyroll_rs::{Crunchyroll, Locale}; use log::{debug, error, warn, LevelFilter}; -use reqwest::{Client, ClientBuilder, Proxy, StatusCode}; +use reqwest::Proxy; use std::{env, fs}; mod archive; @@ -267,16 +267,19 @@ async fn crunchyroll_session(cli: &mut Cli) -> Result { let proxy = cli.proxy.clone(); let mut builder = Crunchyroll::builder() .locale(locale) - .client( - get_client(|| { - if let Some(p) = &proxy { - CrunchyrollBuilder::predefined_client_builder().proxy(p.clone()) - } else { - CrunchyrollBuilder::predefined_client_builder() - } - }) - .await?, - ) + .client({ + let builder = if let Some(p) = &proxy { + CrunchyrollBuilder::predefined_client_builder().proxy(p.clone()) + } else { + CrunchyrollBuilder::predefined_client_builder() + }; + #[cfg(any(feature = "openssl", feature = "openssl-static"))] + let client = builder.use_native_tls().build().unwrap(); + #[cfg(not(any(feature = "openssl", feature = "openssl-static")))] + let client = builder.build().unwrap(); + + client + }) .stabilization_locales(cli.experimental_fixes) .stabilization_season_number(cli.experimental_fixes); if let Command::Download(download) = &cli.command { @@ -351,25 +354,3 @@ async fn crunchyroll_session(cli: &mut Cli) -> Result { Ok(crunchy) } - -#[cfg(target_os = "linux")] -async fn get_client ClientBuilder>(f: F) -> Result { - let client = f().build().unwrap(); - if client - .get("https://www.crunchyroll.com") - .send() - .await? - .status() - != StatusCode::FORBIDDEN - { - return Ok(client); - } - - debug!("rustls tls backend probably triggered the cloudflare bot check, using openssl instead"); - Ok(f().use_native_tls().build().unwrap()) -} - -#[cfg(not(target_os = "linux"))] -async fn get_client ClientBuilder>(f: F) -> Result { - Ok(f().build().unwrap()) -} From 00e8082e660a8242053fb53e4ea4abd1e24cf765 Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 20 Jul 2023 14:21:57 +0200 Subject: [PATCH 054/272] Remove test ci step --- .github/workflows/ci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eb4c0c0..478ee43 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,9 +50,6 @@ jobs: toolchain: stable target: ${{ matrix.toolchain }} - - name: Test - run: cargo test --release --all-features --target ${{ matrix.toolchain }} - - name: Build run: cargo build --release --all-features --target ${{ matrix.toolchain }} From 068c0fcac1f77cf4d555cd9dc72f3879f79cc30c Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 20 Jul 2023 18:07:32 +0200 Subject: [PATCH 055/272] Split ci platforms in separate jobs --- .github/workflows/ci.yml | 98 ++++++++++++++++++++++++++++++---------- 1 file changed, 74 insertions(+), 24 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 478ee43..753ea7c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,23 +8,8 @@ on: workflow_dispatch: jobs: - build: - runs-on: ${{ matrix.os }} - strategy: - matrix: - include: - - os: ubuntu-latest - toolchain: x86_64-unknown-linux-musl - platform: linux - ext: - - os: windows-latest - toolchain: x86_64-pc-windows-gnu - platform: windows - ext: .exe - - os: macos-latest - toolchain: x86_64-apple-darwin - platform: darwin - ext: + build-linux: + runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 @@ -41,35 +26,100 @@ jobs: key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - name: Install system dependencies - if: matrix.platform == 'linux' run: sudo apt-get install musl-tools - name: Install toolchain uses: dtolnay/rust-toolchain@stable with: toolchain: stable - target: ${{ matrix.toolchain }} + target: x86_64-unknown-linux-musl - name: Build - run: cargo build --release --all-features --target ${{ matrix.toolchain }} + run: cargo build --release --all-features --target x86_64-unknown-linux-musl - name: Upload binary artifact uses: actions/upload-artifact@v3 with: - name: crunchy-cli_${{ matrix.platform }} - path: ./target/${{ matrix.toolchain }}/release/crunchy-cli${{ matrix.ext }} + name: crunchy-cli_linux + path: ./target/x86_64-unknown-linux-musl/release/crunchy-cli if-no-files-found: error - name: Upload manpages artifact uses: actions/upload-artifact@v3 with: name: manpages - path: ./target/${{ matrix.toolchain }}/release/manpages + path: ./target/x86_64-unknown-linux-musl/release/manpages if-no-files-found: error - name: Upload completions artifact uses: actions/upload-artifact@v3 with: name: completions - path: ./target/${{ matrix.toolchain }}/release/completions + path: ./target/x86_64-unknown-linux-musl/release/completions + if-no-files-found: error + + build-mac: + runs-on: macos-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Cargo cache + uses: actions/cache@v3 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + + - name: Install toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + target: x86_64-apple-darwin + + - name: Build + run: cargo build --release --all-features --target x86_64-apple-darwin + + - name: Upload binary artifact + uses: actions/upload-artifact@v3 + with: + name: crunchy-cli_darwin + path: ./target/x86_64-apple-darwin/release/crunchy-cli + if-no-files-found: error + + build-windows: + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Cargo cache + uses: actions/cache@v3 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + + - name: Install system dependencies + uses: msys2/setup-msys2@v2 + with: + install: mingw-w64-x86_64-rust base-devel + + - name: Build + shell: msys2 {0} + run: cargo build --release --all-features --target x86_64-pc-windows-gnu + + - name: Upload binary artifact + uses: actions/upload-artifact@v3 + with: + name: crunchy-cli_windows + path: ./target/x86_64-pc-windows-gnu/release/crunchy-cli.exe if-no-files-found: error From 5afda0b5f17027e6bf4a54d9d952e4fec07bdcdb Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 20 Jul 2023 19:59:45 +0200 Subject: [PATCH 056/272] Add openssl alpn support --- crunchy-cli-core/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 522a4bd..8b9f7f4 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -5,8 +5,8 @@ version = "3.0.0-dev.14" edition = "2021" [features] -openssl = ["dep:native-tls", "reqwest/native-tls"] -openssl-static = ["dep:native-tls", "native-tls?/vendored", "reqwest/native-tls-vendored"] +openssl = ["dep:native-tls", "reqwest/native-tls-alpn"] +openssl-static = ["dep:native-tls", "native-tls?/vendored", "reqwest/native-tls-alpn", "reqwest/native-tls-vendored"] [dependencies] anyhow = "1.0" From db156d361fe9bcce70453c7fcd8b084549c766f5 Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 21 Jul 2023 13:56:07 +0200 Subject: [PATCH 057/272] Update dependencies and version --- Cargo.lock | 101 ++++++++++++------------------------ Cargo.toml | 2 +- crunchy-cli-core/Cargo.lock | 99 ++++++++++++----------------------- crunchy-cli-core/Cargo.toml | 4 +- 4 files changed, 68 insertions(+), 138 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 34b7d0b..362e019 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,9 +109,9 @@ checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" [[package]] name = "async-trait" -version = "0.1.71" +version = "0.1.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" +checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" dependencies = [ "proc-macro2", "quote", @@ -237,9 +237,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.12" +version = "4.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eab9e8ceb9afdade1ab3f0fd8dbce5b1b2f468ad653baf10e771781b2b67b73" +checksum = "5b0827b011f6f8ab38590295339817b0d26f344aa4932c3ced71b45b0c54b4a9" dependencies = [ "clap_builder", "clap_derive", @@ -248,9 +248,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.12" +version = "4.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f2763db829349bf00cfc06251268865ed4363b93a943174f638daf3ecdba2cd" +checksum = "9441b403be87be858db6a23edb493e7f694761acdc3343d5a0fcaafd304cbc9e" dependencies = [ "anstream", "anstyle", @@ -369,7 +369,7 @@ dependencies = [ [[package]] name = "crunchy-cli" -version = "3.0.0-dev.14" +version = "3.0.0-dev.15" dependencies = [ "chrono", "clap", @@ -381,7 +381,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.0.0-dev.14" +version = "3.0.0-dev.15" dependencies = [ "anyhow", "async-trait", @@ -396,7 +396,7 @@ dependencies = [ "indicatif", "lazy_static", "log", - "native-tls 0.2.11 (git+https://github.com/crunchy-labs/rust-not-so-native-tls.git)", + "native-tls 0.2.11 (git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=570100d)", "num_cpus", "regex", "reqwest", @@ -612,12 +612,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.9.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "fnv" @@ -975,17 +972,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "ipnet" version = "2.8.0" @@ -999,7 +985,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.4", + "rustix", "windows-sys 0.48.0", ] @@ -1039,12 +1025,6 @@ version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" -[[package]] -name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - [[package]] name = "linux-raw-sys" version = "0.4.3" @@ -1132,7 +1112,7 @@ dependencies = [ [[package]] name = "native-tls" version = "0.2.11" -source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git#bdedf02f48372efeccdf4323920c21bb1a044788" +source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=570100d#570100d3391bd9aab7a390cfef0d1a28e8efe200" dependencies = [ "log", "openssl", @@ -1164,9 +1144,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] @@ -1466,20 +1446,6 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustix" -version = "0.37.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", -] - [[package]] name = "rustix" version = "0.38.4" @@ -1489,7 +1455,7 @@ dependencies = [ "bitflags 2.3.3", "errno", "libc", - "linux-raw-sys 0.4.3", + "linux-raw-sys", "windows-sys 0.48.0", ] @@ -1584,18 +1550,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.171" +version = "1.0.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" +checksum = "3b88756493a5bd5e5395d53baa70b194b05764ab85b59e43e4b8f4e1192fa9b1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.171" +version = "1.0.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" +checksum = "6e5c3a298c7f978e53536f95a63bdc4c4a64550582f31a0359a9afda6aede62e" dependencies = [ "proc-macro2", "quote", @@ -1636,9 +1602,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f02d8aa6e3c385bf084924f660ce2a3a6bd333ba55b35e8590b321f35d88513" +checksum = "21e47d95bc83ed33b2ecf84f4187ad1ab9685d18ff28db000c99deac8ce180e3" dependencies = [ "base64", "chrono", @@ -1652,9 +1618,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc7d5d3932fb12ce722ee5e64dd38c504efba37567f0c402f6ca728c3b8b070" +checksum = "ea3cee93715c2e266b9338b7544da68a9f24e227722ba482bd1c024367c77c65" dependencies = [ "darling", "proc-macro2", @@ -1724,9 +1690,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.26" +version = "2.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" +checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" dependencies = [ "proc-macro2", "quote", @@ -1745,32 +1711,31 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.6.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" dependencies = [ - "autocfg", "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix 0.37.23", + "rustix", "windows-sys 0.48.0", ] [[package]] name = "thiserror" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index cab33ae..aa52a9e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.0.0-dev.14" +version = "3.0.0-dev.15" edition = "2021" [features] diff --git a/crunchy-cli-core/Cargo.lock b/crunchy-cli-core/Cargo.lock index 6297bf2..f3acc59 100644 --- a/crunchy-cli-core/Cargo.lock +++ b/crunchy-cli-core/Cargo.lock @@ -109,9 +109,9 @@ checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" [[package]] name = "async-trait" -version = "0.1.71" +version = "0.1.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" +checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" dependencies = [ "proc-macro2", "quote", @@ -237,9 +237,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.12" +version = "4.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eab9e8ceb9afdade1ab3f0fd8dbce5b1b2f468ad653baf10e771781b2b67b73" +checksum = "5b0827b011f6f8ab38590295339817b0d26f344aa4932c3ced71b45b0c54b4a9" dependencies = [ "clap_builder", "clap_derive", @@ -248,9 +248,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.12" +version = "4.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f2763db829349bf00cfc06251268865ed4363b93a943174f638daf3ecdba2cd" +checksum = "9441b403be87be858db6a23edb493e7f694761acdc3343d5a0fcaafd304cbc9e" dependencies = [ "anstream", "anstyle", @@ -350,7 +350,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.0.0-dev.14" +version = "3.0.0-dev.15" dependencies = [ "anyhow", "async-trait", @@ -365,7 +365,7 @@ dependencies = [ "indicatif", "lazy_static", "log", - "native-tls 0.2.11 (git+https://github.com/crunchy-labs/rust-not-so-native-tls.git)", + "native-tls 0.2.11 (git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=570100d)", "num_cpus", "regex", "reqwest", @@ -581,12 +581,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.9.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" [[package]] name = "fnv" @@ -944,17 +941,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "ipnet" version = "2.8.0" @@ -968,7 +954,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.4", + "rustix", "windows-sys 0.48.0", ] @@ -1008,12 +994,6 @@ version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" -[[package]] -name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - [[package]] name = "linux-raw-sys" version = "0.4.3" @@ -1101,7 +1081,7 @@ dependencies = [ [[package]] name = "native-tls" version = "0.2.11" -source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git#bdedf02f48372efeccdf4323920c21bb1a044788" +source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=570100d#570100d3391bd9aab7a390cfef0d1a28e8efe200" dependencies = [ "log", "openssl", @@ -1133,9 +1113,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] @@ -1429,20 +1409,6 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustix" -version = "0.37.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", -] - [[package]] name = "rustix" version = "0.38.4" @@ -1452,7 +1418,7 @@ dependencies = [ "bitflags 2.3.3", "errno", "libc", - "linux-raw-sys 0.4.3", + "linux-raw-sys", "windows-sys 0.48.0", ] @@ -1547,18 +1513,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.171" +version = "1.0.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" +checksum = "3b88756493a5bd5e5395d53baa70b194b05764ab85b59e43e4b8f4e1192fa9b1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.171" +version = "1.0.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" +checksum = "6e5c3a298c7f978e53536f95a63bdc4c4a64550582f31a0359a9afda6aede62e" dependencies = [ "proc-macro2", "quote", @@ -1599,9 +1565,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f02d8aa6e3c385bf084924f660ce2a3a6bd333ba55b35e8590b321f35d88513" +checksum = "21e47d95bc83ed33b2ecf84f4187ad1ab9685d18ff28db000c99deac8ce180e3" dependencies = [ "base64", "chrono", @@ -1615,9 +1581,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc7d5d3932fb12ce722ee5e64dd38c504efba37567f0c402f6ca728c3b8b070" +checksum = "ea3cee93715c2e266b9338b7544da68a9f24e227722ba482bd1c024367c77c65" dependencies = [ "darling", "proc-macro2", @@ -1687,9 +1653,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.26" +version = "2.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" +checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" dependencies = [ "proc-macro2", "quote", @@ -1708,32 +1674,31 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.6.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" dependencies = [ - "autocfg", "cfg-if", "fastrand", "redox_syscall 0.3.5", - "rustix 0.37.23", + "rustix", "windows-sys 0.48.0", ] [[package]] name = "thiserror" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" dependencies = [ "proc-macro2", "quote", diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 8b9f7f4..4a6a229 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.0.0-dev.14" +version = "3.0.0-dev.15" edition = "2021" [features] @@ -36,7 +36,7 @@ sys-locale = "0.3" # fork of the `native-tls` crate which uses 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", optional = true } +native-tls = { git = "https://github.com/crunchy-labs/rust-not-so-native-tls.git", rev = "570100d", features = ["alpn"], optional = true } [build-dependencies] chrono = "0.4" From 9ced3483d87416441cf1e0d6a1e8f5c61c8032c4 Mon Sep 17 00:00:00 2001 From: bytedream Date: Sat, 22 Jul 2023 15:13:24 +0200 Subject: [PATCH 058/272] Error if download series has an episode in an unexpected language and input url is a series url (#225) --- crunchy-cli-core/src/download/filter.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/crunchy-cli-core/src/download/filter.rs b/crunchy-cli-core/src/download/filter.rs index b04aef8..31c0db6 100644 --- a/crunchy-cli-core/src/download/filter.rs +++ b/crunchy-cli-core/src/download/filter.rs @@ -14,6 +14,7 @@ pub(crate) struct DownloadFilter { interactive_input: bool, season_episode_count: HashMap>, season_subtitles_missing: Vec, + season_visited: bool, } impl DownloadFilter { @@ -24,6 +25,7 @@ impl DownloadFilter { interactive_input, season_episode_count: HashMap::new(), season_subtitles_missing: vec![], + season_visited: false, } } } @@ -101,6 +103,8 @@ impl Filter for DownloadFilter { } async fn visit_season(&mut self, season: Season) -> Result> { + self.season_visited = true; + let mut episodes = season.episodes().await?; if Format::has_relative_episodes_fmt(&self.download.output) { @@ -139,14 +143,22 @@ impl Filter for DownloadFilter { .await? .contains(&self.download.audio) { - bail!( + let error_message = format!( "Episode {} ({}) of {} season {} is not available with {} audio", episode.episode_number, episode.title, episode.series_title, episode.season_number, self.download.audio - ) + ); + // sometimes a series randomly has episode in an other language. if this is the case, + // only error if the input url was a episode url + if self.season_visited { + warn!("{}", error_message); + return Ok(None); + } else { + bail!("{}", error_message) + } } // overwrite the current episode with the other version episode episode = episode From 4c396a9e4a2c107fc5a237ba8869412446ccc016 Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 26 Jul 2023 19:17:10 +0200 Subject: [PATCH 059/272] Remove option to configure ffmpeg args with env variables --- crunchy-cli-core/src/utils/ffmpeg.rs | 32 ++++++---------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/crunchy-cli-core/src/utils/ffmpeg.rs b/crunchy-cli-core/src/utils/ffmpeg.rs index 3336fca..210b0f7 100644 --- a/crunchy-cli-core/src/utils/ffmpeg.rs +++ b/crunchy-cli-core/src/utils/ffmpeg.rs @@ -1,12 +1,11 @@ use lazy_static::lazy_static; use regex::Regex; -use std::env; use std::str::FromStr; #[derive(Clone, Debug, Eq, PartialEq)] pub enum FFmpegPreset { Predefined(FFmpegCodec, Option, FFmpegQuality), - Custom(Option, Option), + Custom(Option), } lazy_static! { @@ -81,7 +80,7 @@ ffmpeg_enum! { impl Default for FFmpegPreset { fn default() -> Self { - Self::Custom(None, Some("-c:v copy -c:a copy".to_string())) + Self::Custom(Some("-c:v copy -c:a copy".to_string())) } } @@ -181,27 +180,8 @@ impl FFmpegPreset { } pub(crate) fn parse(s: &str) -> Result { - let env_ffmpeg_input_args = env::var("FFMPEG_INPUT_ARGS").ok(); - let env_ffmpeg_output_args = env::var("FFMPEG_OUTPUT_ARGS").ok(); - - if env_ffmpeg_input_args.is_some() || env_ffmpeg_output_args.is_some() { - if let Some(input) = &env_ffmpeg_input_args { - if shlex::split(input).is_none() { - return Err(format!("Failed to find custom ffmpeg input '{}' (`FFMPEG_INPUT_ARGS` env variable)", input)); - } - } - if let Some(output) = &env_ffmpeg_output_args { - if shlex::split(output).is_none() { - return Err(format!("Failed to find custom ffmpeg output '{}' (`FFMPEG_INPUT_ARGS` env variable)", output)); - } - } - - return Ok(FFmpegPreset::Custom( - env_ffmpeg_input_args, - env_ffmpeg_output_args, - )); - } else if !PREDEFINED_PRESET.is_match(s) { - return Ok(FFmpegPreset::Custom(None, Some(s.to_string()))); + if !PREDEFINED_PRESET.is_match(s) { + return Ok(FFmpegPreset::Custom(Some(s.to_string()))); } let mut codec: Option = None; @@ -272,8 +252,8 @@ impl FFmpegPreset { pub(crate) fn into_input_output_args(self) -> (Vec, Vec) { match self { - FFmpegPreset::Custom(input, output) => ( - input.map_or(vec![], |i| shlex::split(&i).unwrap_or_default()), + FFmpegPreset::Custom(output) => ( + vec![], output.map_or(vec![], |o| shlex::split(&o).unwrap_or_default()), ), FFmpegPreset::Predefined(codec, hwaccel_opt, quality) => { From 84c70f2bee6525b49b87e34bc5cf1209f4a7a105 Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 26 Jul 2023 20:51:34 +0200 Subject: [PATCH 060/272] Add workaround for incorrect hardsub labeling (#231) --- Cargo.lock | 17 +++++++---------- crunchy-cli-core/Cargo.lock | 17 +++++++---------- crunchy-cli-core/Cargo.toml | 2 +- crunchy-cli-core/src/utils/video.rs | 23 ++++++++++++++++++++++- 4 files changed, 37 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 362e019..56ec987 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -412,9 +412,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1fc76ad1ab97992a987dd2a5fadfa4e90fc69d337704f42b7eeb30f7fda1eb1" +checksum = "a0b33d2464e990dec5d3e6265cc892a88ab89971cfd177b7d7c7d0e9f8cde817" dependencies = [ "aes", "async-trait", @@ -434,14 +434,14 @@ dependencies = [ "serde_urlencoded", "smart-default", "tokio", - "webpki-roots 0.24.0", + "webpki-roots 0.25.0", ] [[package]] name = "crunchyroll-rs-internal" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f9581dc7276f1c327dcaa91fa6d3b3f09c46018dc5a0d7815be3f8027780a07" +checksum = "cab3e4af975066a3dc3dd0bb50b1a29c4a3cdee5365e8b6559d21aa15d9ace6a" dependencies = [ "darling", "quote", @@ -2088,12 +2088,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" -dependencies = [ - "rustls-webpki", -] +checksum = "1a4ac452058d835c2b7ff6d74f0ad9f40e172bb1ce661b1444f397eeb1d19e6d" [[package]] name = "winapi" diff --git a/crunchy-cli-core/Cargo.lock b/crunchy-cli-core/Cargo.lock index f3acc59..a5f9b1d 100644 --- a/crunchy-cli-core/Cargo.lock +++ b/crunchy-cli-core/Cargo.lock @@ -381,9 +381,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1fc76ad1ab97992a987dd2a5fadfa4e90fc69d337704f42b7eeb30f7fda1eb1" +checksum = "a0b33d2464e990dec5d3e6265cc892a88ab89971cfd177b7d7c7d0e9f8cde817" dependencies = [ "aes", "async-trait", @@ -403,14 +403,14 @@ dependencies = [ "serde_urlencoded", "smart-default", "tokio", - "webpki-roots 0.24.0", + "webpki-roots 0.25.0", ] [[package]] name = "crunchyroll-rs-internal" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f9581dc7276f1c327dcaa91fa6d3b3f09c46018dc5a0d7815be3f8027780a07" +checksum = "cab3e4af975066a3dc3dd0bb50b1a29c4a3cdee5365e8b6559d21aa15d9ace6a" dependencies = [ "darling", "quote", @@ -2051,12 +2051,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.24.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" -dependencies = [ - "rustls-webpki", -] +checksum = "1a4ac452058d835c2b7ff6d74f0ad9f40e172bb1ce661b1444f397eeb1d19e6d" [[package]] name = "winapi" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 4a6a229..f7a3f43 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -13,7 +13,7 @@ anyhow = "1.0" async-trait = "0.1" clap = { version = "4.3", features = ["derive", "string"] } chrono = "0.4" -crunchyroll-rs = { version = "0.5.0", features = ["dash-stream"] } +crunchyroll-rs = { version = "0.5.1", features = ["dash-stream"] } ctrlc = "3.4" dialoguer = { version = "0.10", default-features = false } dirs = "5.0" diff --git a/crunchy-cli-core/src/utils/video.rs b/crunchy-cli-core/src/utils/video.rs index f2fabd4..5b3eaeb 100644 --- a/crunchy-cli-core/src/utils/video.rs +++ b/crunchy-cli-core/src/utils/video.rs @@ -1,11 +1,32 @@ use anyhow::Result; use crunchyroll_rs::media::{Resolution, Stream, VariantData}; +use crunchyroll_rs::Locale; pub async fn variant_data_from_stream( stream: &Stream, resolution: &Resolution, ) -> Result> { - let mut streaming_data = stream.dash_streaming_data(None).await?; + // sometimes Crunchyroll marks episodes without real subtitles that they have subtitles and + // reports that only hardsub episode are existing. the following lines are trying to prevent + // potential errors which might get caused by this incorrect reporting + // (https://github.com/crunchy-labs/crunchy-cli/issues/231) + let mut hardsub_locales = stream.streaming_hardsub_locales(); + let hardsub_locale = if !hardsub_locales.contains(&Locale::Custom("".to_string())) + && !hardsub_locales.contains(&Locale::Custom(":".to_string())) + { + // if only one hardsub locale exists, assume that this stream doesn't really contains hardsubs + if hardsub_locales.len() == 1 { + Some(hardsub_locales.remove(0)) + } else { + // fallback to `None`. this should trigger an error message in `stream.dash_streaming_data` + // that the requested stream is not available + None + } + } else { + None + }; + + let mut streaming_data = stream.dash_streaming_data(hardsub_locale).await?; streaming_data .0 .sort_by(|a, b| a.bandwidth.cmp(&b.bandwidth).reverse()); From 700b041f9a2a9c882e1cb6d3a008eeb461e66c0f Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 27 Jul 2023 14:18:53 +0200 Subject: [PATCH 061/272] Remove deprecated archive --locale flag --- crunchy-cli-core/src/archive/command.rs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 9a2ee21..398f6c7 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -15,7 +15,7 @@ use anyhow::Result; use chrono::Duration; use crunchyroll_rs::media::{Resolution, Subtitle}; use crunchyroll_rs::Locale; -use log::{debug, warn}; +use log::debug; use std::collections::HashMap; use std::path::PathBuf; @@ -29,9 +29,6 @@ pub struct Archive { Available languages are:\n {}", Locale::all().into_iter().map(|l| format!("{:<6} → {}", l.to_string(), l.to_human_readable())).collect::>().join("\n ")))] #[arg(short, long, default_values_t = vec![Locale::ja_JP, crate::utils::locale::system_locale()])] pub(crate) audio: Vec, - #[arg(help = "Deprecated. Use '-a' / '--audio' instead")] - #[arg(short, long)] - locale: Vec, #[arg(help = format!("Subtitle languages. Can be used multiple times. \ Available languages are: {}", Locale::all().into_iter().map(|l| l.to_string()).collect::>().join(", ")))] #[arg(long_help = format!("Subtitle languages. Can be used multiple times. \ @@ -122,15 +119,6 @@ impl Execute for Archive { bail!("File extension is not '.mkv'. Currently only matroska / '.mkv' files are supported") } - if !self.locale.is_empty() { - warn!("The '-l' / '--locale' flag is deprecated, use '-a' / '--audio' instead"); - for locale in &self.locale { - if !self.audio.contains(locale) { - self.audio.push(locale.clone()) - } - } - } - self.audio = all_locale_in_locales(self.audio.clone()); self.subtitle = all_locale_in_locales(self.subtitle.clone()); From b1342d54f33dd8b11bfbbacec9dbc0edc4c3c769 Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 27 Jul 2023 21:25:51 +0200 Subject: [PATCH 062/272] Change name of output artifacts --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 753ea7c..870c99e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: - name: Upload binary artifact uses: actions/upload-artifact@v3 with: - name: crunchy-cli_linux + name: crunchy-cli-linux-x86_64 path: ./target/x86_64-unknown-linux-musl/release/crunchy-cli if-no-files-found: error @@ -87,7 +87,7 @@ jobs: - name: Upload binary artifact uses: actions/upload-artifact@v3 with: - name: crunchy-cli_darwin + name: crunchy-cli-darwin-x86_64 path: ./target/x86_64-apple-darwin/release/crunchy-cli if-no-files-found: error @@ -120,6 +120,6 @@ jobs: - name: Upload binary artifact uses: actions/upload-artifact@v3 with: - name: crunchy-cli_windows + name: crunchy-cli-windows-x86_64 path: ./target/x86_64-pc-windows-gnu/release/crunchy-cli.exe if-no-files-found: error From 435b75bbf9c80c4a8aac911825779df747f2f8e7 Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 27 Jul 2023 22:05:25 +0200 Subject: [PATCH 063/272] Add aarch64 architecture to linux ci --- .github/workflows/ci.yml | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 870c99e..3cdfd77 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,6 +10,13 @@ on: jobs: build-linux: runs-on: ubuntu-latest + strategy: + matrix: + include: + - arch: x86_64 + toolchain: x86_64-unknown-linux-musl + - arch: aarch64 + toolchain: aarch64-unknown-linux-musl steps: - name: Checkout uses: actions/checkout@v3 @@ -25,37 +32,31 @@ jobs: target/ key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - - name: Install system dependencies - run: sudo apt-get install musl-tools - - - name: Install toolchain - uses: dtolnay/rust-toolchain@stable - with: - toolchain: stable - target: x86_64-unknown-linux-musl + - name: Install cross + run: cargo install cross - name: Build - run: cargo build --release --all-features --target x86_64-unknown-linux-musl + run: cross build --release --all-features --target ${{ matrix.toolchain }} - name: Upload binary artifact uses: actions/upload-artifact@v3 with: - name: crunchy-cli-linux-x86_64 - path: ./target/x86_64-unknown-linux-musl/release/crunchy-cli + name: crunchy-cli-linux-${{ matrix.arch }} + path: ./target/${{ matrix.toolchain }}/release/crunchy-cli if-no-files-found: error - name: Upload manpages artifact uses: actions/upload-artifact@v3 with: name: manpages - path: ./target/x86_64-unknown-linux-musl/release/manpages + path: ./target/${{ matrix.toolchain }}/release/manpages if-no-files-found: error - name: Upload completions artifact uses: actions/upload-artifact@v3 with: name: completions - path: ./target/x86_64-unknown-linux-musl/release/completions + path: ./target/${{ matrix.toolchain }}/release/completions if-no-files-found: error build-mac: From 0586f38cdc1bed3a1bad0c579f4b728590036a7d Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 7 Aug 2023 15:33:42 +0200 Subject: [PATCH 064/272] Update ffmpeg preset help message --- crunchy-cli-core/src/archive/command.rs | 7 +++---- crunchy-cli-core/src/download/command.rs | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 398f6c7..10133f2 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -75,11 +75,10 @@ pub struct Archive { #[arg(value_parser = MergeBehavior::parse)] pub(crate) merge: MergeBehavior, - #[arg(help = format!("Presets for video converting. Can be used multiple times. \ + #[arg(help = format!("Presets for converting the video to a specific coding format. \ Available presets: \n {}", FFmpegPreset::available_matches_human_readable().join("\n ")))] - #[arg(long_help = format!("Presets for video converting. Can be used multiple times. \ - Generally used to minify the file size with keeping (nearly) the same quality. \ - It is recommended to only use this if you archive videos with high resolutions since low resolution videos tend to result in a larger file with any of the provided presets. \ + #[arg(long_help = format!("Presets for converting the video to a specific coding format. \ + If you need more specific ffmpeg customizations you can pass ffmpeg output arguments instead of a preset as value. \ Available presets: \n {}", FFmpegPreset::available_matches_human_readable().join("\n ")))] #[arg(long)] #[arg(value_parser = FFmpegPreset::parse)] diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index ac1e391..1ce731d 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -59,11 +59,10 @@ pub struct Download { #[arg(value_parser = crate::utils::clap::clap_parse_resolution)] pub(crate) resolution: Resolution, - #[arg(help = format!("Presets for video converting. Can be used multiple times. \ + #[arg(help = format!("Presets for converting the video to a specific coding format. \ Available presets: \n {}", FFmpegPreset::available_matches_human_readable().join("\n ")))] - #[arg(long_help = format!("Presets for video converting. Can be used multiple times. \ - Generally used to minify the file size with keeping (nearly) the same quality. \ - It is recommended to only use this if you download videos with high resolutions since low resolution videos tend to result in a larger file with any of the provided presets. \ + #[arg(long_help = format!("Presets for converting the video to a specific coding format. \ + If you need more specific ffmpeg customizations you can pass ffmpeg output arguments instead of a preset as value. \ Available presets: \n {}", FFmpegPreset::available_matches_human_readable().join("\n ")))] #[arg(long)] #[arg(value_parser = FFmpegPreset::parse)] From 2bcaa6e4d5fce93be98c629f5604e5dca2fa3c9d Mon Sep 17 00:00:00 2001 From: ByteDream <63594396+ByteDream@users.noreply.github.com> Date: Mon, 7 Aug 2023 14:40:05 +0100 Subject: [PATCH 065/272] Add ci to publish AUR package on release (#233) --- .github/scripts/PKGBUILD.binary | 39 +++++++++++++++++++ .github/scripts/PKGBUILD.source | 34 ++++++++++++++++ .github/workflows/publish.yml | 69 +++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 .github/scripts/PKGBUILD.binary create mode 100644 .github/scripts/PKGBUILD.source create mode 100644 .github/workflows/publish.yml diff --git a/.github/scripts/PKGBUILD.binary b/.github/scripts/PKGBUILD.binary new file mode 100644 index 0000000..c9cc76e --- /dev/null +++ b/.github/scripts/PKGBUILD.binary @@ -0,0 +1,39 @@ +# Maintainer: ByteDream +pkgname=crunchy-cli-bin +pkgdesc="Command-line downloader for Crunchyroll" +arch=('x86_64') +url="https://github.com/crunchy-labs/crunchy-cli" +license=('MIT') + +pkgver=$CI_PKG_VERSION +pkgrel=1 + +depends=('ffmpeg') +source=( + "crunchy-cli::https://github.com/crunchy-labs/crunchy-cli/releases/download/v${pkgver}/crunchy-cli-v${pkgver}-linux-x86_64" + "manpages.zip::https://github.com/crunchy-labs/crunchy-cli/releases/download/v${pkgver}/crunchy-cli-v${pkgver}-manpages.zip" + "completions.zip::https://github.com/crunchy-labs/crunchy-cli/releases/download/v${pkgver}/crunchy-cli-v${pkgver}-completions.zip" + "LICENSE::https://raw.githubusercontent.com/crunchy-labs/crunchy-cli/v${pkgver}/LICENSE" +) +noextract=("manpages.zip" "completions.zip") +sha256sums=('$CI_SHA_SUM' '$CI_MANPAGES_SHA_SUM' '$CI_COMPLETIONS_SHA_SUM' '$CI_LICENSE_SHA_SUM') + +package() { + cd "$srcdir" + + # all files in manpages.zip and completions.zip are stored in root of the archive, makepkg extracts them all to $srcdir + # which makes it pretty messy. so the extraction is done manually to keep the content of $srcdir structured + mkdir manpages completions + cd manpages + bsdtar -xf ../manpages.zip + cd ../completions + bsdtar -xf ../completions.zip + cd .. + + install -Dm755 crunchy-cli $pkgdir/usr/bin/crunchy-cli + install -Dm644 manpages/* -t $pkgdir/usr/share/man/man1 + install -Dm644 completions/crunchy-cli.bash $pkgdir/usr/share/bash-completions/completions/crunchy-cli + install -Dm644 completions/_crunchy-cli $pkgdir/usr/share/zsh/site-functions/_crunchy-cli + install -Dm644 completions/crunchy-cli.fish $pkgdir/usr/share/fish/vendor_completions.d/crunchy-cli.fish + install -Dm644 LICENSE $pkgdir/usr/share/licenses/crunchy-cli/LICENSE +} diff --git a/.github/scripts/PKGBUILD.source b/.github/scripts/PKGBUILD.source new file mode 100644 index 0000000..737a699 --- /dev/null +++ b/.github/scripts/PKGBUILD.source @@ -0,0 +1,34 @@ +# Maintainer: ByteDream +pkgname=crunchy-cli +pkgdesc="Command-line downloader for Crunchyroll" +arch=('x86_64' 'i686' 'arm' 'armv6h' 'armv7h' 'aarch64') +url="https://github.com/crunchy-labs/crunchy-cli" +license=('MIT') + +pkgver=$CI_PKG_VERSION +pkgrel=1 + +depends=('ffmpeg' 'openssl') +makedepends=('cargo') +source=("${pkgname}-${pkgver}.tar.gz::https://github.com/crunchy-labs/crunchy-cli/archive/refs/tags/v${pkgver}.tar.gz") +sha256sums=('$CI_SHA_SUM') + +build() { + cd "$srcdir/${pkgname}-$pkgver" + + export CARGO_HOME="$srcdir/cargo-home" + export RUSTUP_TOOLCHAIN=stable + + cargo build --release --no-default-features --features openssl +} + +package() { + cd "$srcdir/${pkgname}-$pkgver" + + install -Dm755 target/release/crunchy-cli $pkgdir/usr/bin/crunchy-cli + install -Dm644 target/release/manpages/* $pkgdir/usr/share/man/man1 + install -Dm644 target/release/completions/crunchy-cli.bash $pkgdir/usr/share/bash-completions/completions/crunchy-cli + install -Dm644 target/release/completions/_crunchy-cli $pkgdir/usr/share/zsh/site-functions/_crunchy-cli + install -Dm644 target/release/completions/crunchy-cli.fish $pkgdir/usr/share/fish/vendor_completions.d/crunchy-cli.fish + install -Dm644 LICENSE $pkgdir/usr/share/licenses/crunchy-cli/LICENSE +} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..37f4379 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,69 @@ +name: publish + +on: + push: + tags: + - v* + +jobs: + publish-aur: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Get version + run: echo "RELEASE_VERSION=$(echo ${{ github.ref_name }} | cut -c 2-)" >> $GITHUB_ENV + + - name: Generate crunchy-cli sha sum + run: | + curl -LO https://github.com/crunchy-labs/crunchy-cli/archive/refs/tags/${{ github.ref_name }}.tar.gz + echo "CRUNCHY_CLI_SHA256=$(sha256sum ${{ github.ref_name }}.tar.gz | cut -f 1 -d ' ')" >> $GITHUB_ENV + + - name: Generate crunchy-cli PKGBUILD + env: + CI_PKG_VERSION: ${{ env.RELEASE_VERSION }} + CI_SHA_SUM: ${{ env.CRUNCHY_CLI_SHA256 }} + run: envsubst '$CI_PKG_VERSION,$CI_SHA_SUM' < .github/scripts/PKGBUILD.source > PKGBUILD + + - name: Publish crunchy-cli to AUR + uses: KSXGitHub/github-actions-deploy-aur@2.7.0 + with: + pkgname: crunchy-cli + pkgbuild: ./PKGBUILD + commit_username: release-action + commit_email: ${{ secrets.AUR_EMAIL }} + ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }} + commit_message: Update to version {{ env.RELEASE_VERSION }} + test: true + + - name: Generate crunchy-cli-bin sha sums + run: | + curl -LO https://github.com/crunchy-labs/crunchy-cli/releases/download/${{ github.ref_name }}/crunchy-cli-${{ github.ref_name }}-x86_64-linux + curl -LO https://github.com/crunchy-labs/crunchy-cli/releases/download/${{ github.ref_name }}/crunchy-cli-${{ github.ref_name }}-completions.zip + curl -LO https://github.com/crunchy-labs/crunchy-cli/releases/download/${{ github.ref_name }}/crunchy-cli-${{ github.ref_name }}-manpages.zip + curl -LO https://raw.githubusercontent.com/crunchy-labs/crunchy-cli/${{ github.ref_name }}/LICENSE + echo "CRUNCHY_CLI_BIN_SHA256=$(sha256sum crunchy-cli-${{ github.ref_name }}-x86_64-linux | cut -f 1 -d ' ')" >> $GITHUB_ENV + echo "CRUNCHY_CLI_BIN_COMPLETIONS_SHA256=$(sha256sum crunchy-cli-${{ github.ref_name }}-completions.zip | cut -f 1 -d ' ')" >> $GITHUB_ENV + echo "CRUNCHY_CLI_BIN_MANPAGES_SHA256=$(sha256sum crunchy-cli-${{ github.ref_name }}-manpages.zip | cut -f 1 -d ' ')" >> $GITHUB_ENV + echo "CRUNCHY_CLI_BIN_LICENSE_SHA256=$(sha256sum LICENSE | cut -f 1 -d ' ')" >> $GITHUB_ENV + + - name: Generate crunchy-cli-bin PKGBUILD + env: + CI_PKG_VERSION: ${{ env.RELEASE_VERSION }} + CI_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_SHA256 }} + CI_MANPAGES_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_MANPAGES_SHA256 }} + CI_COMPLETIONS_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_COMPLETIONS_SHA256 }} + CI_LICENSE_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_LICENSE_SHA256 }} + run: envsubst '$CI_PKG_VERSION,$CI_SHA_SUM,$CI_COMPLETIONS_SHA_SUM,$CI_MANPAGES_SHA_SUM' < .github/scripts/PKGBUILD.binary > PKGBUILD + + - name: Publish crunchy-cli-bin to AUR + uses: KSXGitHub/github-actions-deploy-aur@2.7.0 + with: + pkgname: crunchy-cli-bin + pkgbuild: ./PKGBUILD + commit_username: release-action + commit_email: ${{ secrets.AUR_EMAIL }} + ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }} + commit_message: Update to version {{ env.RELEASE_VERSION }} + test: true From 6f40ffacec966268de3888de3e550fdcd8384ec6 Mon Sep 17 00:00:00 2001 From: ByteDream <63594396+ByteDream@users.noreply.github.com> Date: Mon, 7 Aug 2023 14:58:51 +0100 Subject: [PATCH 066/272] Change license (#223) --- LICENSE | 699 ++---------------------------------------------------- README.md | 2 +- 2 files changed, 26 insertions(+), 675 deletions(-) diff --git a/LICENSE b/LICENSE index f288702..512eb1b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,674 +1,25 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. +Copyright (c) 2023-NOW Crunchy Labs Team + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index ca87732..1b2a37b 100644 --- a/README.md +++ b/README.md @@ -293,4 +293,4 @@ This tool is **ONLY** meant for private use. You need a subscription to [`💳 C # ⚖ License -This project is licensed under the GNU General Public License v3.0 (GPL-3.0) - see the [LICENSE](LICENSE) file for more details. +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for more details. From a12a8bc3661cc9263fa76f35644a9dc3e32a9ab7 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 7 Aug 2023 16:19:18 +0200 Subject: [PATCH 067/272] Update README --- README.md | 269 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 213 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index 1b2a37b..a8ec76e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # crunchy-cli -A pure [Rust](https://www.rust-lang.org/) CLI for [Crunchyroll](https://www.crunchyroll.com). +👇 A Command-line downloader for Crunchyroll [Crunchyroll](https://www.crunchyroll.com).

@@ -26,23 +26,20 @@ A pure [Rust](https://www.rust-lang.org/) CLI for [Crunchyroll](https://www.crun

Usage 🖥️ • - Disclaimer 📜 + Disclaimer 📜License ⚖

> We are in no way affiliated with, maintained, authorized, sponsored, or officially associated with Crunchyroll LLC or any of its subsidiaries or affiliates. -> The official Crunchyroll website can be found at [crunchyroll.com](https://crunchyroll.com/). - -> This README belongs to the _master_ branch which is currently under heavy development towards the next major version (3.0). -> It is mostly stable but some issues may still occur. -> If you do not want to use an under-development / pre-release version, head over to the _[golang](https://github.com/crunchy-labs/crunchy-cli/tree/golang)_ branch which contains the EOL but last stable version (and documentation for it). +> The official Crunchyroll website can be found at [www.crunchyroll.com](https://www.crunchyroll.com/). ## ✨ Features - Download single videos and entire series from [Crunchyroll](https://www.crunchyroll.com). - Archive episodes or seasons in an `.mkv` file with multiple subtitles and audios. - Specify a range of episodes to download from an anime. +- Search through the Crunchyroll collection and return metadata (title, duration, direct stream link, ...) of all media types. ## 💾 Get the executable @@ -50,12 +47,25 @@ A pure [Rust](https://www.rust-lang.org/) CLI for [Crunchyroll](https://www.crun Check out the [releases](https://github.com/crunchy-labs/crunchy-cli/releases) tab and get the binary from the latest (pre-)release. -### ❄️ The nix way +### 📦 Get it via a package manager -This requires [nix](https://nixos.org) and you'll probably need `--extra-experimental-features "nix-command flakes"` depending on your configurations. -```shell -$ nix github:crunchy-labs/crunchy-cli -``` +- [AUR](https://aur.archlinux.org/) + + If you're using Arch or an Arch based Linux distribution you are able to install our [AUR](https://aur.archlinux.org/) package. + You need an [AUR helper](https://wiki.archlinux.org/title/AUR_helpers) like [yay](https://github.com/Jguer/yay) to install it. + ```shell + # this package builds crunchy-cli manually (recommended) + $ yay -S crunchy-cli + # this package installs the latest pre-compiled release binary + $ yay -S crunchy-cli-bin + ``` + +- [Nix](https://nixos.org/) + + This requires [nix](https://nixos.org) and you'll probably need `--extra-experimental-features "nix-command flakes"`, depending on your configurations. + ```shell + $ nix github:crunchy-labs/crunchy-cli + ``` ### 🛠 Build it yourself @@ -64,7 +74,9 @@ This requires [git](https://git-scm.com/) and [Cargo](https://doc.rust-lang.org/ ```shell $ git clone https://github.com/crunchy-labs/crunchy-cli $ cd crunchy-cli +# either just build it (will be available in ./target/release/crunchy-cli)... $ cargo build --release +# ... or install it globally $ cargo install --force --path . ``` @@ -74,47 +86,101 @@ $ cargo install --force --path . crunchy-cli requires you to log in. Though you can use a non-premium account, you will not have access to premium content without a subscription. -You can authenticate with your credentials (username:password) or by using a refresh token. +You can authenticate with your credentials (user:password) or by using a refresh token. - Credentials - - ```shell - $ crunchy --credentials "user:password" - ``` + + ```shell + $ crunchy-cli --credentials "user:password" + ``` - Refresh Token - - To obtain a refresh token, you have to log in at [crunchyroll.com](https://www.crunchyroll.com/) and extract the `etp_rt` cookie. - The easiest way to get it is via a browser extension which lets you export your cookies, like [Cookie-Editor](https://cookie-editor.cgagnier.ca/) ([Firefox](https://addons.mozilla.org/en-US/firefox/addon/cookie-editor/) / [Chrome](https://chrome.google.com/webstore/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm)). - When installed, look for the `etp_rt` entry and extract its value. - - ```shell - $ crunchy --etp-rt "4ebf1690-53a4-491a-a2ac-488309120f5d" - ``` + + To obtain a refresh token, you have to log in at [crunchyroll.com](https://www.crunchyroll.com/) and extract the `etp_rt` cookie. + The easiest way to get it is via a browser extension which lets you export your cookies, like [Cookie-Editor](https://cookie-editor.cgagnier.ca/) ([Firefox](https://addons.mozilla.org/en-US/firefox/addon/cookie-editor/) / [Chrome](https://chrome.google.com/webstore/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm)). + When installed, look for the `etp_rt` entry and extract its value. + ```shell + $ crunchy-cli --etp-rt "4ebf1690-53a4-491a-a2ac-488309120f5d" + ``` - Stay Anonymous - - Skip the login check: - - ```shell - $ crunchy --anonymous - ``` + + Login without an account (you won't be able to access premium content): + ```shell + $ crunchy-cli --anonymous + ``` + +### Global settings + +You can set specific settings which will be + +- Verbose output + + If you want to include debug information in the output, use the `-v` / `--verbose` flag to show it. + ```shell + $ crunchy-cli -v + ``` + This flag can't be used with `-q` / `--quiet`. + +- Quiet output + + If you want to hide all output, use the `-q` / `--quiet` flag to do so. + This is especially useful if you want to pipe the output video to an external program (like a video player). + ```shell + $ crunchy-cli -q + ``` + +- Language + + By default, the resulting metadata like title or description are shown in your system language (if Crunchyroll supports it, else in English). + If you want to show the results in another language, use the `--lang` flag to set it. + ```shell + $ crunchy-cli --lang de-DE + ``` + +- Experimental fixes + + Crunchyroll constantly changes and breaks its services or just delivers incorrect answers. + The `--experimental-fixes` flag tries to fix some of those issues. + As the *experimental* in `--experimental-fixes` states, these fixes may or may not break other functionality. + ```shell + $ crunchy-cli --experimental-fixes + ``` + For an overview which parts this flag affects, see the [documentation](https://docs.rs/crunchyroll-rs/latest/crunchyroll_rs/crunchyroll/struct.CrunchyrollBuilder.html) of the underlying Crunchyroll library, all functions beginning with `stabilization_` are applied. + +- Proxy + + The `--proxy` flag supports https and socks5 proxies to route all your traffic through. + This may be helpful to bypass the geo-restrictions Crunchyroll has on certain series. + ```shell + $ crunchy-cli --proxy socks5://127.0.0.1:8080 + ``` + Make sure that proxy can either forward TLS requests, which is needed to bypass the (cloudflare) bot protection, or that it is configured so that the proxy can bypass the protection itself. ### Login -crunchy-cli can store your session, so you don't have to authenticate every time you execute a command. - -Note that the `login` keyword has to be used *last*. +The `login` command can store your session, so you don't have to authenticate every time you execute a command. ```shell -$ crunchy --etp-rt "4ebf1690-53a4-491a-a2ac-488309120f5d" login +# save the refresh token which gets generated when login with credentials. +# your username/email and password won't be stored at any time on disk +$ crunchy-cli login --credentials "user:password" +# save etp-rt cookie +$ crunchy-cli login --etp-rt "4ebf1690-53a4-491a-a2ac-488309120f5d" ``` -With the session stored, you do not need to use `--credentials` / `--etp-rt` anymore. This does not work with `--anonymous`. +With the session stored, you do not need to pass `--credentials` / `--etp-rt` / `--anonymous` anymore when you want to execute a command. ### Download +The `download` command lets you download episodes with a specific audio language and optional subtitles. + **Supported urls** - Single episode (with [episode filtering](#episode-filtering)) ```shell - $ crunchy download https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome + $ crunchy-cli download https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome ``` - Series (with [episode filtering](#episode-filtering)) ```shell - $ crunchy download https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + $ crunchy-cli download https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` **Options** @@ -123,7 +189,7 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any Set the audio language with the `-a` / `--audio` flag. This only works if the url points to a series since episode urls are language specific. ```shell - $ crunchy download -a de-DE https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + $ crunchy-cli download -a de-DE https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` Default is your system locale. If not supported by Crunchyroll, `en-US` (American English) is the default. @@ -132,16 +198,15 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any Besides the audio, you can specify the subtitle language by using the `-s` / `--subtitle` flag. The subtitles will be burned into the video track (cf. [hardsub](https://www.urbandictionary.com/define.php?term=hardsub)) and thus can not be turned off. ```shell - $ crunchy download -s de-DE https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + $ crunchy-cli download -s de-DE https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` Default is none. - Output template Define an output template by using the `-o` / `--output` flag. - If you want to use any other file format than [`.ts`](https://en.wikipedia.org/wiki/MPEG_transport_stream) you need [ffmpeg](https://ffmpeg.org/). ```shell - $ crunchy download -o "ditf.mp4" https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome + $ crunchy-cli download -o "ditf.mp4" https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome ``` Default is `{title}.mp4`. See the [Template Options section](#output-template-options) below for more options. @@ -149,20 +214,54 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any The resolution for videos can be set via the `-r` / `--resolution` flag. ```shell - $ crunchy download -r worst https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome + $ crunchy-cli download -r worst https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome ``` Default is `best`. +- FFmpeg Preset + + You can specify specific built-in presets with the `--ffmpeg-preset` flag to convert videos to a specific coding while downloading. + Multiple predefined presets how videos should be encoded (h264, h265, av1, ...) are available, you can see them with `crunchy-cli download --help`. + If you need more specific ffmpeg customizations you could either convert the output file manually or use ffmpeg output arguments as value for this flag. + ```shell + $ crunchy-cli downlaod --ffmpeg-preset av1-lossless https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome + ``` + +- Skip existing + + If you re-download a series but want to skip episodes you've already downloaded, the `--skip-existing` flag skips the already existing/downloaded files. + ```shell + $ crunchy-cli download --skip-existing https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + ``` + +- Yes + + Sometimes different seasons have the same season number (e.g. Sword Art Online Alicization and Alicization War of Underworld are both marked as season 3), in such cases an interactive prompt is shown which needs user further user input to decide which season to download. + The `--yes` flag suppresses this interactive prompt and just downloads all seasons. + ```shell + $ crunchy-cli download --yes https://www.crunchyroll.com/series/GR49G9VP6/sword-art-online + ``` + If you've passed the `-q` / `--quiet` [global flag](#global-settings), this flag is automatically set. + +- Force hardsub + + If you want to burn-in the subtitles, even if the output format/container supports soft-subs (e.g. `.mp4`), use the `--force-hardsub` flag to do so. + ```shell + $ crunchy-cli download --force-hardsub -s en-US https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome + ``` + ### Archive +The `archive` command lets you download episodes with multiple audios and subtitles and merges it into a `.mkv` file. + **Supported urls** - Single episode (with [episode filtering](#episode-filtering)) ```shell - $ crunchy archive https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome + $ crunchy-cli archive https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome ``` - Series (with [episode filtering](#episode-filtering)) ```shell - $ crunchy archive https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + $ crunchy-cli archive https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` **Options** @@ -170,7 +269,7 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any Set the audio language with the `-a` / `--audio` flag. Can be used multiple times. ```shell - $ crunchy archive -a ja-JP -a de-DE https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + $ crunchy-cli archive -a ja-JP -a de-DE https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` Default is your system locale (if not supported by Crunchyroll, `en-US` (American English) and `ja-JP` (Japanese) are used). @@ -178,7 +277,7 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any Besides the audio, you can specify the subtitle language by using the `-s` / `--subtitle` flag. ```shell - $ crunchy archive -s de-DE https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + $ crunchy-cli archive -s de-DE https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` Default is `all` subtitles. @@ -187,7 +286,7 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any Define an output template by using the `-o` / `--output` flag. crunchy-cli uses the [`.mkv`](https://en.wikipedia.org/wiki/Matroska) container format, because of it's ability to store multiple audio, video and subtitle tracks at once. ```shell - $ crunchy archive -o "{title}.mkv" https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + $ crunchy-cli archive -o "{title}.mkv" https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` Default is `{title}.mkv`. See the [Template Options section](#output-template-options) below for more options. @@ -195,7 +294,7 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any The resolution for videos can be set via the `-r` / `--resolution` flag. ```shell - $ crunchy archive -r worst https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + $ crunchy-cli archive -r worst https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` Default is `best`. @@ -208,32 +307,57 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any Valid options are `audio` - store one video and all other languages as audio only; `video` - store the video + audio for every language; `auto` - detect if videos differ in length: if so, behave like `video` - otherwise like `audio`. Subtitles will always match the primary audio and video. ```shell - $ crunchy archive -m audio https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + $ crunchy-cli archive -m audio https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` Default is `auto`. +- FFmpeg Preset + + You can specify specific built-in presets with the `--ffmpeg-preset` flag to convert videos to a specific coding while downloading. + Multiple predefined presets how videos should be encoded (h264, h265, av1, ...) are available, you can see them with `crunchy-cli archive --help`. + If you need more specific ffmpeg customizations you could either convert the output file manually or use ffmpeg output arguments as value for this flag. + ```shell + $ crunchy-cli archive --ffmpeg-preset av1-lossless https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome + ``` + - Default subtitle `--default-subtitle` Set which subtitle language is to be flagged as **default** and **forced**. ```shell - $ crunchy archive --default-subtitle en-US https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + $ crunchy-cli archive --default-subtitle en-US https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` Default is none. +- Skip existing + + If you re-download a series but want to skip episodes you've already downloaded, the `--skip-existing` flag skips the already existing/downloaded files. + ```shell + $ crunchy-cli archive --skip-existing https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + ``` + +- Yes + + Sometimes different seasons have the same season number (e.g. Sword Art Online Alicization and Alicization War of Underworld are both marked as season 3), in such cases an interactive prompt is shown which needs user further user input to decide which season to download. + The `--yes` flag suppresses this interactive prompt and just downloads all seasons. + ```shell + $ crunchy-cli archive --yes https://www.crunchyroll.com/series/GR49G9VP6/sword-art-online + ``` + If you've passed the `-q` / `--quiet` [global flag](#global-settings), this flag is automatically set. + ### Search **Supported urls/input** - Single episode (with [episode filtering](#episode-filtering)) ```shell - $ crunchy search https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome + $ crunchy-cli search https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome ``` - Series (with [episode filtering](#episode-filtering)) ```shell - $ crunchy search https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + $ crunchy-cli search https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` - Search input ```shell - $ crunchy search "darling in the franxx" + $ crunchy-cli search "darling in the franxx" ``` **Options** @@ -241,11 +365,40 @@ With the session stored, you do not need to use `--credentials` / `--etp-rt` any Set the audio language to search via the `--audio` flag. Can be used multiple times. ```shell - $ crunchy search --audio en-US https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + $ crunchy-cli search --audio en-US https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` Default is your system locale. -### Output Template Options +- Result limit + + If your input is a search term instead of an url, you have multiple options to control which results to process. + The `--search-top-results-limit` flag sets the limit of top search results to process. + `--search-series-limit` sets the limit of only series, `--search-movie-listing-limit` of only movie listings, `--search-episode-limit` of only episodes and `--search-music-limit` of only concerts and music videos. + ```shell + $ crunchy-cli search --search-top-results-limit 10 "darling in the franxx" + # only return series which have 'darling' in it. do not return top results which might also be non-series items + $ crunchy-cli search --search-top-results-limit 0 --search-series-limit 10 "darling" + # this returns 2 top results, 3 movie listings, 5 episodes and 1 music item as result + $ crunchy-cli search --search-top-results-limit 2 --search-movie-listing-limit 3 --search-episode-limit 5 --search-music-limit 1 "test" + ``` + Default is `5` for `--search-top-results-limit`, `0` for all others. + +- Output template + + The search command is designed to show only the specific information you want. + This is done with the `-o`/`--output` flag. + You can specify keywords in a specific pattern, and they will get replaced in the output text. + The required pattern for this begins with `{{`, then the keyword, and closes with `}}` (e.g. `{{episode.title}}`). + For example, if you want to get the title of an episode, you can use `Title: {{episode.title}}` and `{{episode.title}}` will be replaced with the episode title. + You can see all supported keywords with `crunchy-cli search --help`. + ```shell + $ crunchy-cli search -o "{{series.title}}" https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + ``` + Default is `S{{season.number}}E{{episode.number}} - {{episode.title}}`. + +--- + +#### Output Template Options You can use various template options to change how the filename is processed. The following tags are available: @@ -263,11 +416,11 @@ You can use various template options to change how the filename is processed. Th Example: ```shell -$ crunchy archive -o "[S{season_number}E{episode_number}] {title}.mkv" https://www.crunchyroll.com/series/G8DHV7W21/dragon-ball +$ crunchy-cli archive -o "[S{season_number}E{episode_number}] {title}.mkv" https://www.crunchyroll.com/series/G8DHV7W21/dragon-ball # Output file: '[S01E01] Secret of the Dragon Ball.mkv' ``` -### Episode filtering +#### Episode filtering Filters patterns can be used to download a specific range of episodes from a single series. @@ -283,13 +436,17 @@ There are many possible patterns, for example: - `...[S3,S5]` - Download season three and five. - `...[S1-S3,S4E2-S4E6]` - Download season one to three, then episodes two to six from season four. -In practice, it would look like this: `https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx[E1-E5]` +In practice, it would look like this: +``` +https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx[E1-E5] +``` # 📜 Disclaimer -This tool is **ONLY** meant for private use. You need a subscription to [`💳 Crunchyroll Premium 💳`](https://www.crunchyroll.com/welcome#plans) to download premium content. +This tool is meant for private use only. +You need a [Crunchyroll Premium](https://www.crunchyroll.com/welcome#plans) subscription to access premium content. -**You are entirely responsible for what happens to files you downloaded through crunchy-cli.** +**You are entirely responsible for what happens when you use crunchy-cli.** # ⚖ License From aef2fddff7529a7d3731c9be40ea39cacadea76c Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 7 Aug 2023 16:24:47 +0200 Subject: [PATCH 068/272] Update version --- Cargo.lock | 8 +- Cargo.toml | 3 +- crunchy-cli-core/Cargo.lock | 183 ++++++++++++++++++++++-------------- crunchy-cli-core/Cargo.toml | 7 +- 4 files changed, 120 insertions(+), 81 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 56ec987..e56716b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -369,7 +369,7 @@ dependencies = [ [[package]] name = "crunchy-cli" -version = "3.0.0-dev.15" +version = "3.0.0" dependencies = [ "chrono", "clap", @@ -381,7 +381,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.0.0-dev.15" +version = "3.0.0" dependencies = [ "anyhow", "async-trait", @@ -1498,9 +1498,9 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "sanitize-filename" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c502bdb638f1396509467cb0580ef3b29aa2a45c5d43e5d84928241280296c" +checksum = "2ed72fbaf78e6f2d41744923916966c4fbe3d7c74e3037a8ee482f1115572603" dependencies = [ "lazy_static", "regex", diff --git a/Cargo.toml b/Cargo.toml index aa52a9e..d1c1868 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,9 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.0.0-dev.15" +version = "3.0.0" edition = "2021" +license = "MIT" [features] default = ["openssl-static"] diff --git a/crunchy-cli-core/Cargo.lock b/crunchy-cli-core/Cargo.lock index a5f9b1d..b26b645 100644 --- a/crunchy-cli-core/Cargo.lock +++ b/crunchy-cli-core/Cargo.lock @@ -199,9 +199,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.79" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -237,9 +240,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.17" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0827b011f6f8ab38590295339817b0d26f344aa4932c3ced71b45b0c54b4a9" +checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" dependencies = [ "clap_builder", "clap_derive", @@ -248,9 +251,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.17" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9441b403be87be858db6a23edb493e7f694761acdc3343d5a0fcaafd304cbc9e" +checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" dependencies = [ "anstream", "anstyle", @@ -302,7 +305,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.23", + "time 0.3.25", "version_check", ] @@ -319,7 +322,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "time 0.3.23", + "time 0.3.25", "url", ] @@ -350,7 +353,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.0.0-dev.15" +version = "3.0.0" dependencies = [ "anyhow", "async-trait", @@ -403,7 +406,7 @@ dependencies = [ "serde_urlencoded", "smart-default", "tokio", - "webpki-roots 0.25.0", + "webpki-roots 0.25.1", ] [[package]] @@ -494,6 +497,15 @@ dependencies = [ "xattr", ] +[[package]] +name = "deranged" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" +dependencies = [ + "serde", +] + [[package]] name = "derive_setters" version = "0.1.6" @@ -539,9 +551,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "encode_unicode" @@ -559,10 +571,16 @@ dependencies = [ ] [[package]] -name = "errno" -version = "0.3.1" +name = "equivalent" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" dependencies = [ "errno-dragonfly", "libc", @@ -722,7 +740,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.3", "slab", "tokio", "tokio-util", @@ -735,6 +753,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "heck" version = "0.4.1" @@ -905,15 +929,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", "serde", ] [[package]] name = "indicatif" -version = "0.17.5" +version = "0.17.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057" +checksum = "0b297dc40733f23a0e52728a58fa9489a5b7638a324932de16b41adc3ef80730" dependencies = [ "console", "instant", @@ -996,9 +1031,9 @@ checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "linux-raw-sys" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" [[package]] name = "log" @@ -1153,9 +1188,9 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.55" +version = "0.10.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" +checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" dependencies = [ "bitflags 1.3.2", "cfg-if", @@ -1185,18 +1220,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "111.26.0+1.1.1u" +version = "111.27.0+1.1.1v" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efc62c9f12b22b8f5208c23a7200a442b2e5999f8bdf80233852122b5a4f6f37" +checksum = "06e8f197c82d7511c5b014030c9b1efeda40d7d5f99d23b4ceed3524a5e63f02" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.90" +version = "0.9.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" +checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" dependencies = [ "cc", "libc", @@ -1219,9 +1254,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" +checksum = "2c516611246607d0c04186886dbb3a754368ef82c79e9827a802c6d836dd111c" [[package]] name = "pin-utils" @@ -1237,9 +1272,9 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "portable-atomic" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc55135a600d700580e406b4de0d59cb9ad25e344a3a091a97ded2622ec4ec6" +checksum = "f32154ba0af3a075eefa1eda8bb414ee928f62303a54ea85b8d6638ff1a6ee9e" [[package]] name = "proc-macro2" @@ -1278,9 +1313,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -1316,9 +1351,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" dependencies = [ "aho-corasick", "memchr", @@ -1328,9 +1363,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.3" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" +checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" dependencies = [ "aho-corasick", "memchr", @@ -1411,9 +1446,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.4" +version = "0.38.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +checksum = "172891ebdceb05aa0005f533a6cbfca599ddd7d966f6f5d4d9b2e70478e70399" dependencies = [ "bitflags 2.3.3", "errno", @@ -1424,9 +1459,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.5" +version = "0.21.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36" +checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" dependencies = [ "log", "ring", @@ -1445,9 +1480,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.1" +version = "0.101.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f36a6828982f422756984e47912a7a51dcbc2a197aa791158f8ca61cd8204e" +checksum = "513722fd73ad80a71f72b61009ea1b584bcfa1483ca93949c8f290298837fa59" dependencies = [ "ring", "untrusted", @@ -1461,9 +1496,9 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "sanitize-filename" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c502bdb638f1396509467cb0580ef3b29aa2a45c5d43e5d84928241280296c" +checksum = "2ed72fbaf78e6f2d41744923916966c4fbe3d7c74e3037a8ee482f1115572603" dependencies = [ "lazy_static", "regex", @@ -1490,9 +1525,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -1503,9 +1538,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -1513,18 +1548,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.174" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b88756493a5bd5e5395d53baa70b194b05764ab85b59e43e4b8f4e1192fa9b1" +checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.174" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e5c3a298c7f978e53536f95a63bdc4c4a64550582f31a0359a9afda6aede62e" +checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" dependencies = [ "proc-macro2", "quote", @@ -1533,9 +1568,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" dependencies = [ "itoa", "ryu", @@ -1565,25 +1600,26 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e47d95bc83ed33b2ecf84f4187ad1ab9685d18ff28db000c99deac8ce180e3" +checksum = "1402f54f9a3b9e2efe71c1cea24e648acce55887983553eeb858cf3115acfd49" dependencies = [ "base64", "chrono", "hex", - "indexmap", + "indexmap 1.9.3", + "indexmap 2.0.0", "serde", "serde_json", "serde_with_macros", - "time 0.3.23", + "time 0.3.25", ] [[package]] name = "serde_with_macros" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea3cee93715c2e266b9338b7544da68a9f24e227722ba482bd1c024367c77c65" +checksum = "9197f1ad0e3c173a0222d3c4404fb04c3afe87e962bcb327af73e8301fa203c7" dependencies = [ "darling", "proc-macro2", @@ -1653,9 +1689,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.27" +version = "2.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" dependencies = [ "proc-macro2", "quote", @@ -1674,9 +1710,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.7.0" +version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" +checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651" dependencies = [ "cfg-if", "fastrand", @@ -1718,10 +1754,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.23" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" +checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" dependencies = [ + "deranged", "itoa", "serde", "time-core", @@ -1736,9 +1773,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" +checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" dependencies = [ "time-core", ] @@ -2051,9 +2088,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a4ac452058d835c2b7ff6d74f0ad9f40e172bb1ce661b1444f397eeb1d19e6d" +checksum = "c9c6eda1c830a36f361e7721c87fd79ea84293b54f8c48c959f85ec636f0f196" [[package]] name = "winapi" @@ -2229,9 +2266,9 @@ dependencies = [ [[package]] name = "xattr" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea263437ca03c1522846a4ddafbca2542d0ad5ed9b784909d4b27b76f62bc34a" +checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" dependencies = [ "libc", ] diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index f7a3f43..c9ebb25 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -1,8 +1,9 @@ [package] name = "crunchy-cli-core" authors = ["Crunchy Labs Maintainers"] -version = "3.0.0-dev.15" +version = "3.0.0" edition = "2021" +license = "MIT" [features] openssl = ["dep:native-tls", "reqwest/native-tls-alpn"] @@ -25,12 +26,12 @@ log = { version = "0.4", features = ["std"] } num_cpus = "1.16" regex = "1.9" reqwest = { version = "0.11", default-features = false, features = ["socks"] } -sanitize-filename = "0.4" +sanitize-filename = "0.5" serde = "1.0" serde_json = "1.0" serde_plain = "1.0" shlex = "1.1" -tempfile = "3.6" +tempfile = "3.7" tokio = { version = "1.29", features = ["macros", "rt-multi-thread", "time"] } sys-locale = "0.3" From 40397e96a379d6b8f1ac5332a82bf89e739b2e5f Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 7 Aug 2023 17:08:04 +0200 Subject: [PATCH 069/272] Fix arch release pipeline --- .github/scripts/PKGBUILD.binary | 10 ++++++---- .github/scripts/PKGBUILD.source | 10 +++++----- .github/workflows/publish.yml | 8 ++++---- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/.github/scripts/PKGBUILD.binary b/.github/scripts/PKGBUILD.binary index c9cc76e..832f4d0 100644 --- a/.github/scripts/PKGBUILD.binary +++ b/.github/scripts/PKGBUILD.binary @@ -9,6 +9,8 @@ pkgver=$CI_PKG_VERSION pkgrel=1 depends=('ffmpeg') +provides=('crunchy-cli') +conflicts=('crunchy-cli') source=( "crunchy-cli::https://github.com/crunchy-labs/crunchy-cli/releases/download/v${pkgver}/crunchy-cli-v${pkgver}-linux-x86_64" "manpages.zip::https://github.com/crunchy-labs/crunchy-cli/releases/download/v${pkgver}/crunchy-cli-v${pkgver}-manpages.zip" @@ -32,8 +34,8 @@ package() { install -Dm755 crunchy-cli $pkgdir/usr/bin/crunchy-cli install -Dm644 manpages/* -t $pkgdir/usr/share/man/man1 - install -Dm644 completions/crunchy-cli.bash $pkgdir/usr/share/bash-completions/completions/crunchy-cli - install -Dm644 completions/_crunchy-cli $pkgdir/usr/share/zsh/site-functions/_crunchy-cli - install -Dm644 completions/crunchy-cli.fish $pkgdir/usr/share/fish/vendor_completions.d/crunchy-cli.fish - install -Dm644 LICENSE $pkgdir/usr/share/licenses/crunchy-cli/LICENSE + install -Dm644 completions/crunchy-cli.bash -t $pkgdir/usr/share/bash-completions/completions/crunchy-cli + install -Dm644 completions/_crunchy-cli -t $pkgdir/usr/share/zsh/site-functions/_crunchy-cli + install -Dm644 completions/crunchy-cli.fish -t $pkgdir/usr/share/fish/vendor_completions.d/crunchy-cli.fish + install -Dm644 LICENSE -t $pkgdir/usr/share/licenses/crunchy-cli/LICENSE } diff --git a/.github/scripts/PKGBUILD.source b/.github/scripts/PKGBUILD.source index 737a699..beffe74 100644 --- a/.github/scripts/PKGBUILD.source +++ b/.github/scripts/PKGBUILD.source @@ -26,9 +26,9 @@ package() { cd "$srcdir/${pkgname}-$pkgver" install -Dm755 target/release/crunchy-cli $pkgdir/usr/bin/crunchy-cli - install -Dm644 target/release/manpages/* $pkgdir/usr/share/man/man1 - install -Dm644 target/release/completions/crunchy-cli.bash $pkgdir/usr/share/bash-completions/completions/crunchy-cli - install -Dm644 target/release/completions/_crunchy-cli $pkgdir/usr/share/zsh/site-functions/_crunchy-cli - install -Dm644 target/release/completions/crunchy-cli.fish $pkgdir/usr/share/fish/vendor_completions.d/crunchy-cli.fish - install -Dm644 LICENSE $pkgdir/usr/share/licenses/crunchy-cli/LICENSE + install -Dm644 target/release/manpages/* -t $pkgdir/usr/share/man/man1 + install -Dm644 target/release/completions/crunchy-cli.bash -t $pkgdir/usr/share/bash-completions/completions/crunchy-cli + install -Dm644 target/release/completions/_crunchy-cli -t $pkgdir/usr/share/zsh/site-functions/_crunchy-cli + install -Dm644 target/release/completions/crunchy-cli.fish -t $pkgdir/usr/share/fish/vendor_completions.d/crunchy-cli.fish + install -Dm644 LICENSE -t $pkgdir/usr/share/licenses/crunchy-cli/LICENSE } diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 37f4379..ddf4136 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -27,7 +27,7 @@ jobs: run: envsubst '$CI_PKG_VERSION,$CI_SHA_SUM' < .github/scripts/PKGBUILD.source > PKGBUILD - name: Publish crunchy-cli to AUR - uses: KSXGitHub/github-actions-deploy-aur@2.7.0 + uses: KSXGitHub/github-actions-deploy-aur@v2.7.0 with: pkgname: crunchy-cli pkgbuild: ./PKGBUILD @@ -39,7 +39,7 @@ jobs: - name: Generate crunchy-cli-bin sha sums run: | - curl -LO https://github.com/crunchy-labs/crunchy-cli/releases/download/${{ github.ref_name }}/crunchy-cli-${{ github.ref_name }}-x86_64-linux + curl -LO https://github.com/crunchy-labs/crunchy-cli/releases/download/${{ github.ref_name }}/crunchy-cli-${{ github.ref_name }}-linux-x86_64 curl -LO https://github.com/crunchy-labs/crunchy-cli/releases/download/${{ github.ref_name }}/crunchy-cli-${{ github.ref_name }}-completions.zip curl -LO https://github.com/crunchy-labs/crunchy-cli/releases/download/${{ github.ref_name }}/crunchy-cli-${{ github.ref_name }}-manpages.zip curl -LO https://raw.githubusercontent.com/crunchy-labs/crunchy-cli/${{ github.ref_name }}/LICENSE @@ -55,10 +55,10 @@ jobs: CI_MANPAGES_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_MANPAGES_SHA256 }} CI_COMPLETIONS_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_COMPLETIONS_SHA256 }} CI_LICENSE_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_LICENSE_SHA256 }} - run: envsubst '$CI_PKG_VERSION,$CI_SHA_SUM,$CI_COMPLETIONS_SHA_SUM,$CI_MANPAGES_SHA_SUM' < .github/scripts/PKGBUILD.binary > PKGBUILD + run: envsubst '$CI_PKG_VERSION,$CI_SHA_SUM,$CI_COMPLETIONS_SHA_SUM,$CI_MANPAGES_SHA_SUM,$CI_LICENSE_SHA_SUM' < .github/scripts/PKGBUILD.binary > PKGBUILD - name: Publish crunchy-cli-bin to AUR - uses: KSXGitHub/github-actions-deploy-aur@2.7.0 + uses: KSXGitHub/github-actions-deploy-aur@v2.7.0 with: pkgname: crunchy-cli-bin pkgbuild: ./PKGBUILD From b98332eae4096832bbfd5b5c7e7aee962df2493b Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 7 Aug 2023 17:47:06 +0200 Subject: [PATCH 070/272] Add aarch64 support for arch release pipeline --- .github/scripts/PKGBUILD.binary | 13 ++++++++++--- .github/workflows/publish.yml | 9 ++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.github/scripts/PKGBUILD.binary b/.github/scripts/PKGBUILD.binary index 832f4d0..08a0569 100644 --- a/.github/scripts/PKGBUILD.binary +++ b/.github/scripts/PKGBUILD.binary @@ -1,7 +1,7 @@ # Maintainer: ByteDream pkgname=crunchy-cli-bin pkgdesc="Command-line downloader for Crunchyroll" -arch=('x86_64') +arch=('x86_64', 'aarch64') url="https://github.com/crunchy-labs/crunchy-cli" license=('MIT') @@ -11,14 +11,21 @@ pkgrel=1 depends=('ffmpeg') provides=('crunchy-cli') conflicts=('crunchy-cli') -source=( +source_x86_64=( "crunchy-cli::https://github.com/crunchy-labs/crunchy-cli/releases/download/v${pkgver}/crunchy-cli-v${pkgver}-linux-x86_64" "manpages.zip::https://github.com/crunchy-labs/crunchy-cli/releases/download/v${pkgver}/crunchy-cli-v${pkgver}-manpages.zip" "completions.zip::https://github.com/crunchy-labs/crunchy-cli/releases/download/v${pkgver}/crunchy-cli-v${pkgver}-completions.zip" "LICENSE::https://raw.githubusercontent.com/crunchy-labs/crunchy-cli/v${pkgver}/LICENSE" ) +source_aarch64=( + "crunchy-cli::https://github.com/crunchy-labs/crunchy-cli/releases/download/v${pkgver}/crunchy-cli-v${pkgver}-linux-aarch64" + "manpages.zip::https://github.com/crunchy-labs/crunchy-cli/releases/download/v${pkgver}/crunchy-cli-v${pkgver}-manpages.zip" + "completions.zip::https://github.com/crunchy-labs/crunchy-cli/releases/download/v${pkgver}/crunchy-cli-v${pkgver}-completions.zip" + "LICENSE::https://raw.githubusercontent.com/crunchy-labs/crunchy-cli/v${pkgver}/LICENSE" +) noextract=("manpages.zip" "completions.zip") -sha256sums=('$CI_SHA_SUM' '$CI_MANPAGES_SHA_SUM' '$CI_COMPLETIONS_SHA_SUM' '$CI_LICENSE_SHA_SUM') +sha256sums_x86_64=('$CI_x86_64_SHA_SUM' '$CI_MANPAGES_SHA_SUM' '$CI_COMPLETIONS_SHA_SUM' '$CI_LICENSE_SHA_SUM') +sha256sums_aarch64=('$CI_aarch64_SHA_SUM' '$CI_MANPAGES_SHA_SUM' '$CI_COMPLETIONS_SHA_SUM' '$CI_LICENSE_SHA_SUM') package() { cd "$srcdir" diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ddf4136..c2857a9 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -40,10 +40,12 @@ jobs: - name: Generate crunchy-cli-bin sha sums run: | curl -LO https://github.com/crunchy-labs/crunchy-cli/releases/download/${{ github.ref_name }}/crunchy-cli-${{ github.ref_name }}-linux-x86_64 + curl -LO https://github.com/crunchy-labs/crunchy-cli/releases/download/${{ github.ref_name }}/crunchy-cli-${{ github.ref_name }}-linux-aarch64 curl -LO https://github.com/crunchy-labs/crunchy-cli/releases/download/${{ github.ref_name }}/crunchy-cli-${{ github.ref_name }}-completions.zip curl -LO https://github.com/crunchy-labs/crunchy-cli/releases/download/${{ github.ref_name }}/crunchy-cli-${{ github.ref_name }}-manpages.zip curl -LO https://raw.githubusercontent.com/crunchy-labs/crunchy-cli/${{ github.ref_name }}/LICENSE - echo "CRUNCHY_CLI_BIN_SHA256=$(sha256sum crunchy-cli-${{ github.ref_name }}-x86_64-linux | cut -f 1 -d ' ')" >> $GITHUB_ENV + echo "CRUNCHY_CLI_BIN_x86_64_SHA256=$(sha256sum crunchy-cli-${{ github.ref_name }}-x86_64-linux | cut -f 1 -d ' ')" >> $GITHUB_ENV + echo "CRUNCHY_CLI_BIN_aarch64_SHA256=$(sha256sum crunchy-cli-${{ github.ref_name }}-aarch64-linux | cut -f 1 -d ' ')" >> $GITHUB_ENV echo "CRUNCHY_CLI_BIN_COMPLETIONS_SHA256=$(sha256sum crunchy-cli-${{ github.ref_name }}-completions.zip | cut -f 1 -d ' ')" >> $GITHUB_ENV echo "CRUNCHY_CLI_BIN_MANPAGES_SHA256=$(sha256sum crunchy-cli-${{ github.ref_name }}-manpages.zip | cut -f 1 -d ' ')" >> $GITHUB_ENV echo "CRUNCHY_CLI_BIN_LICENSE_SHA256=$(sha256sum LICENSE | cut -f 1 -d ' ')" >> $GITHUB_ENV @@ -51,11 +53,12 @@ jobs: - name: Generate crunchy-cli-bin PKGBUILD env: CI_PKG_VERSION: ${{ env.RELEASE_VERSION }} - CI_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_SHA256 }} + CI_x86_64_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_x86_64_SHA256 }} + CI_aarch64_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_aarch64_SHA256 }} CI_MANPAGES_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_MANPAGES_SHA256 }} CI_COMPLETIONS_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_COMPLETIONS_SHA256 }} CI_LICENSE_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_LICENSE_SHA256 }} - run: envsubst '$CI_PKG_VERSION,$CI_SHA_SUM,$CI_COMPLETIONS_SHA_SUM,$CI_MANPAGES_SHA_SUM,$CI_LICENSE_SHA_SUM' < .github/scripts/PKGBUILD.binary > PKGBUILD + run: envsubst '$CI_PKG_VERSION,$CI_x86_64_SHA_SUM,$CI_aarch64_SHA_SUM,$CI_COMPLETIONS_SHA_SUM,$CI_MANPAGES_SHA_SUM,$CI_LICENSE_SHA_SUM' < .github/scripts/PKGBUILD.binary > PKGBUILD - name: Publish crunchy-cli-bin to AUR uses: KSXGitHub/github-actions-deploy-aur@v2.7.0 From 9f9aec1f8a542af14a573933a1a930dd447b84c7 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 7 Aug 2023 17:48:30 +0200 Subject: [PATCH 071/272] Fix cross installation if cache is present --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3cdfd77..e34097d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - name: Install cross - run: cargo install cross + run: cargo install --force cross - name: Build run: cross build --release --all-features --target ${{ matrix.toolchain }} From 800df5ca6c8d339945181eec894a1db831a15fa2 Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 8 Aug 2023 11:06:07 +0200 Subject: [PATCH 072/272] (Re-)add scoop install example --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index a8ec76e..967eecf 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,14 @@ Check out the [releases](https://github.com/crunchy-labs/crunchy-cli/releases) t $ nix github:crunchy-labs/crunchy-cli ``` +- [Scoop](https://scoop.sh/) + + For Windows users, we support the [scoop](https://scoop.sh/#/) command-line installer. + ```shell + $ scoop bucket add extras + $ scoop install extras/crunchy-cli + ``` + ### 🛠 Build it yourself Since we do not support every platform and architecture you may have to build the project yourself. From 448b633be853f8eca017c9b158a4c96e9b912044 Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 8 Aug 2023 17:33:08 +0200 Subject: [PATCH 073/272] Fix AUR completion and license directory --- .github/scripts/PKGBUILD.binary | 8 ++++---- .github/scripts/PKGBUILD.source | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/scripts/PKGBUILD.binary b/.github/scripts/PKGBUILD.binary index 08a0569..0117723 100644 --- a/.github/scripts/PKGBUILD.binary +++ b/.github/scripts/PKGBUILD.binary @@ -41,8 +41,8 @@ package() { install -Dm755 crunchy-cli $pkgdir/usr/bin/crunchy-cli install -Dm644 manpages/* -t $pkgdir/usr/share/man/man1 - install -Dm644 completions/crunchy-cli.bash -t $pkgdir/usr/share/bash-completions/completions/crunchy-cli - install -Dm644 completions/_crunchy-cli -t $pkgdir/usr/share/zsh/site-functions/_crunchy-cli - install -Dm644 completions/crunchy-cli.fish -t $pkgdir/usr/share/fish/vendor_completions.d/crunchy-cli.fish - install -Dm644 LICENSE -t $pkgdir/usr/share/licenses/crunchy-cli/LICENSE + install -Dm644 completions/crunchy-cli.bash $pkgdir/usr/share/bash-completion/completions/crunchy-cli + install -Dm644 completions/_crunchy-cli $pkgdir/usr/share/zsh/site-functions/_crunchy-cli + install -Dm644 completions/crunchy-cli.fish $pkgdir/usr/share/fish/vendor_completions.d/crunchy-cli.fish + install -Dm644 LICENSE $pkgdir/usr/share/licenses/crunchy-cli/LICENSE } diff --git a/.github/scripts/PKGBUILD.source b/.github/scripts/PKGBUILD.source index beffe74..015efe3 100644 --- a/.github/scripts/PKGBUILD.source +++ b/.github/scripts/PKGBUILD.source @@ -27,8 +27,8 @@ package() { install -Dm755 target/release/crunchy-cli $pkgdir/usr/bin/crunchy-cli install -Dm644 target/release/manpages/* -t $pkgdir/usr/share/man/man1 - install -Dm644 target/release/completions/crunchy-cli.bash -t $pkgdir/usr/share/bash-completions/completions/crunchy-cli - install -Dm644 target/release/completions/_crunchy-cli -t $pkgdir/usr/share/zsh/site-functions/_crunchy-cli - install -Dm644 target/release/completions/crunchy-cli.fish -t $pkgdir/usr/share/fish/vendor_completions.d/crunchy-cli.fish - install -Dm644 LICENSE -t $pkgdir/usr/share/licenses/crunchy-cli/LICENSE + install -Dm644 target/release/completions/crunchy-cli.bash $pkgdir/usr/share/bash-completion/completions/crunchy-cli + install -Dm644 target/release/completions/_crunchy-cli $pkgdir/usr/share/zsh/site-functions/_crunchy-cli + install -Dm644 target/release/completions/crunchy-cli.fish $pkgdir/usr/share/fish/vendor_completions.d/crunchy-cli.fish + install -Dm644 LICENSE $pkgdir/usr/share/licenses/crunchy-cli/LICENSE } From a45833f5a2234ec4750d6b9a7c4c6c17bb534b03 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 14 Aug 2023 00:45:18 +0200 Subject: [PATCH 074/272] Update dependencies and version --- Cargo.lock | 242 +++++++++++++++++++++--------------- Cargo.toml | 4 +- crunchy-cli-core/Cargo.lock | 157 ++++++++--------------- crunchy-cli-core/Cargo.toml | 9 +- crunchy-cli-core/src/lib.rs | 25 ++-- 5 files changed, 216 insertions(+), 221 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e56716b..47b0102 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "86b8f9420f797f2d9e935edf629310eb938a0d839f984e25327f3c7eed22300c" dependencies = [ "memchr", ] @@ -93,9 +93,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -109,9 +109,9 @@ checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" [[package]] name = "async-trait" -version = "0.1.72" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", @@ -163,9 +163,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "block-padding" @@ -199,9 +199,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.79" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -237,9 +240,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.17" +version = "4.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0827b011f6f8ab38590295339817b0d26f344aa4932c3ced71b45b0c54b4a9" +checksum = "c27cdf28c0f604ba3f512b0c9a409f8de8513e4816705deb0498b627e7c3a3fd" dependencies = [ "clap_builder", "clap_derive", @@ -248,9 +251,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.17" +version = "4.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9441b403be87be858db6a23edb493e7f694761acdc3343d5a0fcaafd304cbc9e" +checksum = "08a9f1ab5e9f01a9b81f202e8562eb9a10de70abf9eaeac1be465c28b75aa4aa" dependencies = [ "anstream", "anstyle", @@ -321,7 +324,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.23", + "time 0.3.25", "version_check", ] @@ -338,7 +341,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "time 0.3.23", + "time 0.3.25", "url", ] @@ -369,7 +372,7 @@ dependencies = [ [[package]] name = "crunchy-cli" -version = "3.0.0" +version = "3.0.1" dependencies = [ "chrono", "clap", @@ -381,7 +384,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.0.0" +version = "3.0.1" dependencies = [ "anyhow", "async-trait", @@ -412,9 +415,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0b33d2464e990dec5d3e6265cc892a88ab89971cfd177b7d7c7d0e9f8cde817" +checksum = "6560e2f721420854d34b94b8bc35b316e3ff6bc83cb7cbf24750ddf55a21d45a" dependencies = [ "aes", "async-trait", @@ -434,14 +437,14 @@ dependencies = [ "serde_urlencoded", "smart-default", "tokio", - "webpki-roots 0.25.0", + "webpki-roots 0.25.2", ] [[package]] name = "crunchyroll-rs-internal" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab3e4af975066a3dc3dd0bb50b1a29c4a3cdee5365e8b6559d21aa15d9ace6a" +checksum = "b1398807cd10094f08c1d31423f7979e74c25f772c203d477dfa6ddc4ceb81f2" dependencies = [ "darling", "quote", @@ -505,9 +508,9 @@ dependencies = [ [[package]] name = "dash-mpd" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58b55cd4a2bd4b541906e88adbd2242bda9a697517f638c844fa47fb56fe2f17" +checksum = "5d0c74b03285fe95649f588140b6009dc10bc4f747bd774818ed8e9cc6b5cbb6" dependencies = [ "base64", "base64-serde", @@ -525,6 +528,15 @@ dependencies = [ "xattr", ] +[[package]] +name = "deranged" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" +dependencies = [ + "serde", +] + [[package]] name = "derive_setters" version = "0.1.6" @@ -570,9 +582,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "encode_unicode" @@ -590,10 +602,16 @@ dependencies = [ ] [[package]] -name = "errno" -version = "0.3.1" +name = "equivalent" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" dependencies = [ "errno-dragonfly", "libc", @@ -753,7 +771,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.3", "slab", "tokio", "tokio-util", @@ -766,6 +784,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "heck" version = "0.4.1" @@ -814,9 +838,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" @@ -835,7 +859,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -936,15 +960,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", "serde", ] [[package]] name = "indicatif" -version = "0.17.5" +version = "0.17.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057" +checksum = "0b297dc40733f23a0e52728a58fa9489a5b7638a324932de16b41adc3ef80730" dependencies = [ "console", "instant", @@ -1027,15 +1062,15 @@ checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "linux-raw-sys" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "m3u8-rs" @@ -1184,9 +1219,9 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.55" +version = "0.10.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" +checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" dependencies = [ "bitflags 1.3.2", "cfg-if", @@ -1216,18 +1251,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "111.26.0+1.1.1u" +version = "111.27.0+1.1.1v" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efc62c9f12b22b8f5208c23a7200a442b2e5999f8bdf80233852122b5a4f6f37" +checksum = "06e8f197c82d7511c5b014030c9b1efeda40d7d5f99d23b4ceed3524a5e63f02" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.90" +version = "0.9.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" +checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" dependencies = [ "cc", "libc", @@ -1250,9 +1285,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" +checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" [[package]] name = "pin-utils" @@ -1268,9 +1303,9 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "portable-atomic" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edc55135a600d700580e406b4de0d59cb9ad25e344a3a091a97ded2622ec4ec6" +checksum = "f32154ba0af3a075eefa1eda8bb414ee928f62303a54ea85b8d6638ff1a6ee9e" [[package]] name = "proc-macro2" @@ -1299,9 +1334,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b9228215d82c7b61490fec1de287136b5de6f5700f6e58ea9ad61a7964ca51" +checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" dependencies = [ "memchr", "serde", @@ -1309,9 +1344,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -1347,9 +1382,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" dependencies = [ "aho-corasick", "memchr", @@ -1359,9 +1394,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.3" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" +checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" dependencies = [ "aho-corasick", "memchr", @@ -1448,11 +1483,11 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.4" +version = "0.38.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.0", "errno", "libc", "linux-raw-sys", @@ -1461,9 +1496,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.5" +version = "0.21.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36" +checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" dependencies = [ "log", "ring", @@ -1482,9 +1517,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.1" +version = "0.101.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f36a6828982f422756984e47912a7a51dcbc2a197aa791158f8ca61cd8204e" +checksum = "261e9e0888cba427c3316e6322805653c9425240b6fd96cee7cb671ab70ab8d0" dependencies = [ "ring", "untrusted", @@ -1527,9 +1562,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -1540,9 +1575,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -1550,18 +1585,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.174" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b88756493a5bd5e5395d53baa70b194b05764ab85b59e43e4b8f4e1192fa9b1" +checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.174" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e5c3a298c7f978e53536f95a63bdc4c4a64550582f31a0359a9afda6aede62e" +checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" dependencies = [ "proc-macro2", "quote", @@ -1570,9 +1605,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" dependencies = [ "itoa", "ryu", @@ -1602,25 +1637,26 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e47d95bc83ed33b2ecf84f4187ad1ab9685d18ff28db000c99deac8ce180e3" +checksum = "1402f54f9a3b9e2efe71c1cea24e648acce55887983553eeb858cf3115acfd49" dependencies = [ "base64", "chrono", "hex", - "indexmap", + "indexmap 1.9.3", + "indexmap 2.0.0", "serde", "serde_json", "serde_with_macros", - "time 0.3.23", + "time 0.3.25", ] [[package]] name = "serde_with_macros" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea3cee93715c2e266b9338b7544da68a9f24e227722ba482bd1c024367c77c65" +checksum = "9197f1ad0e3c173a0222d3c4404fb04c3afe87e962bcb327af73e8301fa203c7" dependencies = [ "darling", "proc-macro2", @@ -1670,6 +1706,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "spin" version = "0.5.2" @@ -1690,9 +1736,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.27" +version = "2.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" dependencies = [ "proc-macro2", "quote", @@ -1711,9 +1757,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.7.0" +version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" +checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651" dependencies = [ "cfg-if", "fastrand", @@ -1755,10 +1801,11 @@ dependencies = [ [[package]] name = "time" -version = "0.3.23" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" +checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" dependencies = [ + "deranged", "itoa", "serde", "time-core", @@ -1773,9 +1820,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" +checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" dependencies = [ "time-core", ] @@ -1797,18 +1844,17 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.29.1" +version = "1.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +checksum = "40de3a2ba249dcb097e01be5e67a5ff53cf250397715a071a81543e8a832a920" dependencies = [ - "autocfg", "backtrace", "bytes", "libc", "mio", "num_cpus", "pin-project-lite", - "socket2", + "socket2 0.5.3", "tokio-macros", "windows-sys 0.48.0", ] @@ -2088,9 +2134,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.0" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a4ac452058d835c2b7ff6d74f0ad9f40e172bb1ce661b1444f397eeb1d19e6d" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "winapi" @@ -2266,9 +2312,9 @@ dependencies = [ [[package]] name = "xattr" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea263437ca03c1522846a4ddafbca2542d0ad5ed9b784909d4b27b76f62bc34a" +checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" dependencies = [ "libc", ] diff --git a/Cargo.toml b/Cargo.toml index d1c1868..eb15425 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.0.0" +version = "3.0.1" edition = "2021" license = "MIT" @@ -12,7 +12,7 @@ openssl = ["crunchy-cli-core/openssl"] openssl-static = ["crunchy-cli-core/openssl-static"] [dependencies] -tokio = { version = "1.29", features = ["macros", "rt-multi-thread", "time"], default-features = false } +tokio = { version = "1.31", features = ["macros", "rt-multi-thread", "time"], default-features = false } crunchy-cli-core = { path = "./crunchy-cli-core" } diff --git a/crunchy-cli-core/Cargo.lock b/crunchy-cli-core/Cargo.lock index b26b645..5ba4511 100644 --- a/crunchy-cli-core/Cargo.lock +++ b/crunchy-cli-core/Cargo.lock @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "86b8f9420f797f2d9e935edf629310eb938a0d839f984e25327f3c7eed22300c" dependencies = [ "memchr", ] @@ -93,9 +93,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -109,9 +109,9 @@ checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" [[package]] name = "async-trait" -version = "0.1.72" +version = "0.1.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", @@ -163,9 +163,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" [[package]] name = "block-padding" @@ -240,9 +240,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.19" +version = "4.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" +checksum = "c27cdf28c0f604ba3f512b0c9a409f8de8513e4816705deb0498b627e7c3a3fd" dependencies = [ "clap_builder", "clap_derive", @@ -251,9 +251,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.19" +version = "4.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" +checksum = "08a9f1ab5e9f01a9b81f202e8562eb9a10de70abf9eaeac1be465c28b75aa4aa" dependencies = [ "anstream", "anstyle", @@ -326,16 +326,6 @@ dependencies = [ "url", ] -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -353,7 +343,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.0.0" +version = "3.0.1" dependencies = [ "anyhow", "async-trait", @@ -368,7 +358,7 @@ dependencies = [ "indicatif", "lazy_static", "log", - "native-tls 0.2.11 (git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=570100d)", + "native-tls", "num_cpus", "regex", "reqwest", @@ -384,9 +374,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0b33d2464e990dec5d3e6265cc892a88ab89971cfd177b7d7c7d0e9f8cde817" +checksum = "6560e2f721420854d34b94b8bc35b316e3ff6bc83cb7cbf24750ddf55a21d45a" dependencies = [ "aes", "async-trait", @@ -406,14 +396,14 @@ dependencies = [ "serde_urlencoded", "smart-default", "tokio", - "webpki-roots 0.25.1", + "webpki-roots 0.25.2", ] [[package]] name = "crunchyroll-rs-internal" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab3e4af975066a3dc3dd0bb50b1a29c4a3cdee5365e8b6559d21aa15d9ace6a" +checksum = "b1398807cd10094f08c1d31423f7979e74c25f772c203d477dfa6ddc4ceb81f2" dependencies = [ "darling", "quote", @@ -477,9 +467,9 @@ dependencies = [ [[package]] name = "dash-mpd" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58b55cd4a2bd4b541906e88adbd2242bda9a697517f638c844fa47fb56fe2f17" +checksum = "5d0c74b03285fe95649f588140b6009dc10bc4f747bd774818ed8e9cc6b5cbb6" dependencies = [ "base64", "base64-serde", @@ -807,9 +797,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" @@ -828,7 +818,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2", + "socket2 0.4.9", "tokio", "tower-service", "tracing", @@ -857,7 +847,7 @@ checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", "hyper", - "native-tls 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls", "tokio", "tokio-native-tls", ] @@ -1037,9 +1027,9 @@ checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "m3u8-rs" @@ -1095,24 +1085,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "native-tls" version = "0.2.11" @@ -1254,9 +1226,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c516611246607d0c04186886dbb3a754368ef82c79e9827a802c6d836dd111c" +checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" [[package]] name = "pin-utils" @@ -1303,9 +1275,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b9228215d82c7b61490fec1de287136b5de6f5700f6e58ea9ad61a7964ca51" +checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" dependencies = [ "memchr", "serde", @@ -1401,7 +1373,7 @@ dependencies = [ "js-sys", "log", "mime", - "native-tls 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -1446,11 +1418,11 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.7" +version = "0.38.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "172891ebdceb05aa0005f533a6cbfca599ddd7d966f6f5d4d9b2e70478e70399" +checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f" dependencies = [ - "bitflags 2.3.3", + "bitflags 2.4.0", "errno", "libc", "linux-raw-sys", @@ -1480,9 +1452,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.2" +version = "0.101.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "513722fd73ad80a71f72b61009ea1b584bcfa1483ca93949c8f290298837fa59" +checksum = "261e9e0888cba427c3316e6322805653c9425240b6fd96cee7cb671ab70ab8d0" dependencies = [ "ring", "untrusted", @@ -1504,15 +1476,6 @@ dependencies = [ "regex", ] -[[package]] -name = "schannel" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" -dependencies = [ - "windows-sys 0.48.0", -] - [[package]] name = "sct" version = "0.7.0" @@ -1523,29 +1486,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "security-framework" -version = "2.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "serde" version = "1.0.183" @@ -1669,6 +1609,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "socket2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "spin" version = "0.5.2" @@ -1797,18 +1747,17 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.29.1" +version = "1.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +checksum = "40de3a2ba249dcb097e01be5e67a5ff53cf250397715a071a81543e8a832a920" dependencies = [ - "autocfg", "backtrace", "bytes", "libc", "mio", "num_cpus", "pin-project-lite", - "socket2", + "socket2 0.5.3", "tokio-macros", "windows-sys 0.48.0", ] @@ -1830,7 +1779,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ - "native-tls 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls", "tokio", ] @@ -2088,9 +2037,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.1" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9c6eda1c830a36f361e7721c87fd79ea84293b54f8c48c959f85ec636f0f196" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" [[package]] name = "winapi" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index c9ebb25..5f60474 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.0.0" +version = "3.0.1" edition = "2021" license = "MIT" @@ -14,7 +14,7 @@ anyhow = "1.0" async-trait = "0.1" clap = { version = "4.3", features = ["derive", "string"] } chrono = "0.4" -crunchyroll-rs = { version = "0.5.1", features = ["dash-stream"] } +crunchyroll-rs = { version = "0.6.1", features = ["dash-stream"] } ctrlc = "3.4" dialoguer = { version = "0.10", default-features = false } dirs = "5.0" @@ -32,7 +32,7 @@ serde_json = "1.0" serde_plain = "1.0" shlex = "1.1" tempfile = "3.7" -tokio = { version = "1.29", features = ["macros", "rt-multi-thread", "time"] } +tokio = { version = "1.31", features = ["macros", "rt-multi-thread", "time"] } sys-locale = "0.3" # fork of the `native-tls` crate which uses openssl as backend on every platform. this is done as `reqwest` only supports @@ -41,3 +41,6 @@ native-tls = { git = "https://github.com/crunchy-labs/rust-not-so-native-tls.git [build-dependencies] chrono = "0.4" + +[patch.crates-io] +native-tls = { git = "https://github.com/crunchy-labs/rust-not-so-native-tls.git", rev = "570100d" } diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index 9132204..793e946 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -5,7 +5,7 @@ use anyhow::bail; use anyhow::Result; use clap::{Parser, Subcommand}; use crunchyroll_rs::crunchyroll::CrunchyrollBuilder; -use crunchyroll_rs::error::CrunchyrollError; +use crunchyroll_rs::error::Error; use crunchyroll_rs::{Crunchyroll, Locale}; use log::{debug, error, warn, LevelFilter}; use reqwest::Proxy; @@ -205,20 +205,17 @@ async fn pre_check_executor(executor: &mut impl Execute) { } async fn execute_executor(executor: impl Execute, ctx: Context) { - if let Err(err) = executor.execute(ctx).await { - error!("a unexpected error occurred: {}", err); - - if let Some(crunchy_error) = err.downcast_ref::() { - let message = match crunchy_error { - CrunchyrollError::Internal(i) => &i.message, - CrunchyrollError::Request(r) => &r.message, - CrunchyrollError::Decode(d) => &d.message, - CrunchyrollError::Authentication(a) => &a.message, - CrunchyrollError::Input(i) => &i.message, - }; - if message.contains("content.get_video_streams_v2.cms_service_error") { - error!("You've probably hit a rate limit. Try again later, generally after 10-20 minutes the rate limit is over and you can continue to use the cli") + if let Err(mut err) = executor.execute(ctx).await { + if let Some(crunchy_error) = err.downcast_mut::() { + if let Error::Block { message, .. } = crunchy_error { + *message = "Triggered Cloudflare bot protection. Try again later or use a VPN or proxy to spoof your location".to_string() + } else if let Error::Request { message, .. } = crunchy_error { + *message = "You've probably hit a rate limit. Try again later, generally after 10-20 minutes the rate limit is over and you can continue to use the cli".to_string() } + + error!("An error occurred: {}", crunchy_error) + } else { + error!("An error occurred: {}", err) } std::process::exit(1) From 6da292f0135a5fad6da0ff99632aeb78d48c0b1f Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 14 Aug 2023 15:46:14 +0200 Subject: [PATCH 075/272] Do not test PKGBUILD on arch release pipeline --- .github/workflows/publish.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c2857a9..80cb5bb 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -35,7 +35,6 @@ jobs: commit_email: ${{ secrets.AUR_EMAIL }} ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }} commit_message: Update to version {{ env.RELEASE_VERSION }} - test: true - name: Generate crunchy-cli-bin sha sums run: | @@ -69,4 +68,3 @@ jobs: commit_email: ${{ secrets.AUR_EMAIL }} ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }} commit_message: Update to version {{ env.RELEASE_VERSION }} - test: true From f45bb19cd79f766ed3664e20cbc017f4d40bccfd Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 16 Aug 2023 16:55:16 +0200 Subject: [PATCH 076/272] Remove duplicated native-tls entry (#235) --- Cargo.lock | 18 +++--------------- crunchy-cli-core/Cargo.lock | 1 - crunchy-cli-core/Cargo.toml | 10 ++++------ 3 files changed, 7 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 47b0102..a9119d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -399,7 +399,6 @@ dependencies = [ "indicatif", "lazy_static", "log", - "native-tls 0.2.11 (git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=570100d)", "num_cpus", "regex", "reqwest", @@ -888,7 +887,7 @@ checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", "hyper", - "native-tls 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls", "tokio", "tokio-native-tls", ] @@ -1144,17 +1143,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "native-tls" -version = "0.2.11" -source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=570100d#570100d3391bd9aab7a390cfef0d1a28e8efe200" -dependencies = [ - "log", - "openssl", - "openssl-probe", - "openssl-sys", -] - [[package]] name = "nix" version = "0.26.2" @@ -1432,7 +1420,7 @@ dependencies = [ "js-sys", "log", "mime", - "native-tls 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -1876,7 +1864,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ - "native-tls 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls", "tokio", ] diff --git a/crunchy-cli-core/Cargo.lock b/crunchy-cli-core/Cargo.lock index 5ba4511..0a14466 100644 --- a/crunchy-cli-core/Cargo.lock +++ b/crunchy-cli-core/Cargo.lock @@ -358,7 +358,6 @@ dependencies = [ "indicatif", "lazy_static", "log", - "native-tls", "num_cpus", "regex", "reqwest", diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 5f60474..5787f39 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -6,8 +6,8 @@ edition = "2021" license = "MIT" [features] -openssl = ["dep:native-tls", "reqwest/native-tls-alpn"] -openssl-static = ["dep:native-tls", "native-tls?/vendored", "reqwest/native-tls-alpn", "reqwest/native-tls-vendored"] +openssl = ["reqwest/native-tls-alpn"] +openssl-static = ["reqwest/native-tls-alpn", "reqwest/native-tls-vendored"] [dependencies] anyhow = "1.0" @@ -35,12 +35,10 @@ tempfile = "3.7" tokio = { version = "1.31", features = ["macros", "rt-multi-thread", "time"] } sys-locale = "0.3" -# fork of the `native-tls` crate which uses 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 = "570100d", features = ["alpn"], optional = true } - [build-dependencies] chrono = "0.4" [patch.crates-io] +# fork of the `native-tls` crate which uses 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 = "570100d" } From 31fe1460f19b0b928c40e9cbba5ad5ea6c033278 Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 16 Aug 2023 16:57:35 +0200 Subject: [PATCH 077/272] Replace native-tls its internal fork in the root crate --- Cargo.lock | 51 +-------------------------------------------------- Cargo.toml | 5 +++++ 2 files changed, 6 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9119d3..d307294 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -345,16 +345,6 @@ dependencies = [ "url", ] -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -1128,19 +1118,12 @@ dependencies = [ [[package]] name = "native-tls" version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=570100d#570100d3391bd9aab7a390cfef0d1a28e8efe200" dependencies = [ - "lazy_static", - "libc", "log", "openssl", "openssl-probe", "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", ] [[package]] @@ -1529,15 +1512,6 @@ dependencies = [ "regex", ] -[[package]] -name = "schannel" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" -dependencies = [ - "windows-sys 0.48.0", -] - [[package]] name = "sct" version = "0.7.0" @@ -1548,29 +1522,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "security-framework" -version = "2.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "serde" version = "1.0.183" diff --git a/Cargo.toml b/Cargo.toml index eb15425..114de49 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,11 @@ clap_mangen = "0.2" crunchy-cli-core = { path = "./crunchy-cli-core" } +[patch.crates-io] +# fork of the `native-tls` crate which uses 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 = "570100d" } + [profile.release] strip = true opt-level = "z" From d295a57f842f0fdeb348884c5b3e3d1dabc350f4 Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 16 Aug 2023 17:26:03 +0200 Subject: [PATCH 078/272] Use dynamically linked openssl when running with nix --- flake.lock | 6 +++--- flake.nix | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/flake.lock b/flake.lock index 91bbf3d..90e07bf 100644 --- a/flake.lock +++ b/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1685866647, - "narHash": "sha256-4jKguNHY/edLYImB+uL8jKPL/vpfOvMmSlLAGfxSrnY=", + "lastModified": 1692128808, + "narHash": "sha256-Di1Zm/P042NuwThMiZNrtmaAjd4Tm2qBOKHX7xUOfMk=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a53a3bec10deef6e1cc1caba5bc60f53b959b1e8", + "rev": "4ed9856be002a730234a1a1ed9dcd9dd10cbdb40", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 4a48dec..2c297f7 100644 --- a/flake.nix +++ b/flake.nix @@ -30,6 +30,9 @@ allowBuiltinFetchGit = true; }; + buildNoDefaultFeatures = true; + buildFeatures = [ "openssl" ]; + nativeBuildInputs = [ pkgs.pkg-config ] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [ From 92ed4bd87d0cb137e48398134eeaa5e4a0b3eb99 Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 16 Aug 2023 19:08:13 +0200 Subject: [PATCH 079/272] Revert "Replace native-tls its internal fork in the root crate" This reverts commit 31fe1460f19b0b928c40e9cbba5ad5ea6c033278. --- Cargo.lock | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 5 ----- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d307294..a9119d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -345,6 +345,16 @@ dependencies = [ "url", ] +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -1118,12 +1128,19 @@ dependencies = [ [[package]] name = "native-tls" version = "0.2.11" -source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=570100d#570100d3391bd9aab7a390cfef0d1a28e8efe200" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" dependencies = [ + "lazy_static", + "libc", "log", "openssl", "openssl-probe", "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", ] [[package]] @@ -1512,6 +1529,15 @@ dependencies = [ "regex", ] +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "sct" version = "0.7.0" @@ -1522,6 +1548,29 @@ dependencies = [ "untrusted", ] +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.183" diff --git a/Cargo.toml b/Cargo.toml index 114de49..eb15425 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,11 +24,6 @@ clap_mangen = "0.2" crunchy-cli-core = { path = "./crunchy-cli-core" } -[patch.crates-io] -# fork of the `native-tls` crate which uses 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 = "570100d" } - [profile.release] strip = true opt-level = "z" From 6a6b981979bfd62d46eae40ef81831bd3b5c2741 Mon Sep 17 00:00:00 2001 From: StepBroBD Date: Wed, 16 Aug 2023 14:29:39 -0400 Subject: [PATCH 080/272] Fix nix flake overlays (#236) --- flake.lock | 6 +++--- flake.nix | 23 +++++++++-------------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/flake.lock b/flake.lock index 90e07bf..b9c63db 100644 --- a/flake.lock +++ b/flake.lock @@ -41,11 +41,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1685518550, - "narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=", + "lastModified": 1689068808, + "narHash": "sha256-6ixXo3wt24N/melDWjq70UuHQLxGV8jZvooRanIHXw0=", "owner": "numtide", "repo": "flake-utils", - "rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef", + "rev": "919d646de7be200f3bf08cb76ae1f09402b6f9b4", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 2c297f7..2ca105a 100644 --- a/flake.nix +++ b/flake.nix @@ -4,17 +4,12 @@ utils.url = "flake:flake-utils"; }; - outputs = { self, nixpkgs, utils, ... }: utils.lib.eachSystem [ - "aarch64-darwin" - "x86_64-darwin" - "aarch64-linux" - "x86_64-linux" - ] + outputs = { self, nixpkgs, utils }: utils.lib.eachDefaultSystem (system: let - pkgs = nixpkgs.legacyPackages.${system}; - # enable musl on Linux makes the build time 100x slower - # since it will trigger a toolchain rebuild + # enable musl on Linux will trigger a toolchain rebuild + # making the build very slow + pkgs = import nixpkgs { inherit system; }; # if nixpkgs.legacyPackages.${system}.stdenv.hostPlatform.isLinux # then nixpkgs.legacyPackages.${system}.pkgsMusl # else nixpkgs.legacyPackages.${system}; @@ -49,10 +44,6 @@ { packages.default = crunchy-cli; - overlays.default = _: prev: { - crunchy-cli = prev.crunchy-cli.override { }; - }; - devShells.default = pkgs.mkShell { packages = with pkgs; [ cargo @@ -77,5 +68,9 @@ formatter = pkgs.nixpkgs-fmt; } - ); + ) // { + overlays.default = final: prev: { + inherit (self.packages.${final.system}) crunchy-cli; + }; + }; } From 70b41b4dd5881d66208e1ec2ac8bcfc5ef236e03 Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 17 Aug 2023 11:53:57 +0200 Subject: [PATCH 081/272] Show an error message if no url was given --- crunchy-cli-core/src/archive/command.rs | 1 + crunchy-cli-core/src/download/command.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 10133f2..b7cd8b7 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -99,6 +99,7 @@ pub struct Archive { pub(crate) yes: bool, #[arg(help = "Crunchyroll series url(s)")] + #[arg(required = true)] pub(crate) urls: Vec, } diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index 1ce731d..df4e616 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -81,6 +81,7 @@ pub struct Download { pub(crate) force_hardsub: bool, #[arg(help = "Url(s) to Crunchyroll episodes or series")] + #[arg(required = true)] pub(crate) urls: Vec, } From 596fcc2342bdc8feec64c0fdc0da99afe6e983c2 Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 17 Aug 2023 11:54:00 +0200 Subject: [PATCH 082/272] Fix relative episode number exceeding actual episode count (#238) --- crunchy-cli-core/src/archive/filter.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/crunchy-cli-core/src/archive/filter.rs b/crunchy-cli-core/src/archive/filter.rs index 38fed32..851b4b5 100644 --- a/crunchy-cli-core/src/archive/filter.rs +++ b/crunchy-cli-core/src/archive/filter.rs @@ -18,7 +18,7 @@ pub(crate) struct ArchiveFilter { url_filter: UrlFilter, archive: Archive, interactive_input: bool, - season_episode_count: HashMap>, + season_episode_count: HashMap>, season_subtitles_missing: Vec, season_sorting: Vec, visited: Visited, @@ -229,7 +229,7 @@ impl Filter for ArchiveFilter { if Format::has_relative_episodes_fmt(&self.archive.output) { for episode in episodes.iter() { self.season_episode_count - .entry(episode.season_number) + .entry(episode.season_id.clone()) .or_insert(vec![]) .push(episode.id.clone()) } @@ -300,20 +300,16 @@ impl Filter for ArchiveFilter { } let relative_episode_number = if Format::has_relative_episodes_fmt(&self.archive.output) { - if self - .season_episode_count - .get(&episode.season_number) - .is_none() - { + if self.season_episode_count.get(&episode.season_id).is_none() { let season_episodes = episode.season().await?.episodes().await?; self.season_episode_count.insert( - episode.season_number, + episode.season_id.clone(), season_episodes.into_iter().map(|e| e.id).collect(), ); } let relative_episode_number = self .season_episode_count - .get(&episode.season_number) + .get(&episode.season_id) .unwrap() .iter() .position(|id| id == &episode.id) From 2f57b075591b2906992f32b451dbec90f30a0e69 Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 17 Aug 2023 11:58:11 +0200 Subject: [PATCH 083/272] Change ci cargo cache key --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e34097d..bb2f797 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,7 +30,7 @@ jobs: ~/.cargo/registry/cache/ ~/.cargo/git/db/ target/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + key: ${{ matrix.toolchain }}-cargo-${{ hashFiles('**/Cargo.lock') }} - name: Install cross run: cargo install --force cross @@ -74,7 +74,7 @@ jobs: ~/.cargo/registry/cache/ ~/.cargo/git/db/ target/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + key: x86_64-apple-darwin-cargo-${{ hashFiles('**/Cargo.lock') }} - name: Install toolchain uses: dtolnay/rust-toolchain@stable @@ -107,7 +107,7 @@ jobs: ~/.cargo/registry/cache/ ~/.cargo/git/db/ target/ - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + key: x86_64-pc-windows-gnu-cargo-${{ hashFiles('**/Cargo.lock') }} - name: Install system dependencies uses: msys2/setup-msys2@v2 From a80f6e5df484a14008fd46d787cef773531ab84a Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 25 Aug 2023 14:24:12 +0200 Subject: [PATCH 084/272] Use workspace instead of separate Cargo.lock file --- Cargo.lock | 293 ++--- Cargo.toml | 8 + crunchy-cli-core/Cargo.lock | 2222 ----------------------------------- crunchy-cli-core/Cargo.toml | 5 - 4 files changed, 115 insertions(+), 2413 deletions(-) delete mode 100644 crunchy-cli-core/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock index a9119d3..b07d41b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.20.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8f9420f797f2d9e935edf629310eb938a0d839f984e25327f3c7eed22300c" +checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" dependencies = [ "memchr", ] @@ -54,24 +54,23 @@ dependencies = [ [[package]] name = "anstream" -version = "0.3.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" +checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" [[package]] name = "anstyle-parse" @@ -93,9 +92,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "1.0.2" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c" +checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -103,9 +102,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.72" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "async-trait" @@ -126,9 +125,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.68" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", @@ -199,9 +198,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ "libc", ] @@ -240,9 +239,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.21" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c27cdf28c0f604ba3f512b0c9a409f8de8513e4816705deb0498b627e7c3a3fd" +checksum = "1d5f1946157a96594eb2d2c10eb7ad9a2b27518cb3000209dec700c35df9197d" dependencies = [ "clap_builder", "clap_derive", @@ -251,9 +250,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.21" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a9f1ab5e9f01a9b81f202e8562eb9a10de70abf9eaeac1be465c28b75aa4aa" +checksum = "78116e32a042dd73c2901f0dc30790d20ff3447f3e3472fad359e8c3d282bcd6" dependencies = [ "anstream", "anstyle", @@ -263,18 +262,18 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.3.2" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc443334c81a804575546c5a8a79b4913b50e28d69232903604cada1de817ce" +checksum = "586a385f7ef2f8b4d86bddaa0c094794e7ccbfe5ffef1f434fe928143fc783a5" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.3.12" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" +checksum = "c9fd1a5729c4548118d7d70ff234a44868d00489a4b6597b0b020918a0e91a1a" dependencies = [ "heck", "proc-macro2", @@ -284,15 +283,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] name = "clap_mangen" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f2e32b579dae093c2424a8b7e2bea09c89da01e1ce5065eb2f0a6f1cc15cc1f" +checksum = "cf8e5f34d85d9e0bbe2491d100a7a7c1007bb2467b518080bfe311e8947197a9" dependencies = [ "clap", "roff", @@ -324,7 +323,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.25", + "time 0.3.27", "version_check", ] @@ -341,20 +340,10 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "time 0.3.25", + "time 0.3.27", "url", ] -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -436,7 +425,7 @@ dependencies = [ "serde_urlencoded", "smart-default", "tokio", - "webpki-roots 0.25.2", + "webpki-roots", ] [[package]] @@ -507,9 +496,9 @@ dependencies = [ [[package]] name = "dash-mpd" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0c74b03285fe95649f588140b6009dc10bc4f747bd774818ed8e9cc6b5cbb6" +checksum = "b18de4d072c5be455129422f6a69eb17c032467750d857820cb0c9a92e86a4ed" dependencies = [ "base64", "base64-serde", @@ -529,9 +518,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" dependencies = [ "serde", ] @@ -593,9 +582,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" dependencies = [ "cfg-if", ] @@ -754,15 +743,15 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.3" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "h2" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" dependencies = [ "bytes", "fnv", @@ -1012,17 +1001,6 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" -[[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.48.0", -] - [[package]] name = "iso8601" version = "0.6.1" @@ -1128,19 +1106,12 @@ dependencies = [ [[package]] name = "native-tls" version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=570100d#570100d3391bd9aab7a390cfef0d1a28e8efe200" dependencies = [ - "lazy_static", - "libc", "log", "openssl", "openssl-probe", "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", ] [[package]] @@ -1192,9 +1163,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.31.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" dependencies = [ "memchr", ] @@ -1332,9 +1303,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.32" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] @@ -1399,9 +1370,9 @@ checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ "base64", "bytes", @@ -1438,7 +1409,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.22.6", + "webpki-roots", "winreg", ] @@ -1505,9 +1476,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.3" +version = "0.101.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261e9e0888cba427c3316e6322805653c9425240b6fd96cee7cb671ab70ab8d0" +checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d" dependencies = [ "ring", "untrusted", @@ -1529,15 +1500,6 @@ dependencies = [ "regex", ] -[[package]] -name = "schannel" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" -dependencies = [ - "windows-sys 0.48.0", -] - [[package]] name = "sct" version = "0.7.0" @@ -1548,43 +1510,20 @@ dependencies = [ "untrusted", ] -[[package]] -name = "security-framework" -version = "2.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "serde" -version = "1.0.183" +version = "1.0.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" +checksum = "9f5db24220c009de9bd45e69fb2938f4b6d2df856aa9304ce377b3180f83b7c1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.183" +version = "1.0.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" +checksum = "5ad697f7e0b65af4983a4ce8f56ed5b357e8d3c36651bf6a7e13639c17b8e670" dependencies = [ "proc-macro2", "quote", @@ -1593,9 +1532,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.104" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" dependencies = [ "itoa", "ryu", @@ -1625,9 +1564,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1402f54f9a3b9e2efe71c1cea24e648acce55887983553eeb858cf3115acfd49" +checksum = "1ca3b16a3d82c4088f343b7480a93550b3eabe1a358569c2dfe38bbcead07237" dependencies = [ "base64", "chrono", @@ -1637,14 +1576,14 @@ dependencies = [ "serde", "serde_json", "serde_with_macros", - "time 0.3.25", + "time 0.3.27", ] [[package]] name = "serde_with_macros" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9197f1ad0e3c173a0222d3c4404fb04c3afe87e962bcb327af73e8301fa203c7" +checksum = "2e6be15c453eb305019bfa438b1593c731f36a289a7853f7707ee29e870b3b3c" dependencies = [ "darling", "proc-macro2", @@ -1666,9 +1605,9 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] @@ -1724,9 +1663,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.28" +version = "2.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" dependencies = [ "proc-macro2", "quote", @@ -1745,9 +1684,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.7.1" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", "fastrand", @@ -1758,18 +1697,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.44" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.44" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" dependencies = [ "proc-macro2", "quote", @@ -1789,9 +1728,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.25" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" +checksum = "0bb39ee79a6d8de55f48f2293a830e040392f1c5f16e336bdd1788cd0aadce07" dependencies = [ "deranged", "itoa", @@ -1808,9 +1747,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.11" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" +checksum = "733d258752e9303d392b94b75230d07b0b9c489350c69b851fc6c065fde3e8f9" dependencies = [ "time-core", ] @@ -1832,9 +1771,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.31.0" +version = "1.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40de3a2ba249dcb097e01be5e67a5ff53cf250397715a071a81543e8a832a920" +checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" dependencies = [ "backtrace", "bytes", @@ -2101,25 +2040,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "webpki-roots" -version = "0.22.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" -dependencies = [ - "webpki", -] - [[package]] name = "webpki-roots" version = "0.25.2" @@ -2154,7 +2074,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -2172,7 +2092,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -2192,17 +2112,17 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -2213,9 +2133,9 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" @@ -2225,9 +2145,9 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" @@ -2237,9 +2157,9 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" @@ -2249,9 +2169,9 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" @@ -2261,9 +2181,9 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" @@ -2273,9 +2193,9 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" @@ -2285,17 +2205,18 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if", + "windows-sys 0.48.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index eb15425..6aa5ce0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,14 @@ clap_mangen = "0.2" crunchy-cli-core = { path = "./crunchy-cli-core" } +[workspace] +members = ["crunchy-cli-core"] + +[patch.crates-io] +# fork of the `native-tls` crate which uses 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 = "570100d" } + [profile.release] strip = true opt-level = "z" diff --git a/crunchy-cli-core/Cargo.lock b/crunchy-cli-core/Cargo.lock deleted file mode 100644 index 0a14466..0000000 --- a/crunchy-cli-core/Cargo.lock +++ /dev/null @@ -1,2222 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "aes" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "aho-corasick" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8f9420f797f2d9e935edf629310eb938a0d839f984e25327f3c7eed22300c" -dependencies = [ - "memchr", -] - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anstream" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is-terminal", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" - -[[package]] -name = "anstyle-parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" -dependencies = [ - "windows-sys 0.48.0", -] - -[[package]] -name = "anstyle-wincon" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c" -dependencies = [ - "anstyle", - "windows-sys 0.48.0", -] - -[[package]] -name = "anyhow" -version = "1.0.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" - -[[package]] -name = "async-trait" -version = "0.1.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "backtrace" -version = "0.3.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base64" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" - -[[package]] -name = "base64-serde" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba368df5de76a5bea49aaf0cf1b39ccfbbef176924d1ba5db3e4135216cbe3c7" -dependencies = [ - "base64", - "serde", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" - -[[package]] -name = "block-padding" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bumpalo" -version = "3.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" - -[[package]] -name = "bytes" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" - -[[package]] -name = "cbc" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" -dependencies = [ - "cipher", -] - -[[package]] -name = "cc" -version = "1.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" -dependencies = [ - "libc", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "serde", - "time 0.1.45", - "wasm-bindgen", - "winapi", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "clap" -version = "4.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c27cdf28c0f604ba3f512b0c9a409f8de8513e4816705deb0498b627e7c3a3fd" -dependencies = [ - "clap_builder", - "clap_derive", - "once_cell", -] - -[[package]] -name = "clap_builder" -version = "4.3.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a9f1ab5e9f01a9b81f202e8562eb9a10de70abf9eaeac1be465c28b75aa4aa" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" - -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - -[[package]] -name = "console" -version = "0.15.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "unicode-width", - "windows-sys 0.45.0", -] - -[[package]] -name = "cookie" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" -dependencies = [ - "percent-encoding", - "time 0.3.25", - "version_check", -] - -[[package]] -name = "cookie_store" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d606d0fba62e13cf04db20536c05cb7f13673c161cb47a47a82b9b9e7d3f1daa" -dependencies = [ - "cookie", - "idna 0.2.3", - "log", - "publicsuffix", - "serde", - "serde_derive", - "serde_json", - "time 0.3.25", - "url", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" - -[[package]] -name = "cpufeatures" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" -dependencies = [ - "libc", -] - -[[package]] -name = "crunchy-cli-core" -version = "3.0.1" -dependencies = [ - "anyhow", - "async-trait", - "chrono", - "clap", - "crunchyroll-rs", - "ctrlc", - "derive_setters", - "dialoguer", - "dirs", - "fs2", - "indicatif", - "lazy_static", - "log", - "num_cpus", - "regex", - "reqwest", - "sanitize-filename", - "serde", - "serde_json", - "serde_plain", - "shlex", - "sys-locale", - "tempfile", - "tokio", -] - -[[package]] -name = "crunchyroll-rs" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6560e2f721420854d34b94b8bc35b316e3ff6bc83cb7cbf24750ddf55a21d45a" -dependencies = [ - "aes", - "async-trait", - "cbc", - "chrono", - "crunchyroll-rs-internal", - "dash-mpd", - "futures-util", - "http", - "lazy_static", - "m3u8-rs", - "regex", - "reqwest", - "rustls", - "serde", - "serde_json", - "serde_urlencoded", - "smart-default", - "tokio", - "webpki-roots 0.25.2", -] - -[[package]] -name = "crunchyroll-rs-internal" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1398807cd10094f08c1d31423f7979e74c25f772c203d477dfa6ddc4ceb81f2" -dependencies = [ - "darling", - "quote", - "syn", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "ctrlc" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e" -dependencies = [ - "nix", - "windows-sys 0.48.0", -] - -[[package]] -name = "darling" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn", -] - -[[package]] -name = "darling_macro" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" -dependencies = [ - "darling_core", - "quote", - "syn", -] - -[[package]] -name = "dash-mpd" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0c74b03285fe95649f588140b6009dc10bc4f747bd774818ed8e9cc6b5cbb6" -dependencies = [ - "base64", - "base64-serde", - "chrono", - "fs-err", - "iso8601", - "log", - "num-traits", - "quick-xml", - "regex", - "serde", - "serde_with", - "thiserror", - "tokio", - "xattr", -] - -[[package]] -name = "deranged" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" -dependencies = [ - "serde", -] - -[[package]] -name = "derive_setters" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e8ef033054e131169b8f0f9a7af8f5533a9436fadf3c500ed547f730f07090d" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "dialoguer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59c6f2989294b9a498d3ad5491a79c6deb604617378e1cdc4bfc1c1361fe2f87" -dependencies = [ - "console", - "shell-words", -] - -[[package]] -name = "dirs" -version = "5.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", -] - -[[package]] -name = "either" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" - -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - -[[package]] -name = "encoding_rs" -version = "0.8.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "errno" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "fastrand" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fs-err" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541" - -[[package]] -name = "fs2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "futures-channel" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" -dependencies = [ - "futures-core", -] - -[[package]] -name = "futures-core" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" - -[[package]] -name = "futures-macro" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" - -[[package]] -name = "futures-task" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" - -[[package]] -name = "futures-util" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" -dependencies = [ - "futures-core", - "futures-macro", - "futures-task", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", -] - -[[package]] -name = "gimli" -version = "0.27.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" - -[[package]] -name = "h2" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 1.9.3", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "hermit-abi" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "http" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hyper" -version = "0.14.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.4.9", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" -dependencies = [ - "futures-util", - "http", - "hyper", - "rustls", - "tokio", - "tokio-rustls", -] - -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[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.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "idna" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - -[[package]] -name = "indexmap" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" -dependencies = [ - "equivalent", - "hashbrown 0.14.0", - "serde", -] - -[[package]] -name = "indicatif" -version = "0.17.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b297dc40733f23a0e52728a58fa9489a5b7638a324932de16b41adc3ef80730" -dependencies = [ - "console", - "instant", - "number_prefix", - "portable-atomic", - "unicode-width", -] - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "block-padding", - "generic-array", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "ipnet" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" - -[[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.48.0", -] - -[[package]] -name = "iso8601" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "924e5d73ea28f59011fec52a0d12185d496a9b075d360657aed2a5707f701153" -dependencies = [ - "nom", -] - -[[package]] -name = "itoa" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" - -[[package]] -name = "js-sys" -version = "0.3.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.147" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" - -[[package]] -name = "linux-raw-sys" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" - -[[package]] -name = "log" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" - -[[package]] -name = "m3u8-rs" -version = "5.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39af8845edca961e3286dcbafeb9e6407d3df6a616ef086847162d46f438d75" -dependencies = [ - "chrono", - "nom", -] - -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" -dependencies = [ - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", -] - -[[package]] -name = "native-tls" -version = "0.2.11" -source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=570100d#570100d3391bd9aab7a390cfef0d1a28e8efe200" -dependencies = [ - "log", - "openssl", - "openssl-probe", - "openssl-sys", -] - -[[package]] -name = "nix" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" -dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "libc", - "static_assertions", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "num-traits" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "number_prefix" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" - -[[package]] -name = "object" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - -[[package]] -name = "openssl" -version = "0.10.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" -dependencies = [ - "bitflags 1.3.2", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-src" -version = "111.27.0+1.1.1v" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e8f197c82d7511c5b014030c9b1efeda40d7d5f99d23b4ceed3524a5e63f02" -dependencies = [ - "cc", -] - -[[package]] -name = "openssl-sys" -version = "0.9.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" -dependencies = [ - "cc", - "libc", - "openssl-src", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "option-ext" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" - -[[package]] -name = "percent-encoding" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" - -[[package]] -name = "pin-project-lite" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - -[[package]] -name = "portable-atomic" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f32154ba0af3a075eefa1eda8bb414ee928f62303a54ea85b8d6638ff1a6ee9e" - -[[package]] -name = "proc-macro2" -version = "1.0.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "psl-types" -version = "2.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" - -[[package]] -name = "publicsuffix" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457" -dependencies = [ - "idna 0.3.0", - "psl-types", -] - -[[package]] -name = "quick-xml" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "quote" -version = "1.0.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom", - "redox_syscall 0.2.16", - "thiserror", -] - -[[package]] -name = "regex" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" - -[[package]] -name = "reqwest" -version = "0.11.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" -dependencies = [ - "base64", - "bytes", - "cookie", - "cookie_store", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-rustls", - "hyper-tls", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls", - "rustls-pemfile", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-native-tls", - "tokio-rustls", - "tokio-socks", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots 0.22.6", - "winreg", -] - -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - -[[package]] -name = "rustix" -version = "0.38.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f" -dependencies = [ - "bitflags 2.4.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.48.0", -] - -[[package]] -name = "rustls" -version = "0.21.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" -dependencies = [ - "log", - "ring", - "rustls-webpki", - "sct", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" -dependencies = [ - "base64", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261e9e0888cba427c3316e6322805653c9425240b6fd96cee7cb671ab70ab8d0" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "ryu" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" - -[[package]] -name = "sanitize-filename" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ed72fbaf78e6f2d41744923916966c4fbe3d7c74e3037a8ee482f1115572603" -dependencies = [ - "lazy_static", - "regex", -] - -[[package]] -name = "sct" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "serde" -version = "1.0.183" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.183" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_plain" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6018081315db179d0ce57b1fe4b62a12a0028c9cf9bbef868c9cf477b3c34ae" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_with" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1402f54f9a3b9e2efe71c1cea24e648acce55887983553eeb858cf3115acfd49" -dependencies = [ - "base64", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.0.0", - "serde", - "serde_json", - "serde_with_macros", - "time 0.3.25", -] - -[[package]] -name = "serde_with_macros" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9197f1ad0e3c173a0222d3c4404fb04c3afe87e962bcb327af73e8301fa203c7" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "shell-words" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" - -[[package]] -name = "shlex" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" - -[[package]] -name = "slab" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smart-default" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eb01866308440fc64d6c44d9e86c5cc17adfe33c4d6eed55da9145044d0ffc1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "socket2" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "socket2" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "syn" -version = "2.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sys-locale" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0b9eefabb91675082b41eb94c3ecd91af7656caee3fb4961a07c0ec8c7ca6f" -dependencies = [ - "libc", - "windows-sys 0.45.0", -] - -[[package]] -name = "tempfile" -version = "3.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651" -dependencies = [ - "cfg-if", - "fastrand", - "redox_syscall 0.3.5", - "rustix", - "windows-sys 0.48.0", -] - -[[package]] -name = "thiserror" -version = "1.0.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[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", -] - -[[package]] -name = "time" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" -dependencies = [ - "deranged", - "itoa", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" - -[[package]] -name = "time-macros" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" -dependencies = [ - "time-core", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40de3a2ba249dcb097e01be5e67a5ff53cf250397715a071a81543e8a832a920" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "pin-project-lite", - "socket2 0.5.3", - "tokio-macros", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-macros" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-socks" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0" -dependencies = [ - "either", - "futures-util", - "thiserror", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" -dependencies = [ - "cfg-if", - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" - -[[package]] -name = "typenum" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" - -[[package]] -name = "unicode-bidi" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" - -[[package]] -name = "unicode-ident" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" - -[[package]] -name = "unicode-normalization" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-width" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "url" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" -dependencies = [ - "form_urlencoded", - "idna 0.4.0", - "percent-encoding", -] - -[[package]] -name = "utf8parse" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" - -[[package]] -name = "vcpkg" -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 = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" - -[[package]] -name = "web-sys" -version = "0.3.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "webpki-roots" -version = "0.22.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" -dependencies = [ - "webpki", -] - -[[package]] -name = "webpki-roots" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" -dependencies = [ - "windows-targets 0.48.1", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.1", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.48.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" -dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" - -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - -[[package]] -name = "xattr" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985" -dependencies = [ - "libc", -] diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 5787f39..c66aa1e 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -37,8 +37,3 @@ sys-locale = "0.3" [build-dependencies] chrono = "0.4" - -[patch.crates-io] -# fork of the `native-tls` crate which uses 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 = "570100d" } From 70b3a7a3e1d0c935ccc6c8f3decc8e5948114b7a Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 25 Aug 2023 14:34:16 +0200 Subject: [PATCH 085/272] Remove toolchain setup step from apple build action --- .github/workflows/ci.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bb2f797..f020b68 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -76,12 +76,6 @@ jobs: target/ key: x86_64-apple-darwin-cargo-${{ hashFiles('**/Cargo.lock') }} - - name: Install toolchain - uses: dtolnay/rust-toolchain@stable - with: - toolchain: stable - target: x86_64-apple-darwin - - name: Build run: cargo build --release --all-features --target x86_64-apple-darwin From e06e6b2b01b13eac73e714e2bef8e6b5f71d5f14 Mon Sep 17 00:00:00 2001 From: Simon <47527944+Frooastside@users.noreply.github.com> Date: Fri, 25 Aug 2023 15:21:37 +0200 Subject: [PATCH 086/272] Update README.md (#240) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 967eecf..7a620cb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # crunchy-cli -👇 A Command-line downloader for Crunchyroll [Crunchyroll](https://www.crunchyroll.com). +👇 A Command-line downloader for [Crunchyroll](https://www.crunchyroll.com).

From 3ae6fe4a1a43b034a9e9fe17c67441eed5b5ba8e Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 25 Aug 2023 17:14:44 +0200 Subject: [PATCH 087/272] Fmt --- crunchy-cli-core/src/archive/command.rs | 3 ++- crunchy-cli-core/src/download/command.rs | 3 ++- crunchy-cli-core/src/utils/format.rs | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index b7cd8b7..7ce1658 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -213,7 +213,8 @@ async fn get_format( for single_format in single_formats { let stream = single_format.stream().await?; - let Some((video, audio)) = variant_data_from_stream(&stream, &archive.resolution).await? else { + let Some((video, audio)) = variant_data_from_stream(&stream, &archive.resolution).await? + else { if single_format.is_episode() { bail!( "Resolution ({}) is not available for episode {} ({}) of {} season {}", diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index df4e616..031ed04 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -185,7 +185,8 @@ async fn get_format( single_format: &SingleFormat, ) -> Result<(DownloadFormat, Format)> { let stream = single_format.stream().await?; - let Some((video, audio)) = variant_data_from_stream(&stream, &download.resolution).await? else { + let Some((video, audio)) = variant_data_from_stream(&stream, &download.resolution).await? + else { if single_format.is_episode() { bail!( "Resolution ({}) is not available for episode {} ({}) of {} season {}", diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index d975042..b6dcf35 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -297,8 +297,8 @@ impl Iterator for SingleFormatCollectionIterator { type Item = Vec; fn next(&mut self) -> Option { - let Some((_, episodes)) = self.0.0.iter_mut().next() else { - return None + let Some((_, episodes)) = self.0 .0.iter_mut().next() else { + return None; }; let value = episodes.pop_first().unwrap().1; From 18f891efd2aa7d91a944c2620adb9c66014388a1 Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 25 Aug 2023 17:15:06 +0200 Subject: [PATCH 088/272] Use system certs when using openssl --- Cargo.lock | 67 +++++++++++++++++++++++++++++++++---- crunchy-cli-core/Cargo.toml | 9 ++--- crunchy-cli-core/src/lib.rs | 12 ++++++- 3 files changed, 77 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b07d41b..5fccedf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -344,6 +344,16 @@ dependencies = [ "url", ] +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -391,6 +401,7 @@ dependencies = [ "num_cpus", "regex", "reqwest", + "rustls-native-certs", "sanitize-filename", "serde", "serde_json", @@ -403,9 +414,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6560e2f721420854d34b94b8bc35b316e3ff6bc83cb7cbf24750ddf55a21d45a" +checksum = "771cd92c5a4cc050f301674d77bca6c23f8f260ef346bd06c11b4b05ab9e0166" dependencies = [ "aes", "async-trait", @@ -430,9 +441,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs-internal" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1398807cd10094f08c1d31423f7979e74c25f772c203d477dfa6ddc4ceb81f2" +checksum = "b260191f1125c7ba31e35071524938de5c6b0c2d248e5a35c62c4605e2da427e" dependencies = [ "darling", "quote", @@ -1244,9 +1255,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -1465,6 +1476,18 @@ dependencies = [ "sct", ] +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + [[package]] name = "rustls-pemfile" version = "1.0.3" @@ -1500,6 +1523,15 @@ dependencies = [ "regex", ] +[[package]] +name = "schannel" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "sct" version = "0.7.0" @@ -1510,6 +1542,29 @@ dependencies = [ "untrusted", ] +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "1.0.186" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index c66aa1e..6c9b59c 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -6,15 +6,15 @@ edition = "2021" license = "MIT" [features] -openssl = ["reqwest/native-tls-alpn"] -openssl-static = ["reqwest/native-tls-alpn", "reqwest/native-tls-vendored"] +openssl = ["reqwest/native-tls-alpn", "dep:rustls-native-certs"] +openssl-static = ["reqwest/native-tls-alpn", "reqwest/native-tls-vendored", "dep:rustls-native-certs"] [dependencies] anyhow = "1.0" async-trait = "0.1" clap = { version = "4.3", features = ["derive", "string"] } chrono = "0.4" -crunchyroll-rs = { version = "0.6.1", features = ["dash-stream"] } +crunchyroll-rs = { version = "0.6.2", features = ["dash-stream"] } ctrlc = "3.4" dialoguer = { version = "0.10", default-features = false } dirs = "5.0" @@ -31,9 +31,10 @@ serde = "1.0" serde_json = "1.0" serde_plain = "1.0" shlex = "1.1" +sys-locale = "0.3" tempfile = "3.7" tokio = { version = "1.31", features = ["macros", "rt-multi-thread", "time"] } -sys-locale = "0.3" +rustls-native-certs = { version = "0.6", optional = true } [build-dependencies] chrono = "0.4" diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index 793e946..bae3bed 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -271,7 +271,17 @@ async fn crunchyroll_session(cli: &mut Cli) -> Result { CrunchyrollBuilder::predefined_client_builder() }; #[cfg(any(feature = "openssl", feature = "openssl-static"))] - let client = builder.use_native_tls().build().unwrap(); + let client = { + let mut builder = builder.use_native_tls().tls_built_in_root_certs(false); + + for certificate in rustls_native_certs::load_native_certs().unwrap() { + builder = builder.add_root_certificate( + reqwest::Certificate::from_der(certificate.0.as_slice()).unwrap(), + ) + } + + builder.build().unwrap() + }; #[cfg(not(any(feature = "openssl", feature = "openssl-static")))] let client = builder.build().unwrap(); From b477ca982cd25d009f80bb4aa631128a906635dd Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 6 Sep 2023 02:55:04 +0200 Subject: [PATCH 089/272] Add options to get drm dash and hls url with search --- crunchy-cli-core/src/search/command.rs | 2 ++ crunchy-cli-core/src/search/format.rs | 28 ++++++++++++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/crunchy-cli-core/src/search/command.rs b/crunchy-cli-core/src/search/command.rs index 0159c05..1ec4cb9 100644 --- a/crunchy-cli-core/src/search/command.rs +++ b/crunchy-cli-core/src/search/command.rs @@ -87,7 +87,9 @@ pub struct Search { /// /// stream.locale → Stream locale/language /// stream.dash_url → Stream url in DASH format + /// stream.drm_dash_url → Stream url in DRM protected DASH format /// stream.hls_url → Stream url in HLS format + /// stream.drm_hls_url → Stream url in DRM protected HLS format /// /// subtitle.locale → Subtitle locale/language /// subtitle.url → Url to the subtitle diff --git a/crunchy-cli-core/src/search/format.rs b/crunchy-cli-core/src/search/format.rs index 3574597..55cba7c 100644 --- a/crunchy-cli-core/src/search/format.rs +++ b/crunchy-cli-core/src/search/format.rs @@ -163,25 +163,37 @@ impl From<&Concert> for FormatConcert { struct FormatStream { pub locale: Locale, pub dash_url: String, + pub drm_dash_url: String, pub hls_url: String, + pub drm_hls_url: String, } impl From<&Stream> for FormatStream { fn from(value: &Stream) -> Self { - let (dash_url, hls_url) = value.variants.get(&Locale::Custom("".to_string())).map_or( - ("".to_string(), "".to_string()), - |v| { + let (dash_url, drm_dash_url, hls_url, drm_hls_url) = + value.variants.get(&Locale::Custom("".to_string())).map_or( ( - v.adaptive_dash.clone().unwrap_or_default().url, - v.adaptive_hls.clone().unwrap_or_default().url, - ) - }, - ); + "".to_string(), + "".to_string(), + "".to_string(), + "".to_string(), + ), + |v| { + ( + v.adaptive_dash.clone().unwrap_or_default().url, + v.drm_adaptive_dash.clone().unwrap_or_default().url, + v.adaptive_hls.clone().unwrap_or_default().url, + v.drm_adaptive_hls.clone().unwrap_or_default().url, + ) + }, + ); Self { locale: value.audio_locale.clone(), dash_url, + drm_dash_url, hls_url, + drm_hls_url, } } } From 0f7e6c9120506ba502e653e64928176e66d31108 Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 6 Sep 2023 03:02:40 +0200 Subject: [PATCH 090/272] Add root flag to set custom user agent --- crunchy-cli-core/src/lib.rs | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index bae3bed..50b1e4c 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -63,6 +63,10 @@ pub struct Cli { #[arg(value_parser = crate::utils::clap::clap_parse_proxy)] proxy: Option, + #[arg(help = "Use custom user agent")] + #[clap(long)] + user_agent: Option, + #[clap(subcommand)] command: Command, } @@ -261,15 +265,17 @@ async fn crunchyroll_session(cli: &mut Cli) -> Result { lang }; - let proxy = cli.proxy.clone(); let mut builder = Crunchyroll::builder() .locale(locale) .client({ - let builder = if let Some(p) = &proxy { - CrunchyrollBuilder::predefined_client_builder().proxy(p.clone()) - } else { - CrunchyrollBuilder::predefined_client_builder() - }; + let mut builder = CrunchyrollBuilder::predefined_client_builder(); + if let Some(p) = &cli.proxy { + builder = builder.proxy(p.clone()) + } + if let Some(ua) = &cli.user_agent { + builder = builder.user_agent(ua) + } + #[cfg(any(feature = "openssl", feature = "openssl-static"))] let client = { let mut builder = builder.use_native_tls().tls_built_in_root_certs(false); @@ -292,14 +298,6 @@ async fn crunchyroll_session(cli: &mut Cli) -> Result { if let Command::Download(download) = &cli.command { builder = builder.preferred_audio_locale(download.audio.clone()) } - if let Some(p) = &cli.proxy { - builder = builder.client( - CrunchyrollBuilder::predefined_client_builder() - .proxy(p.clone()) - .build() - .unwrap(), - ) - } let root_login_methods_count = cli.login_method.credentials.is_some() as u8 + cli.login_method.etp_rt.is_some() as u8 From 7485bd8e76aa6e5fda7e5850c4342556b46d57d1 Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 8 Sep 2023 21:41:25 +0200 Subject: [PATCH 091/272] Update dependencies and version --- Cargo.lock | 179 +++++++++++++++--------------------- Cargo.toml | 8 +- crunchy-cli-core/Cargo.toml | 10 +- 3 files changed, 85 insertions(+), 112 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5fccedf..b7e3911 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6748e8def348ed4d14996fa801f4122cd763fff530258cdc03f64b25f89d3a5a" +checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" dependencies = [ "memchr", ] @@ -140,9 +140,9 @@ dependencies = [ [[package]] name = "base64" -version = "0.21.2" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" [[package]] name = "base64-serde" @@ -183,9 +183,9 @@ checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cbc" @@ -213,18 +213,17 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "defd4e7873dbddba6c7c91e199c7fcb946abc4a6a4ac3195400bcfb01b5de877" dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", - "time 0.1.45", "wasm-bindgen", - "winapi", + "windows-targets 0.48.5", ] [[package]] @@ -239,20 +238,19 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d5f1946157a96594eb2d2c10eb7ad9a2b27518cb3000209dec700c35df9197d" +checksum = "6a13b88d2c62ff462f88e4a121f17a82c1af05693a2f192b5c38d14de73c19f6" dependencies = [ "clap_builder", "clap_derive", - "once_cell", ] [[package]] name = "clap_builder" -version = "4.4.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78116e32a042dd73c2901f0dc30790d20ff3447f3e3472fad359e8c3d282bcd6" +checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" dependencies = [ "anstream", "anstyle", @@ -262,18 +260,18 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.4.0" +version = "4.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "586a385f7ef2f8b4d86bddaa0c094794e7ccbfe5ffef1f434fe928143fc783a5" +checksum = "4110a1e6af615a9e6d0a36f805d5c99099f8bab9b8042f5bc1fa220a4a89e36f" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.4.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9fd1a5729c4548118d7d70ff234a44868d00489a4b6597b0b020918a0e91a1a" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ "heck", "proc-macro2", @@ -323,7 +321,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" dependencies = [ "percent-encoding", - "time 0.3.27", + "time", "version_check", ] @@ -340,7 +338,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "time 0.3.27", + "time", "url", ] @@ -371,7 +369,7 @@ dependencies = [ [[package]] name = "crunchy-cli" -version = "3.0.1" +version = "3.0.2" dependencies = [ "chrono", "clap", @@ -383,7 +381,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.0.1" +version = "3.0.2" dependencies = [ "anyhow", "async-trait", @@ -462,9 +460,9 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.4.0" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a011bbe2c35ce9c1f143b7af6f94f29a167beb4cd1d29e6740ce836f723120e" +checksum = "82e95fbd621905b854affdc67943b043a0fbb6ed7385fd5a25650d19a8a6cfdf" dependencies = [ "nix", "windows-sys 0.48.0", @@ -608,9 +606,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" +checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", @@ -749,7 +747,7 @@ checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -1078,9 +1076,9 @@ checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" [[package]] name = "mime" @@ -1110,7 +1108,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.48.0", ] @@ -1127,14 +1125,13 @@ dependencies = [ [[package]] name = "nix" -version = "0.26.2" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "cfg-if", "libc", - "static_assertions", ] [[package]] @@ -1174,9 +1171,9 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.32.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ac5bbd07aea88c60a577a1ce218075ffd59208b2d7ca97adf9bfc5aeb21ebe" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] @@ -1189,11 +1186,11 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.56" +version = "0.10.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "cfg-if", "foreign-types", "libc", @@ -1221,18 +1218,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "111.27.0+1.1.1v" +version = "300.1.3+3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e8f197c82d7511c5b014030c9b1efeda40d7d5f99d23b4ceed3524a5e63f02" +checksum = "cd2c101a165fff9935e34def4669595ab1c7847943c42be86e21503e482be107" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.91" +version = "0.9.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" +checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" dependencies = [ "cc", "libc", @@ -1273,9 +1270,9 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "portable-atomic" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f32154ba0af3a075eefa1eda8bb414ee928f62303a54ea85b8d6638ff1a6ee9e" +checksum = "31114a898e107c51bb1609ffaf55a0e011cf6a4d7f1170d0015a165082c0338b" [[package]] name = "proc-macro2" @@ -1352,9 +1349,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.9.3" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" dependencies = [ "aho-corasick", "memchr", @@ -1364,9 +1361,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" dependencies = [ "aho-corasick", "memchr", @@ -1375,9 +1372,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "reqwest" @@ -1453,9 +1450,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.8" +version = "0.38.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f" +checksum = "c0c3dde1fc030af041adc40e79c0e7fbcf431dd24870053d187d7c66e4b87453" dependencies = [ "bitflags 2.4.0", "errno", @@ -1466,9 +1463,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.6" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", "ring", @@ -1567,18 +1564,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.186" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f5db24220c009de9bd45e69fb2938f4b6d2df856aa9304ce377b3180f83b7c1" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.186" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad697f7e0b65af4983a4ce8f56ed5b357e8d3c36651bf6a7e13639c17b8e670" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", @@ -1598,9 +1595,9 @@ dependencies = [ [[package]] name = "serde_plain" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6018081315db179d0ce57b1fe4b62a12a0028c9cf9bbef868c9cf477b3c34ae" +checksum = "9ce1fc6db65a611022b23a0dec6975d63fb80a302cb3388835ff02c097258d50" dependencies = [ "serde", ] @@ -1631,7 +1628,7 @@ dependencies = [ "serde", "serde_json", "serde_with_macros", - "time 0.3.27", + "time", ] [[package]] @@ -1654,9 +1651,9 @@ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" [[package]] name = "shlex" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" +checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" [[package]] name = "slab" @@ -1704,12 +1701,6 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "strsim" version = "0.10.0" @@ -1718,9 +1709,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.29" +version = "2.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" +checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" dependencies = [ "proc-macro2", "quote", @@ -1729,12 +1720,11 @@ dependencies = [ [[package]] name = "sys-locale" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0b9eefabb91675082b41eb94c3ecd91af7656caee3fb4961a07c0ec8c7ca6f" +checksum = "e801cf239ecd6ccd71f03d270d67dd53d13e90aab208bf4b8fe4ad957ea949b0" dependencies = [ "libc", - "windows-sys 0.45.0", ] [[package]] @@ -1752,18 +1742,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.47" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.47" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", @@ -1772,20 +1762,9 @@ dependencies = [ [[package]] name = "time" -version = "0.1.45" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "time" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb39ee79a6d8de55f48f2293a830e040392f1c5f16e336bdd1788cd0aadce07" +checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" dependencies = [ "deranged", "itoa", @@ -1802,9 +1781,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733d258752e9303d392b94b75230d07b0b9c489350c69b851fc6c065fde3e8f9" +checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" dependencies = [ "time-core", ] @@ -1971,9 +1950,9 @@ checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna 0.4.0", @@ -2007,12 +1986,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" diff --git a/Cargo.toml b/Cargo.toml index 6aa5ce0..be15b04 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.0.1" +version = "3.0.2" edition = "2021" license = "MIT" @@ -12,14 +12,14 @@ openssl = ["crunchy-cli-core/openssl"] openssl-static = ["crunchy-cli-core/openssl-static"] [dependencies] -tokio = { version = "1.31", features = ["macros", "rt-multi-thread", "time"], default-features = false } +tokio = { version = "1.32", features = ["macros", "rt-multi-thread", "time"], default-features = false } crunchy-cli-core = { path = "./crunchy-cli-core" } [build-dependencies] chrono = "0.4" -clap = { version = "4.3", features = ["string"] } -clap_complete = "4.3" +clap = { version = "4.4", features = ["string"] } +clap_complete = "4.4" clap_mangen = "0.2" crunchy-cli-core = { path = "./crunchy-cli-core" } diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 6c9b59c..f75c57d 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.0.1" +version = "3.0.2" edition = "2021" license = "MIT" @@ -12,7 +12,7 @@ openssl-static = ["reqwest/native-tls-alpn", "reqwest/native-tls-vendored", "dep [dependencies] anyhow = "1.0" async-trait = "0.1" -clap = { version = "4.3", features = ["derive", "string"] } +clap = { version = "4.4", features = ["derive", "string"] } chrono = "0.4" crunchyroll-rs = { version = "0.6.2", features = ["dash-stream"] } ctrlc = "3.4" @@ -30,10 +30,10 @@ sanitize-filename = "0.5" serde = "1.0" serde_json = "1.0" serde_plain = "1.0" -shlex = "1.1" +shlex = "1.2" sys-locale = "0.3" -tempfile = "3.7" -tokio = { version = "1.31", features = ["macros", "rt-multi-thread", "time"] } +tempfile = "3.8" +tokio = { version = "1.32", features = ["macros", "rt-multi-thread", "time"] } rustls-native-certs = { version = "0.6", optional = true } [build-dependencies] From 185b65fc9b58a5085d1fe538f1c2519eb7e63de5 Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 8 Sep 2023 22:49:58 +0200 Subject: [PATCH 092/272] Remove invalid character from AUR binary PKGBUILD --- .github/scripts/PKGBUILD.binary | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/PKGBUILD.binary b/.github/scripts/PKGBUILD.binary index 0117723..3493ee6 100644 --- a/.github/scripts/PKGBUILD.binary +++ b/.github/scripts/PKGBUILD.binary @@ -1,7 +1,7 @@ # Maintainer: ByteDream pkgname=crunchy-cli-bin pkgdesc="Command-line downloader for Crunchyroll" -arch=('x86_64', 'aarch64') +arch=('x86_64' 'aarch64') url="https://github.com/crunchy-labs/crunchy-cli" license=('MIT') From 8eda8df3f7dd048f9c5aae672f4cbb242d05b1bc Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 21 Sep 2023 13:46:23 +0200 Subject: [PATCH 093/272] Use native tls as default tls backend, add features to use rustls or openssl instead --- Cargo.lock | 98 ++++++++++++++++++++----------------- Cargo.toml | 20 +++++--- build.rs | 23 +++++++++ crunchy-cli-core/Cargo.toml | 6 ++- crunchy-cli-core/src/lib.rs | 4 +- src/main.rs | 8 +++ 6 files changed, 103 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b7e3911..506097c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.5" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" dependencies = [ "memchr", ] @@ -68,9 +68,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" +checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" [[package]] name = "anstyle-parse" @@ -140,9 +140,9 @@ dependencies = [ [[package]] name = "base64" -version = "0.21.3" +version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" [[package]] name = "base64-serde" @@ -177,9 +177,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytes" @@ -213,9 +213,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.30" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defd4e7873dbddba6c7c91e199c7fcb946abc4a6a4ac3195400bcfb01b5de877" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", @@ -238,9 +238,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.2" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a13b88d2c62ff462f88e4a121f17a82c1af05693a2f192b5c38d14de73c19f6" +checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" dependencies = [ "clap_builder", "clap_derive", @@ -248,9 +248,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.2" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" +checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" dependencies = [ "anstream", "anstyle", @@ -287,9 +287,9 @@ checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] name = "clap_mangen" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf8e5f34d85d9e0bbe2491d100a7a7c1007bb2467b518080bfe311e8947197a9" +checksum = "b44f35c514163027542f7147797ff930523eea288e03642727348ef1a9666f6b" dependencies = [ "clap", "roff", @@ -376,6 +376,7 @@ dependencies = [ "clap_complete", "clap_mangen", "crunchy-cli-core", + "native-tls", "tokio", ] @@ -795,9 +796,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "hex" @@ -1042,15 +1043,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] name = "linux-raw-sys" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" +checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" [[package]] name = "log" @@ -1115,12 +1116,17 @@ dependencies = [ [[package]] name = "native-tls" version = "0.2.11" -source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=570100d#570100d3391bd9aab7a390cfef0d1a28e8efe200" +source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=fdba246#fdba246a79986607cbdf573733445498bb6da2a9" dependencies = [ + "libc", "log", "openssl", "openssl-probe", "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", ] [[package]] @@ -1218,9 +1224,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.1.3+3.1.2" +version = "300.1.5+3.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd2c101a165fff9935e34def4669595ab1c7847943c42be86e21503e482be107" +checksum = "559068e4c12950d7dcaa1857a61725c0d38d4fc03ff8e070ab31a75d6e316491" dependencies = [ "cc", ] @@ -1276,9 +1282,9 @@ checksum = "31114a898e107c51bb1609ffaf55a0e011cf6a4d7f1170d0015a165082c0338b" [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ "unicode-ident", ] @@ -1450,9 +1456,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.11" +version = "0.38.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0c3dde1fc030af041adc40e79c0e7fbcf431dd24870053d187d7c66e4b87453" +checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" dependencies = [ "bitflags 2.4.0", "errno", @@ -1496,9 +1502,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.4" +version = "0.101.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d" +checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed" dependencies = [ "ring", "untrusted", @@ -1584,9 +1590,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.105" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -1687,9 +1693,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" +checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" dependencies = [ "libc", "windows-sys 0.48.0", @@ -1709,9 +1715,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.31" +version = "2.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" dependencies = [ "proc-macro2", "quote", @@ -1815,7 +1821,7 @@ dependencies = [ "mio", "num_cpus", "pin-project-lite", - "socket2 0.5.3", + "socket2 0.5.4", "tokio-macros", "windows-sys 0.48.0", ] @@ -1865,9 +1871,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" dependencies = [ "bytes", "futures-core", @@ -1911,9 +1917,9 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" @@ -1923,9 +1929,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -1938,9 +1944,9 @@ dependencies = [ [[package]] name = "unicode-width" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "untrusted" diff --git a/Cargo.toml b/Cargo.toml index be15b04..099bc6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,14 +6,22 @@ edition = "2021" license = "MIT" [features] -default = ["openssl-static"] +default = ["native-tls"] -openssl = ["crunchy-cli-core/openssl"] -openssl-static = ["crunchy-cli-core/openssl-static"] +rustls-tls = ["crunchy-cli-core/rustls-tls"] +native-tls = ["crunchy-cli-core/native-tls"] +openssl-tls = ["dep:native-tls", "native-tls/openssl", "crunchy-cli-core/openssl-tls"] +openssl-tls-static = ["dep:native-tls", "native-tls/openssl", "crunchy-cli-core/openssl-tls-static"] + +# deprecated +openssl = ["openssl-tls"] +openssl-static = ["openssl-tls-static"] [dependencies] tokio = { version = "1.32", features = ["macros", "rt-multi-thread", "time"], default-features = false } +native-tls = { version = "0.2.11", optional = true } + crunchy-cli-core = { path = "./crunchy-cli-core" } [build-dependencies] @@ -28,9 +36,9 @@ crunchy-cli-core = { path = "./crunchy-cli-core" } members = ["crunchy-cli-core"] [patch.crates-io] -# fork of the `native-tls` crate which uses 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 = "570100d" } +# 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 = "fdba246" } [profile.release] strip = true diff --git a/build.rs b/build.rs index 7056c67..5b464c4 100644 --- a/build.rs +++ b/build.rs @@ -3,6 +3,29 @@ use clap_complete::shells; use std::path::{Path, PathBuf}; fn main() -> std::io::Result<()> { + let rustls_tls = cfg!(feature = "rustls-tls"); + let native_tls = cfg!(feature = "native-tls"); + let openssl_tls = cfg!(any(feature = "openssl-tls", feature = "openssl-tls-static")); + + if rustls_tls as u8 + native_tls as u8 + openssl_tls as u8 > 1 { + let active_tls_backend = if openssl_tls { + "openssl" + } else if native_tls { + "native tls" + } else { + "rustls" + }; + + println!("cargo:warning=Multiple tls backends are activated (through the '*-tls' features). Consider to activate only one as it is not possible to change the backend during runtime. The active backend for this build will be '{}'.", active_tls_backend) + } + + if cfg!(feature = "openssl") { + println!("cargo:warning=The 'openssl' feature is deprecated and will be removed in a future version. Use the 'openssl-tls' feature instead.") + } + if cfg!(feature = "openssl-static") { + println!("cargo:warning=The 'openssl-static' feature is deprecated and will be removed in a future version. Use the 'openssl-tls-static' feature instead.") + } + // note that we're using an anti-pattern here / violate the rust conventions. build script are // not supposed to write outside of 'OUT_DIR'. to have the generated files in the build "root" // (the same directory where the output binary lives) is much simpler than in 'OUT_DIR' since diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index f75c57d..8288bf1 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -6,8 +6,10 @@ edition = "2021" license = "MIT" [features] -openssl = ["reqwest/native-tls-alpn", "dep:rustls-native-certs"] -openssl-static = ["reqwest/native-tls-alpn", "reqwest/native-tls-vendored", "dep:rustls-native-certs"] +rustls-tls = ["reqwest/rustls-tls"] +native-tls = ["reqwest/native-tls", "reqwest/native-tls-alpn"] +openssl-tls = ["reqwest/native-tls", "reqwest/native-tls-alpn", "dep:rustls-native-certs"] +openssl-tls-static = ["reqwest/native-tls", "reqwest/native-tls-alpn", "reqwest/native-tls-vendored", "dep:rustls-native-certs"] [dependencies] anyhow = "1.0" diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index 50b1e4c..02bef6f 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -276,7 +276,7 @@ async fn crunchyroll_session(cli: &mut Cli) -> Result { builder = builder.user_agent(ua) } - #[cfg(any(feature = "openssl", feature = "openssl-static"))] + #[cfg(any(feature = "openssl-tls", feature = "openssl-tls-static"))] let client = { let mut builder = builder.use_native_tls().tls_built_in_root_certs(false); @@ -288,7 +288,7 @@ async fn crunchyroll_session(cli: &mut Cli) -> Result { builder.build().unwrap() }; - #[cfg(not(any(feature = "openssl", feature = "openssl-static")))] + #[cfg(not(any(feature = "openssl-tls", feature = "openssl-tls-static")))] let client = builder.build().unwrap(); client diff --git a/src/main.rs b/src/main.rs index 5e1d695..da3c699 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,11 @@ +#[cfg(not(any( + feature = "rustls-tls", + feature = "native-tls", + feature = "openssl-tls", + feature = "openssl-tls-static" +)))] +compile_error!("At least one tls feature must be activated"); + #[tokio::main] async fn main() { crunchy_cli_core::cli_entrypoint().await From 64428ea7d175a2137b755456662914adc73f0c6a Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 21 Sep 2023 19:18:29 +0200 Subject: [PATCH 094/272] Rename native-tls crate to prevent false-positive build warnings --- Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 099bc6f..b5ae0a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,8 +10,8 @@ default = ["native-tls"] rustls-tls = ["crunchy-cli-core/rustls-tls"] native-tls = ["crunchy-cli-core/native-tls"] -openssl-tls = ["dep:native-tls", "native-tls/openssl", "crunchy-cli-core/openssl-tls"] -openssl-tls-static = ["dep:native-tls", "native-tls/openssl", "crunchy-cli-core/openssl-tls-static"] +openssl-tls = ["dep:native-tls-crate", "native-tls-crate/openssl", "crunchy-cli-core/openssl-tls"] +openssl-tls-static = ["dep:native-tls-crate", "native-tls-crate/openssl", "crunchy-cli-core/openssl-tls-static"] # deprecated openssl = ["openssl-tls"] @@ -20,7 +20,7 @@ openssl-static = ["openssl-tls-static"] [dependencies] tokio = { version = "1.32", features = ["macros", "rt-multi-thread", "time"], default-features = false } -native-tls = { version = "0.2.11", optional = true } +native-tls-crate = { package = "native-tls", version = "0.2.11", optional = true } crunchy-cli-core = { path = "./crunchy-cli-core" } From 01913e0db3ba9f9dc78f1759734ce59f1c6c8790 Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 21 Sep 2023 19:20:00 +0200 Subject: [PATCH 095/272] Adjust ci and PKGBUILD build args to feature changes --- .github/scripts/PKGBUILD.source | 2 +- .github/workflows/ci.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/scripts/PKGBUILD.source b/.github/scripts/PKGBUILD.source index 015efe3..af6b8e1 100644 --- a/.github/scripts/PKGBUILD.source +++ b/.github/scripts/PKGBUILD.source @@ -19,7 +19,7 @@ build() { export CARGO_HOME="$srcdir/cargo-home" export RUSTUP_TOOLCHAIN=stable - cargo build --release --no-default-features --features openssl + cargo build --release } package() { diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f020b68..7493041 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,7 +36,7 @@ jobs: run: cargo install --force cross - name: Build - run: cross build --release --all-features --target ${{ matrix.toolchain }} + run: cross build --release --no-default-features --features openssl-tls-static --target ${{ matrix.toolchain }} - name: Upload binary artifact uses: actions/upload-artifact@v3 @@ -77,7 +77,7 @@ jobs: key: x86_64-apple-darwin-cargo-${{ hashFiles('**/Cargo.lock') }} - name: Build - run: cargo build --release --all-features --target x86_64-apple-darwin + run: cargo build --release --target x86_64-apple-darwin - name: Upload binary artifact uses: actions/upload-artifact@v3 @@ -110,7 +110,7 @@ jobs: - name: Build shell: msys2 {0} - run: cargo build --release --all-features --target x86_64-pc-windows-gnu + run: cargo build --release --target x86_64-pc-windows-gnu - name: Upload binary artifact uses: actions/upload-artifact@v3 From 3e21ca4fe7c1831e857118a391bd01e2146c36ab Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 22 Sep 2023 11:52:39 +0200 Subject: [PATCH 096/272] Update dependencies and version --- Cargo.lock | 17 +++++++++-------- Cargo.toml | 2 +- crunchy-cli-core/Cargo.toml | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 506097c..09cad3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -369,7 +369,7 @@ dependencies = [ [[package]] name = "crunchy-cli" -version = "3.0.2" +version = "3.0.3" dependencies = [ "chrono", "clap", @@ -382,7 +382,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.0.2" +version = "3.0.3" dependencies = [ "anyhow", "async-trait", @@ -549,12 +549,13 @@ dependencies = [ [[package]] name = "dialoguer" -version = "0.10.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59c6f2989294b9a498d3ad5491a79c6deb604617378e1cdc4bfc1c1361fe2f87" +checksum = "658bce805d770f407bc62102fca7c2c64ceef2fbcb2b8bd19d2765ce093980de" dependencies = [ "console", "shell-words", + "thiserror", ] [[package]] @@ -975,9 +976,9 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.6" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b297dc40733f23a0e52728a58fa9489a5b7638a324932de16b41adc3ef80730" +checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" dependencies = [ "console", "instant", @@ -1502,9 +1503,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.5" +version = "0.101.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed" +checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" dependencies = [ "ring", "untrusted", diff --git a/Cargo.toml b/Cargo.toml index b5ae0a6..e5882d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.0.2" +version = "3.0.3" edition = "2021" license = "MIT" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 8288bf1..fc298f3 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.0.2" +version = "3.0.3" edition = "2021" license = "MIT" @@ -18,7 +18,7 @@ clap = { version = "4.4", features = ["derive", "string"] } chrono = "0.4" crunchyroll-rs = { version = "0.6.2", features = ["dash-stream"] } ctrlc = "3.4" -dialoguer = { version = "0.10", default-features = false } +dialoguer = { version = "0.11", default-features = false } dirs = "5.0" derive_setters = "0.1" fs2 = "0.4" From a93a1fa807758cf41829233281ca5832a52c6151 Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 22 Sep 2023 12:11:00 +0200 Subject: [PATCH 097/272] Fix env variable resolving in publish pipeline --- .github/workflows/publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 80cb5bb..1599111 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -34,7 +34,7 @@ jobs: commit_username: release-action commit_email: ${{ secrets.AUR_EMAIL }} ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }} - commit_message: Update to version {{ env.RELEASE_VERSION }} + commit_message: Update to version ${{ env.RELEASE_VERSION }} - name: Generate crunchy-cli-bin sha sums run: | @@ -67,4 +67,4 @@ jobs: commit_username: release-action commit_email: ${{ secrets.AUR_EMAIL }} ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }} - commit_message: Update to version {{ env.RELEASE_VERSION }} + commit_message: Update to version ${{ env.RELEASE_VERSION }} From d79197edc6fb9bf2bac699d2f6b55bfae4d7dea7 Mon Sep 17 00:00:00 2001 From: bytedream Date: Sat, 23 Sep 2023 16:56:38 +0200 Subject: [PATCH 098/272] Use async mutex and channel instead of the std equivalents --- crunchy-cli-core/src/utils/download.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index 4531c69..29f160a 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -17,9 +17,11 @@ use std::env; use std::io::Write; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; -use std::sync::{mpsc, Arc, Mutex}; +use std::sync::Arc; use std::time::Duration; use tempfile::TempPath; +use tokio::sync::mpsc::unbounded_channel; +use tokio::sync::Mutex; use tokio::task::JoinSet; #[derive(Clone, Debug)] @@ -576,7 +578,7 @@ pub async fn download_segments( segs[i - ((i / cpus) * cpus)].push(segment); } - let (sender, receiver) = mpsc::channel(); + let (sender, mut receiver) = unbounded_channel(); let mut join_set: JoinSet> = JoinSet::new(); for num in 0..cpus { @@ -629,7 +631,7 @@ pub async fn download_segments( buf = VariantSegment::decrypt(buf.borrow_mut(), segment.key)?.to_vec(); - let mut c = thread_count.lock().unwrap(); + let mut c = thread_count.lock().await; debug!( "Downloaded and decrypted segment [{}/{} {:.2}%] {}", num + (i * cpus) + 1, @@ -663,7 +665,7 @@ pub async fn download_segments( // the segment number and the values the corresponding bytes let mut data_pos = 0; let mut buf: BTreeMap> = BTreeMap::new(); - for (pos, bytes) in receiver.iter() { + while let Some((pos, bytes)) = receiver.recv().await { // if the position is lower than 0, an error occurred in the sending download thread if pos < 0 { break; From f48474ba776bce8a6d00e6f0c97f38cf047b8eb4 Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 27 Sep 2023 00:03:26 +0200 Subject: [PATCH 099/272] Remove numbers from binary PKGBUILD env variables --- .github/scripts/PKGBUILD.binary | 4 ++-- .github/workflows/publish.yml | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/scripts/PKGBUILD.binary b/.github/scripts/PKGBUILD.binary index 3493ee6..00fee47 100644 --- a/.github/scripts/PKGBUILD.binary +++ b/.github/scripts/PKGBUILD.binary @@ -24,8 +24,8 @@ source_aarch64=( "LICENSE::https://raw.githubusercontent.com/crunchy-labs/crunchy-cli/v${pkgver}/LICENSE" ) noextract=("manpages.zip" "completions.zip") -sha256sums_x86_64=('$CI_x86_64_SHA_SUM' '$CI_MANPAGES_SHA_SUM' '$CI_COMPLETIONS_SHA_SUM' '$CI_LICENSE_SHA_SUM') -sha256sums_aarch64=('$CI_aarch64_SHA_SUM' '$CI_MANPAGES_SHA_SUM' '$CI_COMPLETIONS_SHA_SUM' '$CI_LICENSE_SHA_SUM') +sha256sums_x86_64=('$CI_AMD_BINARY_SHA_SUM' '$CI_MANPAGES_SHA_SUM' '$CI_COMPLETIONS_SHA_SUM' '$CI_LICENSE_SHA_SUM') +sha256sums_aarch64=('$CI_ARM_BINARY_SHA_SUM' '$CI_MANPAGES_SHA_SUM' '$CI_COMPLETIONS_SHA_SUM' '$CI_LICENSE_SHA_SUM') package() { cd "$srcdir" diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 1599111..f777f9e 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -52,12 +52,12 @@ jobs: - name: Generate crunchy-cli-bin PKGBUILD env: CI_PKG_VERSION: ${{ env.RELEASE_VERSION }} - CI_x86_64_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_x86_64_SHA256 }} - CI_aarch64_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_aarch64_SHA256 }} + CI_AMD_BINARY_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_x86_64_SHA256 }} + CI_ARM_BINARY_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_aarch64_SHA256 }} CI_MANPAGES_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_MANPAGES_SHA256 }} CI_COMPLETIONS_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_COMPLETIONS_SHA256 }} CI_LICENSE_SHA_SUM: ${{ env.CRUNCHY_CLI_BIN_LICENSE_SHA256 }} - run: envsubst '$CI_PKG_VERSION,$CI_x86_64_SHA_SUM,$CI_aarch64_SHA_SUM,$CI_COMPLETIONS_SHA_SUM,$CI_MANPAGES_SHA_SUM,$CI_LICENSE_SHA_SUM' < .github/scripts/PKGBUILD.binary > PKGBUILD + run: envsubst '$CI_PKG_VERSION,$CI_AMD_BINARY_SHA_SUM,$CI_ARM_BINARY_SHA_SUM,$CI_COMPLETIONS_SHA_SUM,$CI_MANPAGES_SHA_SUM,$CI_LICENSE_SHA_SUM' < .github/scripts/PKGBUILD.binary > PKGBUILD - name: Publish crunchy-cli-bin to AUR uses: KSXGitHub/github-actions-deploy-aur@v2.7.0 From 9596175f7fe2a40fe2f0c20772d373aa13150a0f Mon Sep 17 00:00:00 2001 From: Valentine Briese Date: Wed, 11 Oct 2023 18:24:45 -0700 Subject: [PATCH 100/272] Add FFmpeg Apple hardware acceleration --- crunchy-cli-core/src/utils/ffmpeg.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/utils/ffmpeg.rs b/crunchy-cli-core/src/utils/ffmpeg.rs index 210b0f7..3407d91 100644 --- a/crunchy-cli-core/src/utils/ffmpeg.rs +++ b/crunchy-cli-core/src/utils/ffmpeg.rs @@ -66,7 +66,8 @@ ffmpeg_enum! { ffmpeg_enum! { enum FFmpegHwAccel { - Nvidia + Nvidia, + Apple } } @@ -275,6 +276,9 @@ impl FFmpegPreset { ]); output.extend(["-c:v", "h264_nvenc", "-c:a", "copy"]) } + FFmpegHwAccel::Apple => { + output.extend(["-c:v", "h264_videotoolbox", "-c:a", "copy"]) + } } } else { output.extend(["-c:v", "libx264", "-c:a", "copy"]) @@ -300,6 +304,9 @@ impl FFmpegPreset { ]); output.extend(["-c:v", "hevc_nvenc", "-c:a", "copy"]) } + FFmpegHwAccel::Apple => { + output.extend(["-c:v", "hevc_videotoolbox", "-c:a", "copy"]) + } } } else { output.extend(["-c:v", "libx265", "-c:a", "copy"]) From 610593a79547b577b46707f996adefa7cf27db15 Mon Sep 17 00:00:00 2001 From: Valentine Briese Date: Wed, 11 Oct 2023 18:26:51 -0700 Subject: [PATCH 101/272] Make H265 codec compatible with Apple HEVC standards --- crunchy-cli-core/src/utils/ffmpeg.rs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/crunchy-cli-core/src/utils/ffmpeg.rs b/crunchy-cli-core/src/utils/ffmpeg.rs index 3407d91..6145fcf 100644 --- a/crunchy-cli-core/src/utils/ffmpeg.rs +++ b/crunchy-cli-core/src/utils/ffmpeg.rs @@ -302,14 +302,26 @@ impl FFmpegPreset { "-c:v", "h264_cuvid", ]); - output.extend(["-c:v", "hevc_nvenc", "-c:a", "copy"]) - } - FFmpegHwAccel::Apple => { - output.extend(["-c:v", "hevc_videotoolbox", "-c:a", "copy"]) + output.extend([ + "-c:v", + "hevc_nvenc", + "-c:a", + "copy", + "-tag:v", + "hvc1", + ]) } + FFmpegHwAccel::Apple => output.extend([ + "-c:v", + "hevc_videotoolbox", + "-c:a", + "copy", + "-tag:v", + "hvc1", + ]), } } else { - output.extend(["-c:v", "libx265", "-c:a", "copy"]) + output.extend(["-c:v", "libx265", "-c:a", "copy", "-tag:v", "hvc1"]) } match quality { From 7095e2b8b6464edeb9d79a21540365d02133a93b Mon Sep 17 00:00:00 2001 From: Valentine Briese Date: Wed, 11 Oct 2023 18:54:47 -0700 Subject: [PATCH 102/272] Use `-q:v` FFmpeg option for Apple hardware acceleration --- crunchy-cli-core/src/utils/ffmpeg.rs | 65 +++++++++++++++++++--------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/crunchy-cli-core/src/utils/ffmpeg.rs b/crunchy-cli-core/src/utils/ffmpeg.rs index 6145fcf..af29bfd 100644 --- a/crunchy-cli-core/src/utils/ffmpeg.rs +++ b/crunchy-cli-core/src/utils/ffmpeg.rs @@ -263,6 +263,12 @@ impl FFmpegPreset { match codec { FFmpegCodec::H264 => { + let mut crf_quality = || match quality { + FFmpegQuality::Lossless => output.extend(["-crf", "18"]), + FFmpegQuality::Normal => (), + FFmpegQuality::Low => output.extend(["-crf", "35"]), + }; + if let Some(hwaccel) = hwaccel_opt { match hwaccel { FFmpegHwAccel::Nvidia => { @@ -274,23 +280,37 @@ impl FFmpegPreset { "-c:v", "h264_cuvid", ]); + crf_quality(); output.extend(["-c:v", "h264_nvenc", "-c:a", "copy"]) } FFmpegHwAccel::Apple => { + // Apple's Video Toolbox encoders ignore `-crf`, + // use `-q:v` instead. It's on a scale of 1-100, + // 100 being lossless. Just did some math + // ((-a/51+1)*99+1 where `a` is the old crf value) + // so these settings very likely need some more + // tweeking. + match quality { + FFmpegQuality::Lossless => output.extend(["-q:v", "65"]), + FFmpegQuality::Normal => (), + FFmpegQuality::Low => output.extend(["-q:v", "32"]), + } + output.extend(["-c:v", "h264_videotoolbox", "-c:a", "copy"]) } } } else { + crf_quality(); output.extend(["-c:v", "libx264", "-c:a", "copy"]) } - - match quality { - FFmpegQuality::Lossless => output.extend(["-crf", "18"]), - FFmpegQuality::Normal => (), - FFmpegQuality::Low => output.extend(["-crf", "35"]), - } } FFmpegCodec::H265 => { + let mut crf_quality = || match quality { + FFmpegQuality::Lossless => output.extend(["-crf", "20"]), + FFmpegQuality::Normal => (), + FFmpegQuality::Low => output.extend(["-crf", "35"]), + }; + if let Some(hwaccel) = hwaccel_opt { match hwaccel { FFmpegHwAccel::Nvidia => { @@ -302,6 +322,7 @@ impl FFmpegPreset { "-c:v", "h264_cuvid", ]); + crf_quality(); output.extend([ "-c:v", "hevc_nvenc", @@ -311,24 +332,28 @@ impl FFmpegPreset { "hvc1", ]) } - FFmpegHwAccel::Apple => output.extend([ - "-c:v", - "hevc_videotoolbox", - "-c:a", - "copy", - "-tag:v", - "hvc1", - ]), + FFmpegHwAccel::Apple => { + // See the comment that starts on line 287. + match quality { + FFmpegQuality::Lossless => output.extend(["-q:v", "61"]), + FFmpegQuality::Normal => (), + FFmpegQuality::Low => output.extend(["-q:v", "32"]), + } + + output.extend([ + "-c:v", + "hevc_videotoolbox", + "-c:a", + "copy", + "-tag:v", + "hvc1", + ]) + } } } else { + crf_quality(); output.extend(["-c:v", "libx265", "-c:a", "copy", "-tag:v", "hvc1"]) } - - match quality { - FFmpegQuality::Lossless => output.extend(["-crf", "20"]), - FFmpegQuality::Normal => (), - FFmpegQuality::Low => output.extend(["-crf", "35"]), - } } FFmpegCodec::Av1 => { output.extend(["-c:v", "libsvtav1", "-c:a", "copy"]); From e5db8e95043c7d9dabeb6e05c0f2f6311563a58d Mon Sep 17 00:00:00 2001 From: Valentine Briese Date: Thu, 12 Oct 2023 12:20:06 -0700 Subject: [PATCH 103/272] Fix `ffmpeg-preset` option in `download` command (#254) --- crunchy-cli-core/src/download/command.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index 031ed04..baf27bf 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -148,7 +148,8 @@ impl Execute for Download { Some("mpegts".to_string()) } else { None - }); + }) + .ffmpeg_preset(self.ffmpeg_preset.clone().unwrap_or_default()); for mut single_formats in single_format_collection.into_iter() { // the vec contains always only one item From 13335c020b19f80cde7e56455d4380c9921a681f Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 13 Oct 2023 11:41:56 +0200 Subject: [PATCH 104/272] Sanitize the full output filename (#253) --- crunchy-cli-core/src/utils/format.rs | 80 +++++++++++++--------------- 1 file changed, 36 insertions(+), 44 deletions(-) diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index b6dcf35..618f7d5 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -371,51 +371,43 @@ impl Format { /// Formats the given string if it has specific pattern in it. It's possible to sanitize it which /// removes characters which can cause failures if the output string is used as a file name. pub fn format_path(&self, path: PathBuf, sanitize: bool) -> PathBuf { - let sanitize_func = if sanitize { - |s: &str| sanitize_filename::sanitize(s) + let path = path + .to_string_lossy() + .to_string() + .replace("{title}", &self.title) + .replace( + "{audio}", + &self + .locales + .iter() + .map(|(a, _)| a.to_string()) + .collect::>() + .join("|"), + ) + .replace("{resolution}", &self.resolution.to_string()) + .replace("{series_id}", &self.series_id) + .replace("{series_name}", &self.series_name) + .replace("{season_id}", &self.season_id) + .replace("{season_name}", &self.season_title) + .replace( + "{season_number}", + &format!("{:0>2}", self.season_number.to_string()), + ) + .replace("{episode_id}", &self.episode_id) + .replace( + "{episode_number}", + &format!("{:0>2}", self.episode_number.to_string()), + ) + .replace( + "{relative_episode_number}", + &self.relative_episode_number.unwrap_or_default().to_string(), + ); + + if sanitize { + PathBuf::from(sanitize_filename::sanitize(path)) } else { - // converting this to a string is actually unnecessary - |s: &str| s.to_string() - }; - - let as_string = path.to_string_lossy().to_string(); - - PathBuf::from( - as_string - .replace("{title}", &sanitize_func(&self.title)) - .replace( - "{audio}", - &sanitize_func( - &self - .locales - .iter() - .map(|(a, _)| a.to_string()) - .collect::>() - .join("|"), - ), - ) - .replace("{resolution}", &sanitize_func(&self.resolution.to_string())) - .replace("{series_id}", &sanitize_func(&self.series_id)) - .replace("{series_name}", &sanitize_func(&self.series_name)) - .replace("{season_id}", &sanitize_func(&self.season_id)) - .replace("{season_name}", &sanitize_func(&self.season_title)) - .replace( - "{season_number}", - &sanitize_func(&format!("{:0>2}", self.season_number.to_string())), - ) - .replace("{episode_id}", &sanitize_func(&self.episode_id)) - .replace( - "{episode_number}", - &sanitize_func(&format!("{:0>2}", self.episode_number.to_string())), - ) - .replace( - "{relative_episode_number}", - &sanitize_func(&format!( - "{:0>2}", - self.relative_episode_number.unwrap_or_default().to_string() - )), - ), - ) + PathBuf::from(path) + } } pub fn visual_output(&self, dst: &Path) { From 81385ef6ce257522dc197d2ce8dd9a252d2f99c7 Mon Sep 17 00:00:00 2001 From: bytedream Date: Sun, 15 Oct 2023 20:49:03 +0200 Subject: [PATCH 105/272] Add relative_sequence_number format option (#206, #241, #246) --- crunchy-cli-core/src/archive/command.rs | 24 +++++---- crunchy-cli-core/src/archive/filter.rs | 64 +++++++++++++++--------- crunchy-cli-core/src/download/command.rs | 24 +++++---- crunchy-cli-core/src/download/filter.rs | 60 +++++++++++----------- crunchy-cli-core/src/utils/format.rs | 33 +++++++++--- 5 files changed, 122 insertions(+), 83 deletions(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 7ce1658..ffdc00c 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -39,17 +39,19 @@ pub struct Archive { #[arg(help = "Name of the output file")] #[arg(long_help = "Name of the output file.\ If you use one of the following pattern they will get replaced:\n \ - {title} → Title of the video\n \ - {series_name} → Name of the series\n \ - {season_name} → Name of the season\n \ - {audio} → Audio language of the video\n \ - {resolution} → Resolution of the video\n \ - {season_number} → Number of the season\n \ - {episode_number} → Number of the episode\n \ - {relative_episode_number} → Number of the episode relative to its season\n \ - {series_id} → ID of the series\n \ - {season_id} → ID of the season\n \ - {episode_id} → ID of the episode")] + {title} → Title of the video\n \ + {series_name} → Name of the series\n \ + {season_name} → Name of the season\n \ + {audio} → Audio language of the video\n \ + {resolution} → Resolution of the video\n \ + {season_number} → Number of the season\n \ + {episode_number} → Number of the episode\n \ + {relative_episode_number} → Number of the episode relative to its season\n \ + {sequence_number} → Like '{episode_number}' but without possible non-number characters\n \ + {relative_sequence_number} → Like '{relative_episode_number}' but with support for episode 0's and .5's\n \ + {series_id} → ID of the series\n \ + {season_id} → ID of the season\n \ + {episode_id} → ID of the episode")] #[arg(short, long, default_value = "{title}.mkv")] pub(crate) output: String, diff --git a/crunchy-cli-core/src/archive/filter.rs b/crunchy-cli-core/src/archive/filter.rs index 851b4b5..c2cc206 100644 --- a/crunchy-cli-core/src/archive/filter.rs +++ b/crunchy-cli-core/src/archive/filter.rs @@ -18,7 +18,7 @@ pub(crate) struct ArchiveFilter { url_filter: UrlFilter, archive: Archive, interactive_input: bool, - season_episode_count: HashMap>, + season_episodes: HashMap>, season_subtitles_missing: Vec, season_sorting: Vec, visited: Visited, @@ -30,7 +30,7 @@ impl ArchiveFilter { url_filter, archive, interactive_input, - season_episode_count: HashMap::new(), + season_episodes: HashMap::new(), season_subtitles_missing: vec![], season_sorting: vec![], visited: Visited::None, @@ -226,12 +226,12 @@ impl Filter for ArchiveFilter { episodes.extend(eps) } - if Format::has_relative_episodes_fmt(&self.archive.output) { + if Format::has_relative_fmt(&self.archive.output) { for episode in episodes.iter() { - self.season_episode_count + self.season_episodes .entry(episode.season_id.clone()) .or_insert(vec![]) - .push(episode.id.clone()) + .push(episode.clone()) } } @@ -299,22 +299,34 @@ impl Filter for ArchiveFilter { episodes.push((episode.clone(), episode.subtitle_locales.clone())) } - let relative_episode_number = if Format::has_relative_episodes_fmt(&self.archive.output) { - if self.season_episode_count.get(&episode.season_id).is_none() { - let season_episodes = episode.season().await?.episodes().await?; - self.season_episode_count.insert( - episode.season_id.clone(), - season_episodes.into_iter().map(|e| e.id).collect(), - ); + let mut relative_episode_number = None; + let mut relative_sequence_number = None; + // get the relative episode number. only done if the output string has the pattern to include + // the relative episode number as this requires some extra fetching + if Format::has_relative_fmt(&self.archive.output) { + let season_eps = match self.season_episodes.get(&episode.season_id) { + Some(eps) => eps, + None => { + self.season_episodes.insert( + episode.season_id.clone(), + episode.season().await?.episodes().await?, + ); + self.season_episodes.get(&episode.season_id).unwrap() + } + }; + let mut non_integer_sequence_number_count = 0; + for (i, ep) in season_eps.iter().enumerate() { + if ep.sequence_number.fract() != 0.0 || ep.sequence_number == 0.0 { + non_integer_sequence_number_count += 1; + } + if ep.id == episode.id { + relative_episode_number = Some(i + 1); + relative_sequence_number = + Some((i + 1 - non_integer_sequence_number_count) as f32); + break; + } } - let relative_episode_number = self - .season_episode_count - .get(&episode.season_id) - .unwrap() - .iter() - .position(|id| id == &episode.id) - .map(|index| index + 1); - if relative_episode_number.is_none() { + if relative_episode_number.is_none() || relative_sequence_number.is_none() { warn!( "Failed to get relative episode number for episode {} ({}) of {} season {}", episode.episode_number, @@ -323,16 +335,18 @@ impl Filter for ArchiveFilter { episode.season_number, ) } - relative_episode_number - } else { - None - }; + } Ok(Some( episodes .into_iter() .map(|(e, s)| { - SingleFormat::new_from_episode(e, s, relative_episode_number.map(|n| n as u32)) + SingleFormat::new_from_episode( + e, + s, + relative_episode_number.map(|n| n as u32), + relative_sequence_number, + ) }) .collect(), )) diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index baf27bf..6d059ef 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -35,17 +35,19 @@ pub struct Download { #[arg(help = "Name of the output file")] #[arg(long_help = "Name of the output file.\ If you use one of the following pattern they will get replaced:\n \ - {title} → Title of the video\n \ - {series_name} → Name of the series\n \ - {season_name} → Name of the season\n \ - {audio} → Audio language of the video\n \ - {resolution} → Resolution of the video\n \ - {season_number} → Number of the season\n \ - {episode_number} → Number of the episode\n \ - {relative_episode_number} → Number of the episode relative to its season\n \ - {series_id} → ID of the series\n \ - {season_id} → ID of the season\n \ - {episode_id} → ID of the episode")] + {title} → Title of the video\n \ + {series_name} → Name of the series\n \ + {season_name} → Name of the season\n \ + {audio} → Audio language of the video\n \ + {resolution} → Resolution of the video\n \ + {season_number} → Number of the season\n \ + {episode_number} → Number of the episode\n \ + {relative_episode_number} → Number of the episode relative to its season\n \ + {sequence_number} → Like '{episode_number}' but without possible non-number characters\n \ + {relative_sequence_number} → Like '{relative_episode_number}' but with support for episode 0's and .5's\n \ + {series_id} → ID of the series\n \ + {season_id} → ID of the season\n \ + {episode_id} → ID of the episode")] #[arg(short, long, default_value = "{title}.mp4")] pub(crate) output: String, diff --git a/crunchy-cli-core/src/download/filter.rs b/crunchy-cli-core/src/download/filter.rs index 31c0db6..c5aef7e 100644 --- a/crunchy-cli-core/src/download/filter.rs +++ b/crunchy-cli-core/src/download/filter.rs @@ -12,7 +12,7 @@ pub(crate) struct DownloadFilter { url_filter: UrlFilter, download: Download, interactive_input: bool, - season_episode_count: HashMap>, + season_episodes: HashMap>, season_subtitles_missing: Vec, season_visited: bool, } @@ -23,7 +23,7 @@ impl DownloadFilter { url_filter, download, interactive_input, - season_episode_count: HashMap::new(), + season_episodes: HashMap::new(), season_subtitles_missing: vec![], season_visited: false, } @@ -107,12 +107,12 @@ impl Filter for DownloadFilter { let mut episodes = season.episodes().await?; - if Format::has_relative_episodes_fmt(&self.download.output) { + if Format::has_relative_fmt(&self.download.output) { for episode in episodes.iter() { - self.season_episode_count + self.season_episodes .entry(episode.season_number) .or_insert(vec![]) - .push(episode.id.clone()) + .push(episode.clone()) } } @@ -189,28 +189,34 @@ impl Filter for DownloadFilter { } } + let mut relative_episode_number = None; + let mut relative_sequence_number = None; // get the relative episode number. only done if the output string has the pattern to include // the relative episode number as this requires some extra fetching - let relative_episode_number = if Format::has_relative_episodes_fmt(&self.download.output) { - if self - .season_episode_count - .get(&episode.season_number) - .is_none() - { - let season_episodes = episode.season().await?.episodes().await?; - self.season_episode_count.insert( - episode.season_number, - season_episodes.into_iter().map(|e| e.id).collect(), - ); + if Format::has_relative_fmt(&self.download.output) { + let season_eps = match self.season_episodes.get(&episode.season_number) { + Some(eps) => eps, + None => { + self.season_episodes.insert( + episode.season_number, + episode.season().await?.episodes().await?, + ); + self.season_episodes.get(&episode.season_number).unwrap() + } + }; + let mut non_integer_sequence_number_count = 0; + for (i, ep) in season_eps.iter().enumerate() { + if ep.sequence_number.fract() != 0.0 || ep.sequence_number == 0.0 { + non_integer_sequence_number_count += 1; + } + if ep.id == episode.id { + relative_episode_number = Some(i + 1); + relative_sequence_number = + Some((i + 1 - non_integer_sequence_number_count) as f32); + break; + } } - let relative_episode_number = self - .season_episode_count - .get(&episode.season_number) - .unwrap() - .iter() - .position(|id| id == &episode.id) - .map(|index| index + 1); - if relative_episode_number.is_none() { + if relative_episode_number.is_none() || relative_sequence_number.is_none() { warn!( "Failed to get relative episode number for episode {} ({}) of {} season {}", episode.episode_number, @@ -219,10 +225,7 @@ impl Filter for DownloadFilter { episode.season_number, ) } - relative_episode_number - } else { - None - }; + } Ok(Some(SingleFormat::new_from_episode( episode.clone(), @@ -234,6 +237,7 @@ impl Filter for DownloadFilter { } }), relative_episode_number.map(|n| n as u32), + relative_sequence_number, ))) } diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index 618f7d5..f32d82a 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -29,8 +29,9 @@ pub struct SingleFormat { pub episode_id: String, pub episode_number: String, - pub sequence_number: f32, pub relative_episode_number: Option, + pub sequence_number: f32, + pub relative_sequence_number: Option, pub duration: Duration, @@ -42,6 +43,7 @@ impl SingleFormat { episode: Episode, subtitles: Vec, relative_episode_number: Option, + relative_sequence_number: Option, ) -> Self { Self { identifier: if episode.identifier.is_empty() { @@ -73,6 +75,7 @@ impl SingleFormat { }, sequence_number: episode.sequence_number, relative_episode_number, + relative_sequence_number, duration: episode.duration, source: episode.into(), } @@ -92,8 +95,9 @@ impl SingleFormat { season_number: 1, episode_id: movie.id.clone(), episode_number: "1".to_string(), - sequence_number: 1.0, relative_episode_number: Some(1), + sequence_number: 1.0, + relative_sequence_number: Some(1.0), duration: movie.duration, source: movie.into(), } @@ -113,8 +117,9 @@ impl SingleFormat { season_number: 1, episode_id: music_video.id.clone(), episode_number: "1".to_string(), - sequence_number: 1.0, relative_episode_number: Some(1), + sequence_number: 1.0, + relative_sequence_number: Some(1.0), duration: music_video.duration, source: music_video.into(), } @@ -134,8 +139,9 @@ impl SingleFormat { season_number: 1, episode_id: concert.id.clone(), episode_number: "1".to_string(), - sequence_number: 1.0, relative_episode_number: Some(1), + sequence_number: 1.0, + relative_sequence_number: Some(1.0), duration: concert.duration, source: concert.into(), } @@ -328,8 +334,9 @@ pub struct Format { pub episode_id: String, pub episode_number: String, - pub sequence_number: f32, pub relative_episode_number: Option, + pub sequence_number: f32, + pub relative_sequence_number: Option, } impl Format { @@ -363,8 +370,9 @@ impl Format { season_number: first_format.season_number, episode_id: first_format.episode_id, episode_number: first_format.episode_number, - sequence_number: first_format.sequence_number, relative_episode_number: first_format.relative_episode_number, + sequence_number: first_format.sequence_number, + relative_sequence_number: first_format.relative_sequence_number, } } @@ -401,6 +409,14 @@ impl Format { .replace( "{relative_episode_number}", &self.relative_episode_number.unwrap_or_default().to_string(), + ) + .replace("{sequence_number}", &self.sequence_number.to_string()) + .replace( + "{relative_sequence_number}", + &self + .relative_sequence_number + .unwrap_or_default() + .to_string(), ); if sanitize { @@ -447,7 +463,8 @@ impl Format { tab_info!("FPS: {:.2}", self.fps) } - pub fn has_relative_episodes_fmt>(s: S) -> bool { - return s.as_ref().contains("{relative_episode_number}"); + pub fn has_relative_fmt>(s: S) -> bool { + return s.as_ref().contains("{relative_episode_number}") + || s.as_ref().contains("{relative_sequence_number}"); } } From bbb5a7876520384e2e7725d1adb6bb08faa9caa5 Mon Sep 17 00:00:00 2001 From: Valentine Briese Date: Sun, 15 Oct 2023 11:52:53 -0700 Subject: [PATCH 106/272] Add `--threads` (`-t`) option to downloading commands (#256) * Add `single-threaded` option to downloading commands * Replace `--single-threaded` boolean option with `--threads` optional `usize` option * Simplify `threads` field unwrapping * Make `--threads` `usize` with a default value --- crunchy-cli-core/src/archive/command.rs | 7 +- crunchy-cli-core/src/download/command.rs | 7 +- crunchy-cli-core/src/utils/download.rs | 301 ++++++++++++----------- 3 files changed, 166 insertions(+), 149 deletions(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 7ce1658..bb4794f 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -98,6 +98,10 @@ pub struct Archive { #[arg(short, long, default_value_t = false)] pub(crate) yes: bool, + #[arg(help = "The number of threads used to download")] + #[arg(short, long, default_value_t = num_cpus::get())] + pub(crate) threads: usize, + #[arg(help = "Crunchyroll series url(s)")] #[arg(required = true)] pub(crate) urls: Vec, @@ -158,7 +162,8 @@ impl Execute for Archive { .ffmpeg_preset(self.ffmpeg_preset.clone().unwrap_or_default()) .output_format(Some("matroska".to_string())) .audio_sort(Some(self.audio.clone())) - .subtitle_sort(Some(self.subtitle.clone())); + .subtitle_sort(Some(self.subtitle.clone())) + .threads(self.threads); for single_formats in single_format_collection.into_iter() { let (download_formats, mut format) = get_format(&self, &single_formats).await?; diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index baf27bf..760bf38 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -80,6 +80,10 @@ pub struct Download { #[arg(long, default_value_t = false)] pub(crate) force_hardsub: bool, + #[arg(help = "The number of threads used to download")] + #[arg(short, long, default_value_t = num_cpus::get())] + pub(crate) threads: usize, + #[arg(help = "Url(s) to Crunchyroll episodes or series")] #[arg(required = true)] pub(crate) urls: Vec, @@ -149,7 +153,8 @@ impl Execute for Download { } else { None }) - .ffmpeg_preset(self.ffmpeg_preset.clone().unwrap_or_default()); + .ffmpeg_preset(self.ffmpeg_preset.clone().unwrap_or_default()) + .threads(self.threads); for mut single_formats in single_format_collection.into_iter() { // the vec contains always only one item diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index 29f160a..ff9f240 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -50,6 +50,7 @@ pub struct DownloadBuilder { audio_sort: Option>, subtitle_sort: Option>, force_hardsub: bool, + threads: usize, } impl DownloadBuilder { @@ -61,6 +62,7 @@ impl DownloadBuilder { audio_sort: None, subtitle_sort: None, force_hardsub: false, + threads: num_cpus::get(), } } @@ -73,6 +75,7 @@ impl DownloadBuilder { subtitle_sort: self.subtitle_sort, force_hardsub: self.force_hardsub, + threads: self.threads, formats: vec![], } @@ -99,6 +102,7 @@ pub struct Downloader { subtitle_sort: Option>, force_hardsub: bool, + threads: usize, formats: Vec, } @@ -502,7 +506,8 @@ impl Downloader { let tempfile = tempfile(".mp4")?; let (mut file, path) = tempfile.into_parts(); - download_segments(ctx, &mut file, message, variant_data).await?; + self.download_segments(ctx, &mut file, message, variant_data) + .await?; Ok(path) } @@ -516,7 +521,8 @@ impl Downloader { let tempfile = tempfile(".m4a")?; let (mut file, path) = tempfile.into_parts(); - download_segments(ctx, &mut file, message, variant_data).await?; + self.download_segments(ctx, &mut file, message, variant_data) + .await?; Ok(path) } @@ -537,188 +543,189 @@ impl Downloader { Ok(path) } -} -pub async fn download_segments( - ctx: &Context, - writer: &mut impl Write, - message: String, - variant_data: &VariantData, -) -> Result<()> { - let segments = variant_data.segments().await?; - let total_segments = segments.len(); + async fn download_segments( + &self, + ctx: &Context, + writer: &mut impl Write, + message: String, + variant_data: &VariantData, + ) -> Result<()> { + let segments = variant_data.segments().await?; + let total_segments = segments.len(); - let client = Arc::new(ctx.crunchy.client()); - let count = Arc::new(Mutex::new(0)); + let client = Arc::new(ctx.crunchy.client()); + let count = Arc::new(Mutex::new(0)); - let progress = if log::max_level() == LevelFilter::Info { - let estimated_file_size = estimate_variant_file_size(variant_data, &segments); + let progress = if log::max_level() == LevelFilter::Info { + let estimated_file_size = estimate_variant_file_size(variant_data, &segments); - let progress = ProgressBar::new(estimated_file_size) - .with_style( - ProgressStyle::with_template( - ":: {msg} {bytes:>10} {bytes_per_sec:>12} [{wide_bar}] {percent:>3}%", + let progress = ProgressBar::new(estimated_file_size) + .with_style( + ProgressStyle::with_template( + ":: {msg} {bytes:>10} {bytes_per_sec:>12} [{wide_bar}] {percent:>3}%", + ) + .unwrap() + .progress_chars("##-"), ) - .unwrap() - .progress_chars("##-"), - ) - .with_message(message) - .with_finish(ProgressFinish::Abandon); - Some(progress) - } else { - None - }; + .with_message(message) + .with_finish(ProgressFinish::Abandon); + Some(progress) + } else { + None + }; - let cpus = num_cpus::get(); - let mut segs: Vec> = Vec::with_capacity(cpus); - for _ in 0..cpus { - segs.push(vec![]) - } - for (i, segment) in segments.clone().into_iter().enumerate() { - segs[i - ((i / cpus) * cpus)].push(segment); - } + let cpus = self.threads; + let mut segs: Vec> = Vec::with_capacity(cpus); + for _ in 0..cpus { + segs.push(vec![]) + } + for (i, segment) in segments.clone().into_iter().enumerate() { + segs[i - ((i / cpus) * cpus)].push(segment); + } - let (sender, mut receiver) = unbounded_channel(); + let (sender, mut receiver) = unbounded_channel(); - let mut join_set: JoinSet> = JoinSet::new(); - for num in 0..cpus { - let thread_client = client.clone(); - let thread_sender = sender.clone(); - let thread_segments = segs.remove(0); - let thread_count = count.clone(); - join_set.spawn(async move { - let after_download_sender = thread_sender.clone(); + let mut join_set: JoinSet> = JoinSet::new(); + for num in 0..cpus { + let thread_client = client.clone(); + let thread_sender = sender.clone(); + let thread_segments = segs.remove(0); + let thread_count = count.clone(); + join_set.spawn(async move { + let after_download_sender = thread_sender.clone(); - // the download process is encapsulated in its own function. this is done to easily - // catch errors which get returned with `...?` and `bail!(...)` and that the thread - // itself can report that an error has occurred - let download = || async move { - for (i, segment) in thread_segments.into_iter().enumerate() { - let mut retry_count = 0; - let mut buf = loop { - let request = thread_client - .get(&segment.url) - .timeout(Duration::from_secs(60)) - .send(); + // the download process is encapsulated in its own function. this is done to easily + // catch errors which get returned with `...?` and `bail!(...)` and that the thread + // itself can report that an error has occurred + let download = || async move { + for (i, segment) in thread_segments.into_iter().enumerate() { + let mut retry_count = 0; + let mut buf = loop { + let request = thread_client + .get(&segment.url) + .timeout(Duration::from_secs(60)) + .send(); - let response = match request.await { - Ok(r) => r, - Err(e) => { - if retry_count == 5 { - bail!("Max retry count reached ({}), multiple errors occurred while receiving segment {}: {}", retry_count, num + (i * cpus), e) - } - debug!("Failed to download segment {} ({}). Retrying, {} out of 5 retries left", num + (i * cpus), e, 5 - retry_count); - continue - } - }; - - match response.bytes().await { - Ok(b) => break b.to_vec(), - Err(e) => { - if e.is_body() { + let response = match request.await { + Ok(r) => r, + Err(e) => { if retry_count == 5 { bail!("Max retry count reached ({}), multiple errors occurred while receiving segment {}: {}", retry_count, num + (i * cpus), e) } - debug!("Failed to download segment {} ({}). Retrying, {} out of 5 retries left", num + (i * cpus), e, 5 - retry_count) - } else { - bail!("{}", e) + debug!("Failed to download segment {} ({}). Retrying, {} out of 5 retries left", num + (i * cpus), e, 5 - retry_count); + continue + } + }; + + match response.bytes().await { + Ok(b) => break b.to_vec(), + Err(e) => { + if e.is_body() { + if retry_count == 5 { + bail!("Max retry count reached ({}), multiple errors occurred while receiving segment {}: {}", retry_count, num + (i * cpus), e) + } + debug!("Failed to download segment {} ({}). Retrying, {} out of 5 retries left", num + (i * cpus), e, 5 - retry_count) + } else { + bail!("{}", e) + } } } - } - retry_count += 1; - }; + retry_count += 1; + }; - buf = VariantSegment::decrypt(buf.borrow_mut(), segment.key)?.to_vec(); + buf = VariantSegment::decrypt(buf.borrow_mut(), segment.key)?.to_vec(); - let mut c = thread_count.lock().await; - debug!( - "Downloaded and decrypted segment [{}/{} {:.2}%] {}", - num + (i * cpus) + 1, - total_segments, - ((*c + 1) as f64 / total_segments as f64) * 100f64, - segment.url - ); + let mut c = thread_count.lock().await; + debug!( + "Downloaded and decrypted segment [{}/{} {:.2}%] {}", + num + (i * cpus) + 1, + total_segments, + ((*c + 1) as f64 / total_segments as f64) * 100f64, + segment.url + ); - thread_sender.send((num as i32 + (i * cpus) as i32, buf))?; + thread_sender.send((num as i32 + (i * cpus) as i32, buf))?; - *c += 1; + *c += 1; + } + Ok(()) + }; + + + let result = download().await; + if result.is_err() { + after_download_sender.send((-1 as i32, vec![]))?; } - Ok(()) - }; + result + }); + } + // drop the sender already here so it does not outlive all download threads which are the only + // real consumers of it + drop(sender); - let result = download().await; - if result.is_err() { - after_download_sender.send((-1 as i32, vec![]))?; + // this is the main loop which writes the data. it uses a BTreeMap as a buffer as the write + // happens synchronized. the download consist of multiple segments. the map keys are representing + // the segment number and the values the corresponding bytes + let mut data_pos = 0; + let mut buf: BTreeMap> = BTreeMap::new(); + while let Some((pos, bytes)) = receiver.recv().await { + // if the position is lower than 0, an error occurred in the sending download thread + if pos < 0 { + break; } - result - }); - } - // drop the sender already here so it does not outlive all download threads which are the only - // real consumers of it - drop(sender); + if let Some(p) = &progress { + let progress_len = p.length().unwrap(); + let estimated_segment_len = (variant_data.bandwidth / 8) + * segments.get(pos as usize).unwrap().length.as_secs(); + let bytes_len = bytes.len() as u64; - // this is the main loop which writes the data. it uses a BTreeMap as a buffer as the write - // happens synchronized. the download consist of multiple segments. the map keys are representing - // the segment number and the values the corresponding bytes - let mut data_pos = 0; - let mut buf: BTreeMap> = BTreeMap::new(); - while let Some((pos, bytes)) = receiver.recv().await { - // if the position is lower than 0, an error occurred in the sending download thread - if pos < 0 { - break; + p.set_length(progress_len - estimated_segment_len + bytes_len); + p.inc(bytes_len) + } + + // check if the currently sent bytes are the next in the buffer. if so, write them directly + // to the target without first adding them to the buffer. + // if not, add them to the buffer + if data_pos == pos { + writer.write_all(bytes.borrow())?; + data_pos += 1; + } else { + buf.insert(pos, bytes); + } + // check if the buffer contains the next segment(s) + while let Some(b) = buf.remove(&data_pos) { + writer.write_all(b.borrow())?; + data_pos += 1; + } } - if let Some(p) = &progress { - let progress_len = p.length().unwrap(); - let estimated_segment_len = - (variant_data.bandwidth / 8) * segments.get(pos as usize).unwrap().length.as_secs(); - let bytes_len = bytes.len() as u64; - - p.set_length(progress_len - estimated_segment_len + bytes_len); - p.inc(bytes_len) + // if any error has occurred while downloading it gets returned here + while let Some(joined) = join_set.join_next().await { + joined?? } - // check if the currently sent bytes are the next in the buffer. if so, write them directly - // to the target without first adding them to the buffer. - // if not, add them to the buffer - if data_pos == pos { - writer.write_all(bytes.borrow())?; - data_pos += 1; - } else { - buf.insert(pos, bytes); - } - // check if the buffer contains the next segment(s) + // write the remaining buffer, if existent while let Some(b) = buf.remove(&data_pos) { writer.write_all(b.borrow())?; data_pos += 1; } - } - // if any error has occurred while downloading it gets returned here - while let Some(joined) = join_set.join_next().await { - joined?? - } + if !buf.is_empty() { + bail!( + "Download buffer is not empty. Remaining segments: {}", + buf.into_keys() + .map(|k| k.to_string()) + .collect::>() + .join(", ") + ) + } - // write the remaining buffer, if existent - while let Some(b) = buf.remove(&data_pos) { - writer.write_all(b.borrow())?; - data_pos += 1; + Ok(()) } - - if !buf.is_empty() { - bail!( - "Download buffer is not empty. Remaining segments: {}", - buf.into_keys() - .map(|k| k.to_string()) - .collect::>() - .join(", ") - ) - } - - Ok(()) } fn estimate_variant_file_size(variant_data: &VariantData, segments: &Vec) -> u64 { From 568bce00085cc301029d0b39c39cf15b97aa1d3d Mon Sep 17 00:00:00 2001 From: bytedream Date: Sun, 15 Oct 2023 22:39:53 +0200 Subject: [PATCH 107/272] Manually implement filename sanitizing to allow the usage of file separators --- Cargo.lock | 11 ----- crunchy-cli-core/Cargo.toml | 1 - crunchy-cli-core/src/archive/command.rs | 2 +- crunchy-cli-core/src/download/command.rs | 2 +- crunchy-cli-core/src/utils/format.rs | 55 ++++++++++++------------ crunchy-cli-core/src/utils/os.rs | 48 +++++++++++++++++++++ 6 files changed, 77 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 09cad3e..409a005 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -401,7 +401,6 @@ dependencies = [ "regex", "reqwest", "rustls-native-certs", - "sanitize-filename", "serde", "serde_json", "serde_plain", @@ -1517,16 +1516,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" -[[package]] -name = "sanitize-filename" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ed72fbaf78e6f2d41744923916966c4fbe3d7c74e3037a8ee482f1115572603" -dependencies = [ - "lazy_static", - "regex", -] - [[package]] name = "schannel" version = "0.1.22" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index fc298f3..e38cb1a 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -28,7 +28,6 @@ log = { version = "0.4", features = ["std"] } num_cpus = "1.16" regex = "1.9" reqwest = { version = "0.11", default-features = false, features = ["socks"] } -sanitize-filename = "0.5" serde = "1.0" serde_json = "1.0" serde_plain = "1.0" diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index bb4794f..3f455ed 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -173,7 +173,7 @@ impl Execute for Archive { downloader.add_format(download_format) } - let formatted_path = format.format_path((&self.output).into(), true); + let formatted_path = format.format_path((&self.output).into()); let (path, changed) = free_file(formatted_path.clone()); if changed && self.skip_existing { diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index 760bf38..9c9ecb4 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -165,7 +165,7 @@ impl Execute for Download { let mut downloader = download_builder.clone().build(); downloader.add_format(download_format); - let formatted_path = format.format_path((&self.output).into(), true); + let formatted_path = format.format_path((&self.output).into()); let (path, changed) = free_file(formatted_path.clone()); if changed && self.skip_existing { diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index 618f7d5..f462263 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -1,6 +1,6 @@ use crate::utils::filter::real_dedup_vec; use crate::utils::log::tab_info; -use crate::utils::os::is_special_file; +use crate::utils::os::{is_special_file, sanitize}; use anyhow::Result; use chrono::Duration; use crunchyroll_rs::media::{Resolution, Stream, Subtitle, VariantData}; @@ -368,46 +368,45 @@ impl Format { } } - /// Formats the given string if it has specific pattern in it. It's possible to sanitize it which - /// removes characters which can cause failures if the output string is used as a file name. - pub fn format_path(&self, path: PathBuf, sanitize: bool) -> PathBuf { - let path = path - .to_string_lossy() - .to_string() - .replace("{title}", &self.title) + /// Formats the given string if it has specific pattern in it. It also sanitizes the filename. + pub fn format_path(&self, path: PathBuf) -> PathBuf { + let mut path = sanitize(path.to_string_lossy(), false); + path = path + .replace("{title}", &sanitize(&self.title, true)) .replace( "{audio}", - &self - .locales - .iter() - .map(|(a, _)| a.to_string()) - .collect::>() - .join("|"), + &sanitize( + self.locales + .iter() + .map(|(a, _)| a.to_string()) + .collect::>() + .join("|"), + true, + ), ) - .replace("{resolution}", &self.resolution.to_string()) - .replace("{series_id}", &self.series_id) - .replace("{series_name}", &self.series_name) - .replace("{season_id}", &self.season_id) - .replace("{season_name}", &self.season_title) + .replace("{resolution}", &sanitize(self.resolution.to_string(), true)) + .replace("{series_id}", &sanitize(&self.series_id, true)) + .replace("{series_name}", &sanitize(&self.series_name, true)) + .replace("{season_id}", &sanitize(&self.season_id, true)) + .replace("{season_name}", &sanitize(&self.season_title, true)) .replace( "{season_number}", - &format!("{:0>2}", self.season_number.to_string()), + &format!("{:0>2}", sanitize(self.season_number.to_string(), true)), ) - .replace("{episode_id}", &self.episode_id) + .replace("{episode_id}", &sanitize(&self.episode_id, true)) .replace( "{episode_number}", - &format!("{:0>2}", self.episode_number.to_string()), + &format!("{:0>2}", sanitize(&self.episode_number, true)), ) .replace( "{relative_episode_number}", - &self.relative_episode_number.unwrap_or_default().to_string(), + &sanitize( + self.relative_episode_number.unwrap_or_default().to_string(), + true, + ), ); - if sanitize { - PathBuf::from(sanitize_filename::sanitize(path)) - } else { - PathBuf::from(path) - } + PathBuf::from(path) } pub fn visual_output(&self, dst: &Path) { diff --git a/crunchy-cli-core/src/utils/os.rs b/crunchy-cli-core/src/utils/os.rs index f6d9ad0..1f76b90 100644 --- a/crunchy-cli-core/src/utils/os.rs +++ b/crunchy-cli-core/src/utils/os.rs @@ -1,4 +1,6 @@ use log::debug; +use regex::{Regex, RegexBuilder}; +use std::borrow::Cow; use std::io::ErrorKind; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; @@ -78,3 +80,49 @@ pub fn free_file(mut path: PathBuf) -> (PathBuf, bool) { pub fn is_special_file>(path: P) -> bool { path.as_ref().exists() && !path.as_ref().is_file() && !path.as_ref().is_dir() } + +lazy_static::lazy_static! { + static ref ILLEGAL_RE: Regex = Regex::new(r#"[\?<>:\*\|":]"#).unwrap(); + static ref CONTROL_RE: Regex = Regex::new(r"[\x00-\x1f\x80-\x9f]").unwrap(); + static ref RESERVED_RE: Regex = Regex::new(r"^\.+$").unwrap(); + static ref WINDOWS_RESERVED_RE: Regex = RegexBuilder::new(r"(?i)^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$") + .case_insensitive(true) + .build() + .unwrap(); + static ref WINDOWS_TRAILING_RE: Regex = Regex::new(r"[\. ]+$").unwrap(); +} + +/// Sanitizes a filename with the option to include/exclude the path separator from sanitizing. This +/// is based of the implementation of the +/// [`sanitize-filename`](https://crates.io/crates/sanitize-filename) crate. +pub fn sanitize>(path: S, include_path_separator: bool) -> String { + let path = Cow::from(path.as_ref()); + + let path = ILLEGAL_RE.replace_all(&path, ""); + let path = CONTROL_RE.replace_all(&path, ""); + let path = RESERVED_RE.replace(&path, ""); + + let collect = |name: String| { + if name.len() > 255 { + name[..255].to_string() + } else { + name + } + }; + + if cfg!(windows) { + let path = WINDOWS_RESERVED_RE.replace(&path, ""); + let path = WINDOWS_TRAILING_RE.replace(&path, ""); + let mut path = path.to_string(); + if include_path_separator { + path = path.replace(['\\', '/'], ""); + } + collect(path) + } else { + let mut path = path.to_string(); + if include_path_separator { + path = path.replace('/', ""); + } + collect(path) + } +} From 685c79d673538aa981515806595cbba2da4decbf Mon Sep 17 00:00:00 2001 From: bytedream Date: Sun, 15 Oct 2023 22:55:44 +0200 Subject: [PATCH 108/272] Add 2-digit padding to relative_episode_number, sequence_number and relative_sequence_number format option --- crunchy-cli-core/src/utils/format.rs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index 1ba8136..4679878 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -408,22 +408,28 @@ impl Format { ) .replace( "{relative_episode_number}", - &sanitize( - self.relative_episode_number.unwrap_or_default().to_string(), - true, + &format!( + "{:0>2}", + sanitize( + self.relative_episode_number.unwrap_or_default().to_string(), + true, + ) ), ) .replace( "{sequence_number}", - &sanitize(self.sequence_number.to_string(), true), + &format!("{:0>2}", sanitize(self.sequence_number.to_string(), true)), ) .replace( "{relative_sequence_number}", - &sanitize( - self.relative_sequence_number - .unwrap_or_default() - .to_string(), - true, + &format!( + "{:0>2}", + sanitize( + self.relative_sequence_number + .unwrap_or_default() + .to_string(), + true, + ) ), ); From d0fe7f54f6c0e74f87d13a6d072599c12aad8367 Mon Sep 17 00:00:00 2001 From: bytedream Date: Sun, 15 Oct 2023 23:34:22 +0200 Subject: [PATCH 109/272] Show fractal in relative_sequence_number if present --- crunchy-cli-core/src/archive/filter.rs | 8 +++++--- crunchy-cli-core/src/download/filter.rs | 8 +++++--- crunchy-cli-core/src/utils/parse.rs | 10 ++++++++++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/crunchy-cli-core/src/archive/filter.rs b/crunchy-cli-core/src/archive/filter.rs index c2cc206..024ad17 100644 --- a/crunchy-cli-core/src/archive/filter.rs +++ b/crunchy-cli-core/src/archive/filter.rs @@ -2,7 +2,7 @@ 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::UrlFilter; +use crate::utils::parse::{fract, UrlFilter}; use anyhow::Result; use crunchyroll_rs::{Concert, Episode, Locale, Movie, MovieListing, MusicVideo, Season, Series}; use log::{info, warn}; @@ -321,8 +321,10 @@ impl Filter for ArchiveFilter { } if ep.id == episode.id { relative_episode_number = Some(i + 1); - relative_sequence_number = - Some((i + 1 - non_integer_sequence_number_count) as f32); + relative_sequence_number = Some( + (i + 1 - non_integer_sequence_number_count) as f32 + + fract(ep.sequence_number), + ); break; } } diff --git a/crunchy-cli-core/src/download/filter.rs b/crunchy-cli-core/src/download/filter.rs index c5aef7e..ff3c2ff 100644 --- a/crunchy-cli-core/src/download/filter.rs +++ b/crunchy-cli-core/src/download/filter.rs @@ -2,7 +2,7 @@ use crate::download::Download; use crate::utils::filter::Filter; use crate::utils::format::{Format, SingleFormat, SingleFormatCollection}; use crate::utils::interactive_select::{check_for_duplicated_seasons, get_duplicated_seasons}; -use crate::utils::parse::UrlFilter; +use crate::utils::parse::{fract, UrlFilter}; use anyhow::{bail, Result}; use crunchyroll_rs::{Concert, Episode, Movie, MovieListing, MusicVideo, Season, Series}; use log::{error, info, warn}; @@ -211,8 +211,10 @@ impl Filter for DownloadFilter { } if ep.id == episode.id { relative_episode_number = Some(i + 1); - relative_sequence_number = - Some((i + 1 - non_integer_sequence_number_count) as f32); + relative_sequence_number = Some( + (i + 1 - non_integer_sequence_number_count) as f32 + + fract(ep.sequence_number), + ); break; } } diff --git a/crunchy-cli-core/src/utils/parse.rs b/crunchy-cli-core/src/utils/parse.rs index f85d8c2..c0ac2b0 100644 --- a/crunchy-cli-core/src/utils/parse.rs +++ b/crunchy-cli-core/src/utils/parse.rs @@ -192,3 +192,13 @@ pub fn parse_resolution(mut resolution: String) -> Result { bail!("Could not find resolution") } } + +/// Dirty implementation of [`f32::fract`] with more accuracy. +pub fn fract(input: f32) -> f32 { + if input.fract() == 0.0 { + return 0.0; + } + format!("0.{}", input.to_string().split('.').last().unwrap()) + .parse::() + .unwrap() +} From 5a3a30444329548134ca998eebaa20e96eb88634 Mon Sep 17 00:00:00 2001 From: bytedream Date: Sun, 15 Oct 2023 23:52:44 +0200 Subject: [PATCH 110/272] Use episode sequence number as filter number for url episode filtering --- crunchy-cli-core/src/archive/filter.rs | 2 +- crunchy-cli-core/src/download/filter.rs | 4 ++-- crunchy-cli-core/src/search/filter.rs | 2 +- crunchy-cli-core/src/utils/parse.rs | 10 +++++----- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/crunchy-cli-core/src/archive/filter.rs b/crunchy-cli-core/src/archive/filter.rs index 024ad17..91023a3 100644 --- a/crunchy-cli-core/src/archive/filter.rs +++ b/crunchy-cli-core/src/archive/filter.rs @@ -241,7 +241,7 @@ impl Filter for ArchiveFilter { async fn visit_episode(&mut self, mut episode: Episode) -> Result> { if !self .url_filter - .is_episode_valid(episode.episode_number, episode.season_number) + .is_episode_valid(episode.sequence_number, episode.season_number) { return Ok(None); } diff --git a/crunchy-cli-core/src/download/filter.rs b/crunchy-cli-core/src/download/filter.rs index ff3c2ff..55b1e8b 100644 --- a/crunchy-cli-core/src/download/filter.rs +++ b/crunchy-cli-core/src/download/filter.rs @@ -118,7 +118,7 @@ impl Filter for DownloadFilter { episodes.retain(|e| { self.url_filter - .is_episode_valid(e.episode_number, season.season_number) + .is_episode_valid(e.sequence_number, season.season_number) }); Ok(episodes) @@ -127,7 +127,7 @@ impl Filter for DownloadFilter { async fn visit_episode(&mut self, mut episode: Episode) -> Result> { if !self .url_filter - .is_episode_valid(episode.episode_number, episode.season_number) + .is_episode_valid(episode.sequence_number, episode.season_number) { return Ok(None); } diff --git a/crunchy-cli-core/src/search/filter.rs b/crunchy-cli-core/src/search/filter.rs index 0b31823..264b31d 100644 --- a/crunchy-cli-core/src/search/filter.rs +++ b/crunchy-cli-core/src/search/filter.rs @@ -24,7 +24,7 @@ impl FilterOptions { self.check_audio_language(&vec![e.audio_locale.clone()]) && self .url_filter - .is_episode_valid(e.episode_number, e.season_number) + .is_episode_valid(e.sequence_number, e.season_number) }); episodes } diff --git a/crunchy-cli-core/src/utils/parse.rs b/crunchy-cli-core/src/utils/parse.rs index c0ac2b0..3fc7e7c 100644 --- a/crunchy-cli-core/src/utils/parse.rs +++ b/crunchy-cli-core/src/utils/parse.rs @@ -10,8 +10,8 @@ use regex::Regex; /// If `to_*` is [`None`] they're set to [`u32::MAX`]. #[derive(Debug, Default)] pub struct InnerUrlFilter { - from_episode: Option, - to_episode: Option, + from_episode: Option, + to_episode: Option, from_season: Option, to_season: Option, } @@ -39,10 +39,10 @@ impl UrlFilter { }) } - pub fn is_episode_valid(&self, episode: u32, season: u32) -> bool { + pub fn is_episode_valid(&self, episode: f32, season: u32) -> bool { self.inner.iter().any(|f| { - let from_episode = f.from_episode.unwrap_or(u32::MIN); - let to_episode = f.to_episode.unwrap_or(u32::MAX); + let from_episode = f.from_episode.unwrap_or(f32::MIN); + let to_episode = f.to_episode.unwrap_or(f32::MAX); let from_season = f.from_season.unwrap_or(u32::MIN); let to_season = f.to_season.unwrap_or(u32::MAX); From f56d9ecabf356ab9870c94f8ca5f3b46a2a39484 Mon Sep 17 00:00:00 2001 From: Catd <34575742+Nannk@users.noreply.github.com> Date: Mon, 16 Oct 2023 15:04:45 +0000 Subject: [PATCH 111/272] Changes in Readme regarding subtitles and flag usage (#255) * Update README.md updated Flags and subtitles sections * Update README.md * Update README.md Comma in a better place --- README.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 7a620cb..df285cc 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,8 @@ $ cargo install --force --path . > All shown commands are examples 🧑🏼‍🍳 +### Global Flags + crunchy-cli requires you to log in. Though you can use a non-premium account, you will not have access to premium content without a subscription. You can authenticate with your credentials (user:password) or by using a refresh token. @@ -99,7 +101,7 @@ You can authenticate with your credentials (user:password) or by using a refresh - Credentials ```shell - $ crunchy-cli --credentials "user:password" + $ crunchy-cli --credentials "user:password" ``` - Refresh Token @@ -107,13 +109,13 @@ You can authenticate with your credentials (user:password) or by using a refresh The easiest way to get it is via a browser extension which lets you export your cookies, like [Cookie-Editor](https://cookie-editor.cgagnier.ca/) ([Firefox](https://addons.mozilla.org/en-US/firefox/addon/cookie-editor/) / [Chrome](https://chrome.google.com/webstore/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm)). When installed, look for the `etp_rt` entry and extract its value. ```shell - $ crunchy-cli --etp-rt "4ebf1690-53a4-491a-a2ac-488309120f5d" + $ crunchy-cli --etp-rt "4ebf1690-53a4-491a-a2ac-488309120f5d" ``` - Stay Anonymous Login without an account (you won't be able to access premium content): ```shell - $ crunchy-cli --anonymous + $ crunchy-cli --anonymous ``` ### Global settings @@ -124,7 +126,7 @@ You can set specific settings which will be If you want to include debug information in the output, use the `-v` / `--verbose` flag to show it. ```shell - $ crunchy-cli -v + $ crunchy-cli -v ``` This flag can't be used with `-q` / `--quiet`. @@ -133,7 +135,7 @@ You can set specific settings which will be If you want to hide all output, use the `-q` / `--quiet` flag to do so. This is especially useful if you want to pipe the output video to an external program (like a video player). ```shell - $ crunchy-cli -q + $ crunchy-cli -q ``` - Language @@ -141,7 +143,7 @@ You can set specific settings which will be By default, the resulting metadata like title or description are shown in your system language (if Crunchyroll supports it, else in English). If you want to show the results in another language, use the `--lang` flag to set it. ```shell - $ crunchy-cli --lang de-DE + $ crunchy-cli --lang de-DE ``` - Experimental fixes @@ -150,7 +152,7 @@ You can set specific settings which will be The `--experimental-fixes` flag tries to fix some of those issues. As the *experimental* in `--experimental-fixes` states, these fixes may or may not break other functionality. ```shell - $ crunchy-cli --experimental-fixes + $ crunchy-cli --experimental-fixes ``` For an overview which parts this flag affects, see the [documentation](https://docs.rs/crunchyroll-rs/latest/crunchyroll_rs/crunchyroll/struct.CrunchyrollBuilder.html) of the underlying Crunchyroll library, all functions beginning with `stabilization_` are applied. @@ -159,7 +161,7 @@ You can set specific settings which will be The `--proxy` flag supports https and socks5 proxies to route all your traffic through. This may be helpful to bypass the geo-restrictions Crunchyroll has on certain series. ```shell - $ crunchy-cli --proxy socks5://127.0.0.1:8080 + $ crunchy-cli --proxy socks5://127.0.0.1:8080 ``` Make sure that proxy can either forward TLS requests, which is needed to bypass the (cloudflare) bot protection, or that it is configured so that the proxy can bypass the protection itself. @@ -204,7 +206,7 @@ The `download` command lets you download episodes with a specific audio language - Subtitle language Besides the audio, you can specify the subtitle language by using the `-s` / `--subtitle` flag. - The subtitles will be burned into the video track (cf. [hardsub](https://www.urbandictionary.com/define.php?term=hardsub)) and thus can not be turned off. + In formats that support it (.mp4, .mov and .mkv ), subtitles are stored as soft-subs. All other formats are hardsubbed: the subtitles will be burned into the video track (cf. [hardsub](https://www.urbandictionary.com/define.php?term=hardsub)) and thus can not be turned off. ```shell $ crunchy-cli download -s de-DE https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` From d8b76f8cc7985d5c838d6081985e686042051bd5 Mon Sep 17 00:00:00 2001 From: kennedy <854543+kennedy@users.noreply.github.com> Date: Sun, 29 Oct 2023 05:12:25 +0000 Subject: [PATCH 112/272] Add homebrew instructions (#261) Added details about homebrew and what archs are supported. made minor style linting: add space surrounding shell code blocks, and headers. --- README.md | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index df285cc..aa99c45 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ Check out the [releases](https://github.com/crunchy-labs/crunchy-cli/releases) t If you're using Arch or an Arch based Linux distribution you are able to install our [AUR](https://aur.archlinux.org/) package. You need an [AUR helper](https://wiki.archlinux.org/title/AUR_helpers) like [yay](https://github.com/Jguer/yay) to install it. + ```shell # this package builds crunchy-cli manually (recommended) $ yay -S crunchy-cli @@ -63,6 +64,7 @@ Check out the [releases](https://github.com/crunchy-labs/crunchy-cli/releases) t - [Nix](https://nixos.org/) This requires [nix](https://nixos.org) and you'll probably need `--extra-experimental-features "nix-command flakes"`, depending on your configurations. + ```shell $ nix github:crunchy-labs/crunchy-cli ``` @@ -70,15 +72,27 @@ Check out the [releases](https://github.com/crunchy-labs/crunchy-cli/releases) t - [Scoop](https://scoop.sh/) For Windows users, we support the [scoop](https://scoop.sh/#/) command-line installer. + ```shell $ scoop bucket add extras $ scoop install extras/crunchy-cli ``` +- [Homebrew](https://brew.sh/) + + For macOS/linux users, we support the [brew](https://brew.sh/#/) command-line installer. Packages are compile by the [homebrew project](https://github.com/Homebrew/homebrew-core/pkgs/container/core%2Fcrunchy-cli), and will also install the `openssl@3` and `ffmpeg` dependencies. + + ```shell + $ brew install crunchy-cli + ``` + + Supported archs: `x86_64_linux`, `arm64_monterey`, `sonoma`, `ventura` + ### 🛠 Build it yourself Since we do not support every platform and architecture you may have to build the project yourself. This requires [git](https://git-scm.com/) and [Cargo](https://doc.rust-lang.org/cargo). + ```shell $ git clone https://github.com/crunchy-labs/crunchy-cli $ cd crunchy-cli @@ -103,18 +117,22 @@ You can authenticate with your credentials (user:password) or by using a refresh ```shell $ crunchy-cli --credentials "user:password" ``` + - Refresh Token To obtain a refresh token, you have to log in at [crunchyroll.com](https://www.crunchyroll.com/) and extract the `etp_rt` cookie. The easiest way to get it is via a browser extension which lets you export your cookies, like [Cookie-Editor](https://cookie-editor.cgagnier.ca/) ([Firefox](https://addons.mozilla.org/en-US/firefox/addon/cookie-editor/) / [Chrome](https://chrome.google.com/webstore/detail/cookie-editor/hlkenndednhfkekhgcdicdfddnkalmdm)). When installed, look for the `etp_rt` entry and extract its value. + ```shell $ crunchy-cli --etp-rt "4ebf1690-53a4-491a-a2ac-488309120f5d" ``` + - Stay Anonymous Login without an account (you won't be able to access premium content): - ```shell + + ```shell $ crunchy-cli --anonymous ``` @@ -125,15 +143,18 @@ You can set specific settings which will be - Verbose output If you want to include debug information in the output, use the `-v` / `--verbose` flag to show it. + ```shell $ crunchy-cli -v ``` + This flag can't be used with `-q` / `--quiet`. - Quiet output If you want to hide all output, use the `-q` / `--quiet` flag to do so. This is especially useful if you want to pipe the output video to an external program (like a video player). + ```shell $ crunchy-cli -q ``` @@ -142,6 +163,7 @@ You can set specific settings which will be By default, the resulting metadata like title or description are shown in your system language (if Crunchyroll supports it, else in English). If you want to show the results in another language, use the `--lang` flag to set it. + ```shell $ crunchy-cli --lang de-DE ``` @@ -151,18 +173,22 @@ You can set specific settings which will be Crunchyroll constantly changes and breaks its services or just delivers incorrect answers. The `--experimental-fixes` flag tries to fix some of those issues. As the *experimental* in `--experimental-fixes` states, these fixes may or may not break other functionality. + ```shell $ crunchy-cli --experimental-fixes ``` + For an overview which parts this flag affects, see the [documentation](https://docs.rs/crunchyroll-rs/latest/crunchyroll_rs/crunchyroll/struct.CrunchyrollBuilder.html) of the underlying Crunchyroll library, all functions beginning with `stabilization_` are applied. - Proxy The `--proxy` flag supports https and socks5 proxies to route all your traffic through. This may be helpful to bypass the geo-restrictions Crunchyroll has on certain series. + ```shell $ crunchy-cli --proxy socks5://127.0.0.1:8080 ``` + Make sure that proxy can either forward TLS requests, which is needed to bypass the (cloudflare) bot protection, or that it is configured so that the proxy can bypass the protection itself. ### Login @@ -184,6 +210,7 @@ With the session stored, you do not need to pass `--credentials` / `--etp-rt` / The `download` command lets you download episodes with a specific audio language and optional subtitles. **Supported urls** + - Single episode (with [episode filtering](#episode-filtering)) ```shell $ crunchy-cli download https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome @@ -194,38 +221,47 @@ The `download` command lets you download episodes with a specific audio language ``` **Options** + - Audio language Set the audio language with the `-a` / `--audio` flag. This only works if the url points to a series since episode urls are language specific. + ```shell $ crunchy-cli download -a de-DE https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` + Default is your system locale. If not supported by Crunchyroll, `en-US` (American English) is the default. - Subtitle language Besides the audio, you can specify the subtitle language by using the `-s` / `--subtitle` flag. In formats that support it (.mp4, .mov and .mkv ), subtitles are stored as soft-subs. All other formats are hardsubbed: the subtitles will be burned into the video track (cf. [hardsub](https://www.urbandictionary.com/define.php?term=hardsub)) and thus can not be turned off. + ```shell $ crunchy-cli download -s de-DE https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` + Default is none. - Output template Define an output template by using the `-o` / `--output` flag. + ```shell $ crunchy-cli download -o "ditf.mp4" https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome ``` + Default is `{title}.mp4`. See the [Template Options section](#output-template-options) below for more options. - Resolution The resolution for videos can be set via the `-r` / `--resolution` flag. + ```shell $ crunchy-cli download -r worst https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome ``` + Default is `best`. - FFmpeg Preset @@ -233,6 +269,7 @@ The `download` command lets you download episodes with a specific audio language You can specify specific built-in presets with the `--ffmpeg-preset` flag to convert videos to a specific coding while downloading. Multiple predefined presets how videos should be encoded (h264, h265, av1, ...) are available, you can see them with `crunchy-cli download --help`. If you need more specific ffmpeg customizations you could either convert the output file manually or use ffmpeg output arguments as value for this flag. + ```shell $ crunchy-cli downlaod --ffmpeg-preset av1-lossless https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome ``` @@ -240,6 +277,7 @@ The `download` command lets you download episodes with a specific audio language - Skip existing If you re-download a series but want to skip episodes you've already downloaded, the `--skip-existing` flag skips the already existing/downloaded files. + ```shell $ crunchy-cli download --skip-existing https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` @@ -248,14 +286,17 @@ The `download` command lets you download episodes with a specific audio language Sometimes different seasons have the same season number (e.g. Sword Art Online Alicization and Alicization War of Underworld are both marked as season 3), in such cases an interactive prompt is shown which needs user further user input to decide which season to download. The `--yes` flag suppresses this interactive prompt and just downloads all seasons. + ```shell $ crunchy-cli download --yes https://www.crunchyroll.com/series/GR49G9VP6/sword-art-online ``` + If you've passed the `-q` / `--quiet` [global flag](#global-settings), this flag is automatically set. - Force hardsub If you want to burn-in the subtitles, even if the output format/container supports soft-subs (e.g. `.mp4`), use the `--force-hardsub` flag to do so. + ```shell $ crunchy-cli download --force-hardsub -s en-US https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome ``` @@ -265,6 +306,7 @@ The `download` command lets you download episodes with a specific audio language The `archive` command lets you download episodes with multiple audios and subtitles and merges it into a `.mkv` file. **Supported urls** + - Single episode (with [episode filtering](#episode-filtering)) ```shell $ crunchy-cli archive https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome @@ -275,37 +317,46 @@ The `archive` command lets you download episodes with multiple audios and subtit ``` **Options** + - Audio languages Set the audio language with the `-a` / `--audio` flag. Can be used multiple times. + ```shell $ crunchy-cli archive -a ja-JP -a de-DE https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` + Default is your system locale (if not supported by Crunchyroll, `en-US` (American English) and `ja-JP` (Japanese) are used). - Subtitle languages Besides the audio, you can specify the subtitle language by using the `-s` / `--subtitle` flag. + ```shell $ crunchy-cli archive -s de-DE https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` + Default is `all` subtitles. - Output template Define an output template by using the `-o` / `--output` flag. crunchy-cli uses the [`.mkv`](https://en.wikipedia.org/wiki/Matroska) container format, because of it's ability to store multiple audio, video and subtitle tracks at once. + ```shell $ crunchy-cli archive -o "{title}.mkv" https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` + Default is `{title}.mkv`. See the [Template Options section](#output-template-options) below for more options. - Resolution The resolution for videos can be set via the `-r` / `--resolution` flag. + ```shell $ crunchy-cli archive -r worst https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` + Default is `best`. - Merge behavior @@ -316,9 +367,11 @@ The `archive` command lets you download episodes with multiple audios and subtit With the `-m` / `--merge` flag you can define the behaviour when an episodes' video tracks differ in length. Valid options are `audio` - store one video and all other languages as audio only; `video` - store the video + audio for every language; `auto` - detect if videos differ in length: if so, behave like `video` - otherwise like `audio`. Subtitles will always match the primary audio and video. + ```shell $ crunchy-cli archive -m audio https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` + Default is `auto`. - FFmpeg Preset @@ -326,6 +379,7 @@ The `archive` command lets you download episodes with multiple audios and subtit You can specify specific built-in presets with the `--ffmpeg-preset` flag to convert videos to a specific coding while downloading. Multiple predefined presets how videos should be encoded (h264, h265, av1, ...) are available, you can see them with `crunchy-cli archive --help`. If you need more specific ffmpeg customizations you could either convert the output file manually or use ffmpeg output arguments as value for this flag. + ```shell $ crunchy-cli archive --ffmpeg-preset av1-lossless https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome ``` @@ -333,14 +387,17 @@ The `archive` command lets you download episodes with multiple audios and subtit - Default subtitle `--default-subtitle` Set which subtitle language is to be flagged as **default** and **forced**. + ```shell $ crunchy-cli archive --default-subtitle en-US https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` + Default is none. - Skip existing If you re-download a series but want to skip episodes you've already downloaded, the `--skip-existing` flag skips the already existing/downloaded files. + ```shell $ crunchy-cli archive --skip-existing https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` @@ -349,14 +406,17 @@ The `archive` command lets you download episodes with multiple audios and subtit Sometimes different seasons have the same season number (e.g. Sword Art Online Alicization and Alicization War of Underworld are both marked as season 3), in such cases an interactive prompt is shown which needs user further user input to decide which season to download. The `--yes` flag suppresses this interactive prompt and just downloads all seasons. + ```shell $ crunchy-cli archive --yes https://www.crunchyroll.com/series/GR49G9VP6/sword-art-online ``` + If you've passed the `-q` / `--quiet` [global flag](#global-settings), this flag is automatically set. ### Search **Supported urls/input** + - Single episode (with [episode filtering](#episode-filtering)) ```shell $ crunchy-cli search https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome @@ -371,12 +431,15 @@ The `archive` command lets you download episodes with multiple audios and subtit ``` **Options** + - Audio Set the audio language to search via the `--audio` flag. Can be used multiple times. + ```shell $ crunchy-cli search --audio en-US https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` + Default is your system locale. - Result limit @@ -384,6 +447,7 @@ The `archive` command lets you download episodes with multiple audios and subtit If your input is a search term instead of an url, you have multiple options to control which results to process. The `--search-top-results-limit` flag sets the limit of top search results to process. `--search-series-limit` sets the limit of only series, `--search-movie-listing-limit` of only movie listings, `--search-episode-limit` of only episodes and `--search-music-limit` of only concerts and music videos. + ```shell $ crunchy-cli search --search-top-results-limit 10 "darling in the franxx" # only return series which have 'darling' in it. do not return top results which might also be non-series items @@ -391,6 +455,7 @@ The `archive` command lets you download episodes with multiple audios and subtit # this returns 2 top results, 3 movie listings, 5 episodes and 1 music item as result $ crunchy-cli search --search-top-results-limit 2 --search-movie-listing-limit 3 --search-episode-limit 5 --search-music-limit 1 "test" ``` + Default is `5` for `--search-top-results-limit`, `0` for all others. - Output template @@ -401,9 +466,11 @@ The `archive` command lets you download episodes with multiple audios and subtit The required pattern for this begins with `{{`, then the keyword, and closes with `}}` (e.g. `{{episode.title}}`). For example, if you want to get the title of an episode, you can use `Title: {{episode.title}}` and `{{episode.title}}` will be replaced with the episode title. You can see all supported keywords with `crunchy-cli search --help`. + ```shell $ crunchy-cli search -o "{{series.title}}" https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` + Default is `S{{season.number}}E{{episode.number}} - {{episode.title}}`. --- @@ -425,6 +492,7 @@ You can use various template options to change how the filename is processed. Th - `{episode_id}` → ID of the episode Example: + ```shell $ crunchy-cli archive -o "[S{season_number}E{episode_number}] {title}.mkv" https://www.crunchyroll.com/series/G8DHV7W21/dragon-ball # Output file: '[S01E01] Secret of the Dragon Ball.mkv' @@ -438,6 +506,7 @@ A filter pattern may consist of either a season, an episode, or a combination of When used in combination, seasons `S` must be defined before episodes `E`. There are many possible patterns, for example: + - `...[E5]` - Download the fifth episode. - `...[S1]` - Download the whole first season. - `...[-S2]` - Download the first two seasons. @@ -447,6 +516,7 @@ There are many possible patterns, for example: - `...[S1-S3,S4E2-S4E6]` - Download season one to three, then episodes two to six from season four. In practice, it would look like this: + ``` https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx[E1-E5] ``` From 7594412f5845d0746df755b9536413432ed3a36a Mon Sep 17 00:00:00 2001 From: kennedy <854543+kennedy@users.noreply.github.com> Date: Thu, 2 Nov 2023 08:37:40 -0400 Subject: [PATCH 113/272] updated brew url (#263) * updated brew url Its most appropriate to forward users to the brew's information page generated for crunchy-cli. There are stats on amount of downloads, see where the manifest is location, and what architectures are built for it. * Update README.md Co-authored-by: ByteDream <63594396+ByteDream@users.noreply.github.com> --------- Co-authored-by: ByteDream <63594396+ByteDream@users.noreply.github.com> --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aa99c45..3cbb8c9 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Check out the [releases](https://github.com/crunchy-labs/crunchy-cli/releases) t - [Homebrew](https://brew.sh/) - For macOS/linux users, we support the [brew](https://brew.sh/#/) command-line installer. Packages are compile by the [homebrew project](https://github.com/Homebrew/homebrew-core/pkgs/container/core%2Fcrunchy-cli), and will also install the `openssl@3` and `ffmpeg` dependencies. + For macOS/linux users, we support the [brew](https://brew.sh/#/) command-line installer. Packages are compiled by the [homebrew project](https://formulae.brew.sh/formula/crunchy-cli), and will also install the `openssl@3` and `ffmpeg` dependencies. ```shell $ brew install crunchy-cli From 787d8ab02c206a763b2e5a81b413aee11bfe11b5 Mon Sep 17 00:00:00 2001 From: bytedream Date: Sat, 4 Nov 2023 15:24:14 +0100 Subject: [PATCH 114/272] Add --special-output and --skip-specials flag --- crunchy-cli-core/src/archive/command.rs | 36 ++++++++++++++++--- crunchy-cli-core/src/archive/filter.rs | 16 ++++++++- crunchy-cli-core/src/download/command.rs | 44 +++++++++++++++++++++--- crunchy-cli-core/src/download/filter.rs | 16 ++++++++- crunchy-cli-core/src/utils/format.rs | 4 +++ 5 files changed, 106 insertions(+), 10 deletions(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 7d28e2e..f6da256 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -54,6 +54,11 @@ pub struct Archive { {episode_id} → ID of the episode")] #[arg(short, long, default_value = "{title}.mkv")] pub(crate) output: String, + #[arg(help = "Name of the output file if the episode is a special")] + #[arg(long_help = "Name of the output file if the episode is a special. \ + If not set, the '-o'/'--output' flag will be used as name template")] + #[arg(long)] + pub(crate) special_output: Option, #[arg(help = "Video resolution")] #[arg(long_help = "The video resolution.\ @@ -95,6 +100,9 @@ pub struct Archive { #[arg(help = "Skip files which are already existing")] #[arg(long, default_value_t = false)] pub(crate) skip_existing: bool, + #[arg(help = "Skip special episodes")] + #[arg(long, default_value_t = false)] + pub(crate) skip_specials: bool, #[arg(help = "Skip any interactive input")] #[arg(short, long, default_value_t = false)] @@ -123,6 +131,17 @@ impl Execute for Archive { && self.output != "-" { bail!("File extension is not '.mkv'. Currently only matroska / '.mkv' files are supported") + } else if let Some(special_output) = &self.special_output { + if PathBuf::from(special_output) + .extension() + .unwrap_or_default() + .to_string_lossy() + != "mkv" + && !is_special_file(special_output) + && special_output != "-" + { + bail!("File extension for special episodes is not '.mkv'. Currently only matroska / '.mkv' files are supported") + } } self.audio = all_locale_in_locales(self.audio.clone()); @@ -147,9 +166,10 @@ 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 = ArchiveFilter::new(url_filter, self.clone(), !self.yes) - .visit(media_collection) - .await?; + let single_format_collection = + ArchiveFilter::new(url_filter, self.clone(), !self.yes, self.skip_specials) + .visit(media_collection) + .await?; if single_format_collection.is_empty() { progress_handler.stop(format!("Skipping url {} (no matching videos found)", i + 1)); @@ -175,7 +195,15 @@ impl Execute for Archive { downloader.add_format(download_format) } - let formatted_path = format.format_path((&self.output).into()); + let formatted_path = if format.is_special() { + format.format_path( + self.special_output + .as_ref() + .map_or((&self.output).into(), |so| so.into()), + ) + } else { + format.format_path((&self.output).into()) + }; let (path, changed) = free_file(formatted_path.clone()); if changed && self.skip_existing { diff --git a/crunchy-cli-core/src/archive/filter.rs b/crunchy-cli-core/src/archive/filter.rs index 91023a3..a4e3188 100644 --- a/crunchy-cli-core/src/archive/filter.rs +++ b/crunchy-cli-core/src/archive/filter.rs @@ -18,6 +18,7 @@ pub(crate) struct ArchiveFilter { url_filter: UrlFilter, archive: Archive, interactive_input: bool, + skip_special: bool, season_episodes: HashMap>, season_subtitles_missing: Vec, season_sorting: Vec, @@ -25,11 +26,17 @@ pub(crate) struct ArchiveFilter { } impl ArchiveFilter { - pub(crate) fn new(url_filter: UrlFilter, archive: Archive, interactive_input: bool) -> Self { + pub(crate) fn new( + url_filter: UrlFilter, + archive: Archive, + interactive_input: bool, + skip_special: bool, + ) -> Self { Self { url_filter, archive, interactive_input, + skip_special, season_episodes: HashMap::new(), season_subtitles_missing: vec![], season_sorting: vec![], @@ -246,6 +253,13 @@ impl Filter for ArchiveFilter { return Ok(None); } + // skip the episode if it's a special + if self.skip_special + && (episode.sequence_number == 0.0 || episode.sequence_number.fract() != 0.0) + { + return Ok(None); + } + let mut episodes = vec![]; if !matches!(self.visited, Visited::Series) && !matches!(self.visited, Visited::Season) { if self.archive.audio.contains(&episode.audio_locale) { diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index 376cc2d..da885c3 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -50,6 +50,11 @@ pub struct Download { {episode_id} → ID of the episode")] #[arg(short, long, default_value = "{title}.mp4")] pub(crate) output: String, + #[arg(help = "Name of the output file if the episode is a special")] + #[arg(long_help = "Name of the output file if the episode is a special. \ + If not set, the '-o'/'--output' flag will be used as name template")] + #[arg(long)] + pub(crate) special_output: Option, #[arg(help = "Video resolution")] #[arg(long_help = "The video resolution.\ @@ -73,6 +78,9 @@ pub struct Download { #[arg(help = "Skip files which are already existing")] #[arg(long, default_value_t = false)] pub(crate) skip_existing: bool, + #[arg(help = "Skip special episodes")] + #[arg(long, default_value_t = false)] + pub(crate) skip_specials: bool, #[arg(help = "Skip any interactive input")] #[arg(short, long, default_value_t = false)] @@ -116,6 +124,25 @@ impl Execute for Download { } } + if let Some(special_output) = &self.special_output { + if Path::new(special_output) + .extension() + .unwrap_or_default() + .is_empty() + && !is_special_file(special_output) + && special_output != "-" + { + bail!("No file extension found. Please specify a file extension (via `--special-output`) for the output file") + } + if let Some(ext) = Path::new(special_output).extension() { + if self.force_hardsub { + warn!("Hardsubs are forced for special episodes. Adding subtitles may take a while") + } else if !["mkv", "mov", "mp4"].contains(&ext.to_string_lossy().as_ref()) { + warn!("Detected a container which does not support softsubs. Adding subtitles for special episodes may take a while") + } + } + } + Ok(()) } @@ -135,9 +162,10 @@ impl Execute for Download { for (i, (media_collection, url_filter)) in parsed_urls.into_iter().enumerate() { let progress_handler = progress!("Fetching series details"); - let single_format_collection = DownloadFilter::new(url_filter, self.clone(), !self.yes) - .visit(media_collection) - .await?; + let single_format_collection = + DownloadFilter::new(url_filter, self.clone(), !self.yes, self.skip_specials) + .visit(media_collection) + .await?; if single_format_collection.is_empty() { progress_handler.stop(format!("Skipping url {} (no matching videos found)", i + 1)); @@ -167,7 +195,15 @@ impl Execute for Download { let mut downloader = download_builder.clone().build(); downloader.add_format(download_format); - let formatted_path = format.format_path((&self.output).into()); + let formatted_path = if format.is_special() { + format.format_path( + self.special_output + .as_ref() + .map_or((&self.output).into(), |so| so.into()), + ) + } else { + format.format_path((&self.output).into()) + }; let (path, changed) = free_file(formatted_path.clone()); if changed && self.skip_existing { diff --git a/crunchy-cli-core/src/download/filter.rs b/crunchy-cli-core/src/download/filter.rs index 55b1e8b..626896c 100644 --- a/crunchy-cli-core/src/download/filter.rs +++ b/crunchy-cli-core/src/download/filter.rs @@ -12,17 +12,24 @@ pub(crate) struct DownloadFilter { url_filter: UrlFilter, download: Download, interactive_input: bool, + skip_special: bool, season_episodes: HashMap>, season_subtitles_missing: Vec, season_visited: bool, } impl DownloadFilter { - pub(crate) fn new(url_filter: UrlFilter, download: Download, interactive_input: bool) -> Self { + pub(crate) fn new( + url_filter: UrlFilter, + download: Download, + interactive_input: bool, + skip_special: bool, + ) -> Self { Self { url_filter, download, interactive_input, + skip_special, season_episodes: HashMap::new(), season_subtitles_missing: vec![], season_visited: false, @@ -132,6 +139,13 @@ impl Filter for DownloadFilter { return Ok(None); } + // skip the episode if it's a special + if self.skip_special + && (episode.sequence_number == 0.0 || episode.sequence_number.fract() != 0.0) + { + return Ok(None); + } + // check if the audio locale is correct. // should only be incorrect if the console input was a episode url. otherwise // `DownloadFilter::visit_season` returns the correct episodes with matching audio diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index 4679878..4afaa07 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -473,6 +473,10 @@ impl Format { tab_info!("FPS: {:.2}", self.fps) } + pub fn is_special(&self) -> bool { + self.sequence_number == 0.0 || self.sequence_number.fract() != 0.0 + } + pub fn has_relative_fmt>(s: S) -> bool { return s.as_ref().contains("{relative_episode_number}") || s.as_ref().contains("{relative_sequence_number}"); From e5d9c27af7bf2056dfd96ca87bbe34506674a73f Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 6 Nov 2023 21:10:15 +0100 Subject: [PATCH 115/272] Fix ass filter path escape on windows (#262) --- crunchy-cli-core/src/utils/download.rs | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index ff9f240..23d5863 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -378,8 +378,27 @@ impl Downloader { output_presets.extend([ "-vf".to_string(), format!( - "ass={}", - subtitles.get(position).unwrap().path.to_str().unwrap() + "ass='{}'", + // ffmpeg doesn't removes all ':' and '\' from the filename when using + // the ass filter. well, on windows these characters are used in + // absolute paths, so they have to be correctly escaped here + if cfg!(windows) { + subtitles + .get(position) + .unwrap() + .path + .to_str() + .unwrap() + .replace('\\', "\\\\") + .replace(':', "\\:") + } else { + subtitles + .get(position) + .unwrap() + .path + .to_string_lossy() + .to_string() + } ), ]) } From f31437fba2bc675fbfeb431f30b01dac5463708f Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 6 Nov 2023 21:20:43 +0100 Subject: [PATCH 116/272] Remove leading and trailing whitespaces from output file --- crunchy-cli-core/src/utils/os.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/utils/os.rs b/crunchy-cli-core/src/utils/os.rs index 1f76b90..0596789 100644 --- a/crunchy-cli-core/src/utils/os.rs +++ b/crunchy-cli-core/src/utils/os.rs @@ -96,7 +96,7 @@ lazy_static::lazy_static! { /// is based of the implementation of the /// [`sanitize-filename`](https://crates.io/crates/sanitize-filename) crate. pub fn sanitize>(path: S, include_path_separator: bool) -> String { - let path = Cow::from(path.as_ref()); + let path = Cow::from(path.as_ref().trim()); let path = ILLEGAL_RE.replace_all(&path, ""); let path = CONTROL_RE.replace_all(&path, ""); From cd35dfe2766f6448ea43747dcfe1c24c2f599c51 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 6 Nov 2023 21:48:49 +0100 Subject: [PATCH 117/272] Rename --special-output to --output-specials --- crunchy-cli-core/src/archive/command.rs | 6 +++--- crunchy-cli-core/src/download/command.rs | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index f6da256..0ee723e 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -58,7 +58,7 @@ pub struct Archive { #[arg(long_help = "Name of the output file if the episode is a special. \ If not set, the '-o'/'--output' flag will be used as name template")] #[arg(long)] - pub(crate) special_output: Option, + pub(crate) output_specials: Option, #[arg(help = "Video resolution")] #[arg(long_help = "The video resolution.\ @@ -131,7 +131,7 @@ impl Execute for Archive { && self.output != "-" { bail!("File extension is not '.mkv'. Currently only matroska / '.mkv' files are supported") - } else if let Some(special_output) = &self.special_output { + } else if let Some(special_output) = &self.output_specials { if PathBuf::from(special_output) .extension() .unwrap_or_default() @@ -197,7 +197,7 @@ impl Execute for Archive { let formatted_path = if format.is_special() { format.format_path( - self.special_output + self.output_specials .as_ref() .map_or((&self.output).into(), |so| so.into()), ) diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index da885c3..18355cd 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -54,7 +54,7 @@ pub struct Download { #[arg(long_help = "Name of the output file if the episode is a special. \ If not set, the '-o'/'--output' flag will be used as name template")] #[arg(long)] - pub(crate) special_output: Option, + pub(crate) output_specials: Option, #[arg(help = "Video resolution")] #[arg(long_help = "The video resolution.\ @@ -124,7 +124,7 @@ impl Execute for Download { } } - if let Some(special_output) = &self.special_output { + if let Some(special_output) = &self.output_specials { if Path::new(special_output) .extension() .unwrap_or_default() @@ -132,7 +132,7 @@ impl Execute for Download { && !is_special_file(special_output) && special_output != "-" { - bail!("No file extension found. Please specify a file extension (via `--special-output`) for the output file") + bail!("No file extension found. Please specify a file extension (via `--output-specials`) for the output file") } if let Some(ext) = Path::new(special_output).extension() { if self.force_hardsub { @@ -197,7 +197,7 @@ impl Execute for Download { let formatted_path = if format.is_special() { format.format_path( - self.special_output + self.output_specials .as_ref() .map_or((&self.output).into(), |so| so.into()), ) From 56411c6547223e59c8cb4e8c61d6a29627889537 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 6 Nov 2023 22:01:44 +0100 Subject: [PATCH 118/272] Add missing whitespaces in command help --- crunchy-cli-core/src/archive/command.rs | 4 ++-- crunchy-cli-core/src/download/command.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 0ee723e..7add620 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -37,7 +37,7 @@ pub struct Archive { pub(crate) subtitle: Vec, #[arg(help = "Name of the output file")] - #[arg(long_help = "Name of the output file.\ + #[arg(long_help = "Name of the output file. \ If you use one of the following pattern they will get replaced:\n \ {title} → Title of the video\n \ {series_name} → Name of the series\n \ @@ -61,7 +61,7 @@ pub struct Archive { pub(crate) output_specials: Option, #[arg(help = "Video resolution")] - #[arg(long_help = "The video resolution.\ + #[arg(long_help = "The video resolution. \ Can either be specified via the pixels (e.g. 1920x1080), the abbreviation for pixels (e.g. 1080p) or 'common-use' words (e.g. best). \ Specifying the exact pixels is not recommended, use one of the other options instead. \ Crunchyroll let you choose the quality with pixel abbreviation on their clients, so you might be already familiar with the available options. \ diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index 18355cd..4f189c5 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -33,7 +33,7 @@ pub struct Download { pub(crate) subtitle: Option, #[arg(help = "Name of the output file")] - #[arg(long_help = "Name of the output file.\ + #[arg(long_help = "Name of the output file. \ If you use one of the following pattern they will get replaced:\n \ {title} → Title of the video\n \ {series_name} → Name of the series\n \ From fc6511a361b7ee98830385bf273cd2ce464b1058 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 6 Nov 2023 22:09:21 +0100 Subject: [PATCH 119/272] Format code --- crunchy-cli-core/src/archive/command.rs | 4 ++-- crunchy-cli-core/src/archive/filter.rs | 16 +++++++--------- crunchy-cli-core/src/download/command.rs | 2 +- crunchy-cli-core/src/download/filter.rs | 19 +++++++++---------- crunchy-cli-core/src/lib.rs | 4 ++-- crunchy-cli-core/src/search/filter.rs | 4 ++-- crunchy-cli-core/src/search/format.rs | 1 + crunchy-cli-core/src/utils/download.rs | 13 ++++++------- crunchy-cli-core/src/utils/ffmpeg.rs | 6 +++--- crunchy-cli-core/src/utils/format.rs | 15 +++++++-------- crunchy-cli-core/src/utils/locale.rs | 3 +-- crunchy-cli-core/src/utils/log.rs | 1 - crunchy-cli-core/src/utils/os.rs | 2 +- 13 files changed, 42 insertions(+), 48 deletions(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 7add620..3585e9c 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -306,8 +306,8 @@ async fn get_format( } MergeBehavior::Audio => download_formats.push(DownloadFormat { video: ( - (*format_pairs.first().unwrap()).1.clone(), - (*format_pairs.first().unwrap()).0.audio.clone(), + format_pairs.first().unwrap().1.clone(), + format_pairs.first().unwrap().0.audio.clone(), ), audios: format_pairs .iter() diff --git a/crunchy-cli-core/src/archive/filter.rs b/crunchy-cli-core/src/archive/filter.rs index a4e3188..01612b9 100644 --- a/crunchy-cli-core/src/archive/filter.rs +++ b/crunchy-cli-core/src/archive/filter.rs @@ -103,7 +103,7 @@ impl Filter for ArchiveFilter { seasons.retain(|s| !remove_ids.contains(&s.id)); let duplicated_seasons = get_duplicated_seasons(&seasons); - if duplicated_seasons.len() > 0 { + if !duplicated_seasons.is_empty() { if self.interactive_input { check_for_duplicated_seasons(&mut seasons); } else { @@ -139,8 +139,7 @@ impl Filter for ArchiveFilter { if !matches!(self.visited, Visited::Series) { let mut audio_locales: Vec = seasons .iter() - .map(|s| s.audio_locales.clone()) - .flatten() + .flat_map(|s| s.audio_locales.clone()) .collect(); real_dedup_vec(&mut audio_locales); let missing_audio = missing_locales(&audio_locales, &self.archive.audio); @@ -158,8 +157,7 @@ impl Filter for ArchiveFilter { let subtitle_locales: Vec = seasons .iter() - .map(|s| s.subtitle_locales.clone()) - .flatten() + .flat_map(|s| s.subtitle_locales.clone()) .collect(); let missing_subtitle = missing_locales(&subtitle_locales, &self.archive.subtitle); if !missing_subtitle.is_empty() { @@ -211,7 +209,7 @@ impl Filter for ArchiveFilter { } } if eps.len() < before_len { - if eps.len() == 0 { + if eps.is_empty() { if matches!(self.visited, Visited::Series) { warn!( "Season {} is not available with {} audio", @@ -237,7 +235,7 @@ impl Filter for ArchiveFilter { for episode in episodes.iter() { self.season_episodes .entry(episode.season_id.clone()) - .or_insert(vec![]) + .or_default() .push(episode.clone()) } } @@ -290,7 +288,7 @@ impl Filter for ArchiveFilter { } let mut subtitle_locales: Vec = - episodes.iter().map(|(_, s)| s.clone()).flatten().collect(); + episodes.iter().flat_map(|(_, s)| s.clone()).collect(); real_dedup_vec(&mut subtitle_locales); let missing_subtitles = missing_locales(&subtitle_locales, &self.archive.subtitle); if !missing_subtitles.is_empty() @@ -435,6 +433,6 @@ impl Filter for ArchiveFilter { } } -fn missing_locales<'a>(available: &Vec, searched: &'a Vec) -> Vec<&'a Locale> { +fn missing_locales<'a>(available: &[Locale], searched: &'a [Locale]) -> Vec<&'a Locale> { searched.iter().filter(|p| !available.contains(p)).collect() } diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index 4f189c5..82cb8f8 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -251,7 +251,7 @@ async fn get_format( }; let subtitle = if let Some(subtitle_locale) = &download.subtitle { - stream.subtitles.get(subtitle_locale).map(|s| s.clone()) + stream.subtitles.get(subtitle_locale).cloned() } else { None }; diff --git a/crunchy-cli-core/src/download/filter.rs b/crunchy-cli-core/src/download/filter.rs index 626896c..fb2e563 100644 --- a/crunchy-cli-core/src/download/filter.rs +++ b/crunchy-cli-core/src/download/filter.rs @@ -45,14 +45,13 @@ impl Filter for DownloadFilter { 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() { - if !series.audio_locales.contains(&self.download.audio) { - error!( - "Series {} is not available with {} audio", - series.title, self.download.audio - ); - return Ok(vec![]); - } + if !series.audio_locales.is_empty() && !series.audio_locales.contains(&self.download.audio) + { + error!( + "Series {} is not available with {} audio", + series.title, self.download.audio + ); + return Ok(vec![]); } let mut seasons = vec![]; @@ -91,7 +90,7 @@ impl Filter for DownloadFilter { } let duplicated_seasons = get_duplicated_seasons(&seasons); - if duplicated_seasons.len() > 0 { + if !duplicated_seasons.is_empty() { if self.interactive_input { check_for_duplicated_seasons(&mut seasons); } else { @@ -118,7 +117,7 @@ impl Filter for DownloadFilter { for episode in episodes.iter() { self.season_episodes .entry(episode.season_number) - .or_insert(vec![]) + .or_default() .push(episode.clone()) } } diff --git a/crunchy-cli-core/src/lib.rs b/crunchy-cli-core/src/lib.rs index 02bef6f..d6c2220 100644 --- a/crunchy-cli-core/src/lib.rs +++ b/crunchy-cli-core/src/lib.rs @@ -77,7 +77,7 @@ fn version() -> String { let build_date = env!("BUILD_DATE"); if git_commit_hash.is_empty() { - format!("{}", package_version) + package_version.to_string() } else { format!("{} ({} {})", package_version, git_commit_hash, build_date) } @@ -250,7 +250,7 @@ async fn crunchyroll_session(cli: &mut Cli) -> Result { "Via `--lang` specified language is not supported. Supported languages: {}", supported_langs .iter() - .map(|l| format!("`{}` ({})", l.to_string(), l.to_human_readable())) + .map(|l| format!("`{}` ({})", l, l.to_human_readable())) .collect::>() .join(", ") ) diff --git a/crunchy-cli-core/src/search/filter.rs b/crunchy-cli-core/src/search/filter.rs index 264b31d..3bb6d9f 100644 --- a/crunchy-cli-core/src/search/filter.rs +++ b/crunchy-cli-core/src/search/filter.rs @@ -21,7 +21,7 @@ impl FilterOptions { pub fn filter_episodes(&self, mut episodes: Vec) -> Vec { episodes.retain(|e| { - self.check_audio_language(&vec![e.audio_locale.clone()]) + self.check_audio_language(&[e.audio_locale.clone()]) && self .url_filter .is_episode_valid(e.sequence_number, e.season_number) @@ -38,7 +38,7 @@ impl FilterOptions { ) } - fn check_audio_language(&self, audio: &Vec) -> bool { + fn check_audio_language(&self, audio: &[Locale]) -> bool { if !self.audio.is_empty() { return self.audio.iter().any(|a| audio.contains(a)); } diff --git a/crunchy-cli-core/src/search/format.rs b/crunchy-cli-core/src/search/format.rs index 55cba7c..f9746b1 100644 --- a/crunchy-cli-core/src/search/format.rs +++ b/crunchy-cli-core/src/search/format.rs @@ -372,6 +372,7 @@ impl Format { let stream_empty = self.check_pattern_count_empty(Scope::Stream) && self.check_pattern_count_empty(Scope::Subtitle); + #[allow(clippy::type_complexity)] let mut tree: Vec<(Season, Vec<(Episode, Vec)>)> = vec![]; let series = if !series_empty { diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index 23d5863..945cc14 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -296,7 +296,7 @@ impl Downloader { ]); // the empty language metadata is created to avoid that metadata from the original track // is copied - metadata.extend([format!("-metadata:s:v:{}", i), format!("language=")]) + metadata.extend([format!("-metadata:s:v:{}", i), "language=".to_string()]) } for (i, meta) in audios.iter().enumerate() { input.extend(["-i".to_string(), meta.path.to_string_lossy().to_string()]); @@ -675,7 +675,7 @@ impl Downloader { let result = download().await; if result.is_err() { - after_download_sender.send((-1 as i32, vec![]))?; + after_download_sender.send((-1, vec![]))?; } result @@ -747,7 +747,7 @@ impl Downloader { } } -fn estimate_variant_file_size(variant_data: &VariantData, segments: &Vec) -> u64 { +fn estimate_variant_file_size(variant_data: &VariantData, segments: &[VariantSegment]) -> u64 { (variant_data.bandwidth / 8) * segments.iter().map(|s| s.length.as_secs()).sum::() } @@ -788,9 +788,8 @@ pub fn get_video_length(path: &Path) -> Result { /// [crunchy-labs/crunchy-cli#208](https://github.com/crunchy-labs/crunchy-cli/issues/208) for more /// information. fn fix_subtitles(raw: &mut Vec, max_length: NaiveTime) { - let re = - Regex::new(r#"^Dialogue:\s\d+,(?P\d+:\d+:\d+\.\d+),(?P\d+:\d+:\d+\.\d+),"#) - .unwrap(); + let re = Regex::new(r"^Dialogue:\s\d+,(?P\d+:\d+:\d+\.\d+),(?P\d+:\d+:\d+\.\d+),") + .unwrap(); // chrono panics if we try to format NaiveTime with `%2f` and the nano seconds has more than 2 // digits so them have to be reduced manually to avoid the panic @@ -832,7 +831,7 @@ fn fix_subtitles(raw: &mut Vec, max_length: NaiveTime) { line, format!( "Dialogue: {},{},", - format_naive_time(start.clone()), + format_naive_time(start), &length_as_string ), ) diff --git a/crunchy-cli-core/src/utils/ffmpeg.rs b/crunchy-cli-core/src/utils/ffmpeg.rs index af29bfd..787c79a 100644 --- a/crunchy-cli-core/src/utils/ffmpeg.rs +++ b/crunchy-cli-core/src/utils/ffmpeg.rs @@ -134,7 +134,7 @@ impl FFmpegPreset { description_details.push(format!("{} video quality/compression", q.to_string())) } - let description = if description_details.len() == 0 { + let description = if description_details.is_empty() { format!( "{} encoded with default video quality/compression", codec.to_string() @@ -239,7 +239,7 @@ impl FFmpegPreset { hwaccel.clone(), quality.clone(), )) { - return Err(format!("ffmpeg preset is not supported")); + return Err("ffmpeg preset is not supported".to_string()); } Ok(FFmpegPreset::Predefined( c, @@ -247,7 +247,7 @@ impl FFmpegPreset { quality.unwrap_or(FFmpegQuality::Normal), )) } else { - Err(format!("cannot use ffmpeg preset with without a codec")) + Err("cannot use ffmpeg preset with without a codec".to_string()) } } diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index 4afaa07..4c8d3c8 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -170,10 +170,7 @@ impl SingleFormat { } pub fn is_episode(&self) -> bool { - match self.source { - MediaCollection::Episode(_) => true, - _ => false, - } + matches!(self.source, MediaCollection::Episode(_)) } } @@ -181,7 +178,7 @@ struct SingleFormatCollectionEpisodeKey(f32); impl PartialOrd for SingleFormatCollectionEpisodeKey { fn partial_cmp(&self, other: &Self) -> Option { - self.0.partial_cmp(&other.0) + Some(self.cmp(other)) } } impl Ord for SingleFormatCollectionEpisodeKey { @@ -198,6 +195,7 @@ impl Eq for SingleFormatCollectionEpisodeKey {} struct SingleFormatCollectionSeasonKey((u32, String)); +#[allow(clippy::incorrect_partial_ord_impl_on_ord_type)] impl PartialOrd for SingleFormatCollectionSeasonKey { fn partial_cmp(&self, other: &Self) -> Option { let mut cmp = self.0 .0.partial_cmp(&other.0 .0); @@ -250,7 +248,7 @@ impl SingleFormatCollection { format.season_number, format.season_id.clone(), ))) - .or_insert(BTreeMap::new()) + .or_default() .insert( SingleFormatCollectionEpisodeKey(format.sequence_number), single_formats, @@ -340,6 +338,7 @@ pub struct Format { } impl Format { + #[allow(clippy::type_complexity)] pub fn from_single_formats( mut single_formats: Vec<(SingleFormat, VariantData, Vec<(Subtitle, bool)>)>, ) -> Self { @@ -349,7 +348,7 @@ impl Format { ( single_format.audio.clone(), subtitles - .into_iter() + .iter() .map(|(s, _)| s.locale.clone()) .collect::>(), ) @@ -440,7 +439,7 @@ impl Format { info!( "Downloading {} to {}", self.title, - if is_special_file(&dst) || dst.to_str().unwrap() == "-" { + if is_special_file(dst) || dst.to_str().unwrap() == "-" { dst.to_string_lossy().to_string() } else { format!("'{}'", dst.to_str().unwrap()) diff --git a/crunchy-cli-core/src/utils/locale.rs b/crunchy-cli-core/src/utils/locale.rs index d749fcb..8651078 100644 --- a/crunchy-cli-core/src/utils/locale.rs +++ b/crunchy-cli-core/src/utils/locale.rs @@ -19,8 +19,7 @@ pub fn system_locale() -> Locale { pub fn all_locale_in_locales(locales: Vec) -> Vec { if locales .iter() - .find(|l| l.to_string().to_lowercase().trim() == "all") - .is_some() + .any(|l| l.to_string().to_lowercase().trim() == "all") { Locale::all() } else { diff --git a/crunchy-cli-core/src/utils/log.rs b/crunchy-cli-core/src/utils/log.rs index 6650e58..942c652 100644 --- a/crunchy-cli-core/src/utils/log.rs +++ b/crunchy-cli-core/src/utils/log.rs @@ -57,7 +57,6 @@ macro_rules! tab_info { } pub(crate) use tab_info; -#[allow(clippy::type_complexity)] pub struct CliLogger { level: LevelFilter, progress: Mutex>, diff --git a/crunchy-cli-core/src/utils/os.rs b/crunchy-cli-core/src/utils/os.rs index 0596789..977e968 100644 --- a/crunchy-cli-core/src/utils/os.rs +++ b/crunchy-cli-core/src/utils/os.rs @@ -24,7 +24,7 @@ pub fn has_ffmpeg() -> bool { /// Get the temp directory either by the specified `CRUNCHY_CLI_TEMP_DIR` env variable or the dir /// provided by the os. pub fn temp_directory() -> PathBuf { - env::var("CRUNCHY_CLI_TEMP_DIR").map_or(env::temp_dir(), |d| PathBuf::from(d)) + env::var("CRUNCHY_CLI_TEMP_DIR").map_or(env::temp_dir(), PathBuf::from) } /// Any tempfile should be created with this function. The prefix and directory of every file From c08931b6105d3a6756862d2548e5a428c3f93272 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 6 Nov 2023 22:47:09 +0100 Subject: [PATCH 120/272] Add new commands and format option to readme --- README.md | 112 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 92 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 3cbb8c9..2491939 100644 --- a/README.md +++ b/README.md @@ -61,14 +61,6 @@ Check out the [releases](https://github.com/crunchy-labs/crunchy-cli/releases) t $ yay -S crunchy-cli-bin ``` -- [Nix](https://nixos.org/) - - This requires [nix](https://nixos.org) and you'll probably need `--extra-experimental-features "nix-command flakes"`, depending on your configurations. - - ```shell - $ nix github:crunchy-labs/crunchy-cli - ``` - - [Scoop](https://scoop.sh/) For Windows users, we support the [scoop](https://scoop.sh/#/) command-line installer. @@ -88,6 +80,14 @@ Check out the [releases](https://github.com/crunchy-labs/crunchy-cli/releases) t Supported archs: `x86_64_linux`, `arm64_monterey`, `sonoma`, `ventura` +- [Nix](https://nixos.org/) + + This requires [nix](https://nixos.org) and you'll probably need `--extra-experimental-features "nix-command flakes"`, depending on your configurations. + + ```shell + $ nix github:crunchy-labs/crunchy-cli + ``` + ### 🛠 Build it yourself Since we do not support every platform and architecture you may have to build the project yourself. @@ -191,6 +191,17 @@ You can set specific settings which will be Make sure that proxy can either forward TLS requests, which is needed to bypass the (cloudflare) bot protection, or that it is configured so that the proxy can bypass the protection itself. +- User Agent + + There might be cases where a custom user agent is necessary, e.g. to bypass the cloudflare bot protection (#104). + In such cases, the `--user-agent` flag can be used to set a custom user agent. + + ```shell + $ crunchy-cli --user-agent "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)" + ``` + + Default is the user agent, defined in the underlying [library](https://github.com/crunchy-labs/crunchyroll-rs). + ### Login The `login` command can store your session, so you don't have to authenticate every time you execute a command. @@ -254,6 +265,16 @@ The `download` command lets you download episodes with a specific audio language Default is `{title}.mp4`. See the [Template Options section](#output-template-options) below for more options. +- Output template for special episodes + + Define an output template which only gets used when the episode is a special (episode number is 0 or has non-zero decimal places) by using the `--output-special` flag. + + ```shell + $ crunchy-cli download --output-specials -o "Special EP: {title}" https://www.crunchyroll.com/watch/GY8D975JY/veldoras-journal + ``` + + Default is the template, set by the `-o` / `--output` flag. See the [Template Options section](#output-template-options) below for more options. + - Resolution The resolution for videos can be set via the `-r` / `--resolution` flag. @@ -282,6 +303,14 @@ The `download` command lets you download episodes with a specific audio language $ crunchy-cli download --skip-existing https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` +- Skip specials + + If you doesn't want to download special episodes, use the `--skip-specials` flag to skip the download of them. + + ```shell + $ crunchy-cli download --skip-specials https://www.crunchyroll.com/series/GYZJ43JMR/that-time-i-got-reincarnated-as-a-slime[S2] + ``` + - Yes Sometimes different seasons have the same season number (e.g. Sword Art Online Alicization and Alicization War of Underworld are both marked as season 3), in such cases an interactive prompt is shown which needs user further user input to decide which season to download. @@ -301,6 +330,17 @@ The `download` command lets you download episodes with a specific audio language $ crunchy-cli download --force-hardsub -s en-US https://www.crunchyroll.com/watch/GRDQPM1ZY/alone-and-lonesome ``` +- Threads + + To increase the download speed, video segments are downloaded simultaneously by creating multiple threads. + If you want to manually specify how many threads to use when downloading, do this with the `-t` / `--threads` flag. + + ```shell + $ crunchy-cli download -t 1 https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + ``` + + The default thread count is the count of cpu threads your pc has. + ### Archive The `archive` command lets you download episodes with multiple audios and subtitles and merges it into a `.mkv` file. @@ -341,7 +381,7 @@ The `archive` command lets you download episodes with multiple audios and subtit - Output template Define an output template by using the `-o` / `--output` flag. - crunchy-cli uses the [`.mkv`](https://en.wikipedia.org/wiki/Matroska) container format, because of it's ability to store multiple audio, video and subtitle tracks at once. + _crunchy-cli_ exclusively uses the [`.mkv`](https://en.wikipedia.org/wiki/Matroska) container format, because of its ability to store multiple audio, video and subtitle tracks at once. ```shell $ crunchy-cli archive -o "{title}.mkv" https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx @@ -349,6 +389,17 @@ The `archive` command lets you download episodes with multiple audios and subtit Default is `{title}.mkv`. See the [Template Options section](#output-template-options) below for more options. +- Output template for special episodes + + Define an output template which only gets used when the episode is a special (episode number is 0 or has non-zero decimal places) by using the `--output-special` flag. + _crunchy-cli_ exclusively uses the [`.mkv`](https://en.wikipedia.org/wiki/Matroska) container format, because of its ability to store multiple audio, video and subtitle tracks at once. + + ```shell + $ crunchy-cli archive --output-specials -o "Special EP: {title}" https://www.crunchyroll.com/watch/GY8D975JY/veldoras-journal + ``` + + Default is the template, set by the `-o` / `--output` flag. See the [Template Options section](#output-template-options) below for more options. + - Resolution The resolution for videos can be set via the `-r` / `--resolution` flag. @@ -402,6 +453,14 @@ The `archive` command lets you download episodes with multiple audios and subtit $ crunchy-cli archive --skip-existing https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx ``` +- Skip specials + + If you doesn't want to download special episodes, use the `--skip-specials` flag to skip the download of them. + + ```shell + $ crunchy-cli archive --skip-specials https://www.crunchyroll.com/series/GYZJ43JMR/that-time-i-got-reincarnated-as-a-slime[S2] + ``` + - Yes Sometimes different seasons have the same season number (e.g. Sword Art Online Alicization and Alicization War of Underworld are both marked as season 3), in such cases an interactive prompt is shown which needs user further user input to decide which season to download. @@ -413,6 +472,17 @@ The `archive` command lets you download episodes with multiple audios and subtit If you've passed the `-q` / `--quiet` [global flag](#global-settings), this flag is automatically set. +- Threads + + To increase the download speed, video segments are downloaded simultaneously by creating multiple threads. + If you want to manually specify how many threads to use when downloading, do this with the `-t` / `--threads` flag. + + ```shell + $ crunchy-cli archive -t 1 https://www.crunchyroll.com/series/GY8VEQ95Y/darling-in-the-franxx + ``` + + The default thread count is the count of cpu threads your pc has. + ### Search **Supported urls/input** @@ -479,17 +549,19 @@ The `archive` command lets you download episodes with multiple audios and subtit You can use various template options to change how the filename is processed. The following tags are available: -- `{title}` → Title of the video -- `{series_name}` → Name of the series -- `{season_name}` → Name of the season -- `{audio}` → Audio language of the video -- `{resolution}` → Resolution of the video -- `{season_number}` → Number of the season -- `{episode_number}` → Number of the episode -- `{relative_episode_number}` → Number of the episode relative to its season -- `{series_id}` → ID of the series -- `{season_id}` → ID of the season -- `{episode_id}` → ID of the episode +- `{title}` → Title of the video +- `{series_name}` → Name of the series +- `{season_name}` → Name of the season +- `{audio}` → Audio language of the video +- `{resolution}` → Resolution of the video +- `{season_number}` → Number of the season +- `{episode_number}` → Number of the episode +- `{relative_episode_number}` → Number of the episode relative to its season +- `{sequence_number}` → Like `{episode_number}` but without possible non-number characters +- `{relative_sequence_number}` → Like `{relative_episode_number}` but with support for episode 0's and .5's +- `{series_id}` → ID of the series +- `{season_id}` → ID of the season +- `{episode_id}` → ID of the episode Example: From d52fe7fb923b7b60c0b54b3cda2fe3bf1087bb09 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 6 Nov 2023 22:56:51 +0100 Subject: [PATCH 121/272] Update dependencies and version --- Cargo.lock | 436 ++++++++++++++++++------------------ Cargo.toml | 4 +- crunchy-cli-core/Cargo.toml | 8 +- 3 files changed, 228 insertions(+), 220 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 409a005..8608f0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] @@ -54,9 +54,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.5.0" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" dependencies = [ "anstyle", "anstyle-parse", @@ -68,15 +68,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" dependencies = [ "utf8parse", ] @@ -92,9 +92,9 @@ dependencies = [ [[package]] name = "anstyle-wincon" -version = "2.1.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", "windows-sys 0.48.0", @@ -108,9 +108,9 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", @@ -140,9 +140,9 @@ dependencies = [ [[package]] name = "base64" -version = "0.21.4" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64-serde" @@ -162,9 +162,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" [[package]] name = "block-padding" @@ -238,9 +238,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.4" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" +checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" dependencies = [ "clap_builder", "clap_derive", @@ -248,9 +248,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.4" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" +checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" dependencies = [ "anstream", "anstyle", @@ -260,18 +260,18 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.4.1" +version = "4.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4110a1e6af615a9e6d0a36f805d5c99099f8bab9b8042f5bc1fa220a4a89e36f" +checksum = "bffe91f06a11b4b9420f62103854e90867812cd5d01557f853c5ee8e791b12ae" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ "heck", "proc-macro2", @@ -281,15 +281,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" [[package]] name = "clap_mangen" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b44f35c514163027542f7147797ff930523eea288e03642727348ef1a9666f6b" +checksum = "d3be86020147691e1d2ef58f75346a3d4d94807bfc473e377d52f09f0f7d77f7" dependencies = [ "clap", "roff", @@ -360,16 +360,16 @@ checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] [[package]] name = "crunchy-cli" -version = "3.0.3" +version = "3.1.0" dependencies = [ "chrono", "clap", @@ -382,7 +382,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.0.3" +version = "3.1.0" dependencies = [ "anyhow", "async-trait", @@ -412,9 +412,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771cd92c5a4cc050f301674d77bca6c23f8f260ef346bd06c11b4b05ab9e0166" +checksum = "19bdd19b3f1b26e1a45ed32f7b2db68981111a9f5e9551b2d225bf470dca1e11" dependencies = [ "aes", "async-trait", @@ -439,9 +439,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs-internal" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b260191f1125c7ba31e35071524938de5c6b0c2d248e5a35c62c4605e2da427e" +checksum = "f0a12fb14fd65dede6da7dad3e4c434f6aee9c18cf2bae0d2cc5021cd5a29fec" dependencies = [ "darling", "quote", @@ -505,9 +505,9 @@ dependencies = [ [[package]] name = "dash-mpd" -version = "0.13.1" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b18de4d072c5be455129422f6a69eb17c032467750d857820cb0c9a92e86a4ed" +checksum = "ad33027a1ac2f37def4c33a5987a8e047fd34f77ff7cabc14bd437aa6d8d4dd2" dependencies = [ "base64", "base64-serde", @@ -522,15 +522,17 @@ dependencies = [ "serde_with", "thiserror", "tokio", + "url", "xattr", ] [[package]] name = "deranged" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" dependencies = [ + "powerfmt", "serde", ] @@ -607,30 +609,19 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" dependencies = [ - "errno-dragonfly", "libc", "windows-sys 0.48.0", ] -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "fastrand" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "fnv" @@ -680,50 +671,38 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" - -[[package]] -name = "futures-macro" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" dependencies = [ "futures-core", - "futures-macro", "futures-task", "pin-project-lite", "pin-utils", @@ -784,9 +763,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "heck" @@ -857,7 +836,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "socket2 0.4.10", "tokio", "tower-service", "tracing", @@ -866,9 +845,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", "http", @@ -893,16 +872,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows-core", ] [[package]] @@ -964,12 +943,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.2", "serde", ] @@ -1007,9 +986,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "iso8601" @@ -1028,9 +1007,9 @@ checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] @@ -1043,15 +1022,26 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.148" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.1", + "libc", + "redox_syscall", +] [[package]] name = "linux-raw-sys" -version = "0.4.7" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] name = "log" @@ -1077,9 +1067,9 @@ checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "memchr" -version = "2.6.3" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "mime" @@ -1104,9 +1094,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" dependencies = [ "libc", "wasi", @@ -1135,7 +1125,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "cfg-if", "libc", ] @@ -1152,9 +1142,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] @@ -1192,11 +1182,11 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.57" +version = "0.10.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" +checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "cfg-if", "foreign-types", "libc", @@ -1224,18 +1214,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.1.5+3.1.3" +version = "300.1.6+3.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "559068e4c12950d7dcaa1857a61725c0d38d4fc03ff8e070ab31a75d6e316491" +checksum = "439fac53e092cd7442a3660c85dde4643ab3b5bd39040912388dcdabf6b88085" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.93" +version = "0.9.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d" +checksum = "40a4130519a360279579c2053038317e40eff64d13fd3f004f9e1b72b8a6aaf9" dependencies = [ "cc", "libc", @@ -1276,15 +1266,21 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "portable-atomic" -version = "1.4.3" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31114a898e107c51bb1609ffaf55a0e011cf6a4d7f1170d0015a165082c0338b" +checksum = "3bccab0e7fd7cc19f820a1c8c91720af652d0c88dc9664dd72aef2614f04af3b" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -1307,9 +1303,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.30.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" dependencies = [ "memchr", "serde", @@ -1326,38 +1322,29 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" dependencies = [ "getrandom", - "redox_syscall 0.2.16", + "libredox", "thiserror", ] [[package]] name = "regex" -version = "1.9.5" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", @@ -1367,9 +1354,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.8" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", @@ -1378,15 +1365,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.20" +version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ "base64", "bytes", @@ -1414,6 +1401,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "system-configuration", "tokio", "tokio-native-tls", "tokio-rustls", @@ -1429,17 +1417,16 @@ dependencies = [ [[package]] name = "ring" -version = "0.16.20" +version = "0.17.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" dependencies = [ "cc", + "getrandom", "libc", - "once_cell", "spin", "untrusted", - "web-sys", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -1456,11 +1443,11 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.14" +version = "0.38.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.4.1", "errno", "libc", "linux-raw-sys", @@ -1469,9 +1456,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" dependencies = [ "log", "ring", @@ -1502,9 +1489,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.6" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ "ring", "untrusted", @@ -1527,9 +1514,9 @@ dependencies = [ [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ "ring", "untrusted", @@ -1560,18 +1547,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.188" +version = "1.0.191" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "a834c4821019838224821468552240d4d95d14e751986442c816572d39a080c9" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.191" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "46fa52d5646bce91b680189fe5b1c049d2ea38dabb4e2e7c8d00ca12cfbfbcfd" dependencies = [ "proc-macro2", "quote", @@ -1580,9 +1567,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -1612,15 +1599,15 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca3b16a3d82c4088f343b7480a93550b3eabe1a358569c2dfe38bbcead07237" +checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" dependencies = [ "base64", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.0.0", + "indexmap 2.1.0", "serde", "serde_json", "serde_with_macros", @@ -1629,9 +1616,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e6be15c453eb305019bfa438b1593c731f36a289a7853f7707ee29e870b3b3c" +checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" dependencies = [ "darling", "proc-macro2", @@ -1673,9 +1660,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi", @@ -1683,9 +1670,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", "windows-sys 0.48.0", @@ -1693,9 +1680,9 @@ dependencies = [ [[package]] name = "spin" -version = "0.5.2" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "strsim" @@ -1705,9 +1692,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "2.0.37" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -1724,32 +1711,53 @@ dependencies = [ ] [[package]] -name = "tempfile" -version = "3.8.0" +name = "system-configuration" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ "cfg-if", "fastrand", - "redox_syscall 0.3.5", + "redox_syscall", "rustix", "windows-sys 0.48.0", ] [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", @@ -1758,12 +1766,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" dependencies = [ "deranged", "itoa", + "powerfmt", "serde", "time-core", "time-macros", @@ -1771,15 +1780,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" dependencies = [ "time-core", ] @@ -1801,9 +1810,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.32.0" +version = "1.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" dependencies = [ "backtrace", "bytes", @@ -1811,7 +1820,7 @@ dependencies = [ "mio", "num_cpus", "pin-project-lite", - "socket2 0.5.4", + "socket2 0.5.5", "tokio-macros", "windows-sys 0.48.0", ] @@ -1861,9 +1870,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", @@ -1881,20 +1890,19 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "pin-project-lite", "tracing-core", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] @@ -1940,9 +1948,9 @@ checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "untrusted" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" @@ -1990,9 +1998,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2000,9 +2008,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", @@ -2015,9 +2023,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" dependencies = [ "cfg-if", "js-sys", @@ -2027,9 +2035,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2037,9 +2045,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", @@ -2050,15 +2058,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" dependencies = [ "js-sys", "wasm-bindgen", @@ -2093,10 +2101,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.48.0" +name = "windows-core" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" dependencies = [ "windows-targets 0.48.5", ] diff --git a/Cargo.toml b/Cargo.toml index e5882d6..a0c1871 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.0.3" +version = "3.1.0" edition = "2021" license = "MIT" @@ -18,7 +18,7 @@ openssl = ["openssl-tls"] openssl-static = ["openssl-tls-static"] [dependencies] -tokio = { version = "1.32", features = ["macros", "rt-multi-thread", "time"], default-features = false } +tokio = { version = "1.33", features = ["macros", "rt-multi-thread", "time"], default-features = false } native-tls-crate = { package = "native-tls", version = "0.2.11", optional = true } diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index e38cb1a..9103831 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.0.3" +version = "3.1.0" edition = "2021" license = "MIT" @@ -16,7 +16,7 @@ anyhow = "1.0" async-trait = "0.1" clap = { version = "4.4", features = ["derive", "string"] } chrono = "0.4" -crunchyroll-rs = { version = "0.6.2", features = ["dash-stream"] } +crunchyroll-rs = { version = "0.6.3", features = ["dash-stream"] } ctrlc = "3.4" dialoguer = { version = "0.11", default-features = false } dirs = "5.0" @@ -26,7 +26,7 @@ indicatif = "0.17" lazy_static = "1.4" log = { version = "0.4", features = ["std"] } num_cpus = "1.16" -regex = "1.9" +regex = "1.10" reqwest = { version = "0.11", default-features = false, features = ["socks"] } serde = "1.0" serde_json = "1.0" @@ -34,7 +34,7 @@ serde_plain = "1.0" shlex = "1.2" sys-locale = "0.3" tempfile = "3.8" -tokio = { version = "1.32", features = ["macros", "rt-multi-thread", "time"] } +tokio = { version = "1.33", features = ["macros", "rt-multi-thread", "time"] } rustls-native-certs = { version = "0.6", optional = true } [build-dependencies] From 14e71c05b84ff7458478443b2de4ee71273c61a3 Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 16 Nov 2023 13:51:30 +0100 Subject: [PATCH 122/272] Fix aur binary checksums (#266) --- .github/workflows/publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f777f9e..43ea795 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -43,8 +43,8 @@ jobs: curl -LO https://github.com/crunchy-labs/crunchy-cli/releases/download/${{ github.ref_name }}/crunchy-cli-${{ github.ref_name }}-completions.zip curl -LO https://github.com/crunchy-labs/crunchy-cli/releases/download/${{ github.ref_name }}/crunchy-cli-${{ github.ref_name }}-manpages.zip curl -LO https://raw.githubusercontent.com/crunchy-labs/crunchy-cli/${{ github.ref_name }}/LICENSE - echo "CRUNCHY_CLI_BIN_x86_64_SHA256=$(sha256sum crunchy-cli-${{ github.ref_name }}-x86_64-linux | cut -f 1 -d ' ')" >> $GITHUB_ENV - echo "CRUNCHY_CLI_BIN_aarch64_SHA256=$(sha256sum crunchy-cli-${{ github.ref_name }}-aarch64-linux | cut -f 1 -d ' ')" >> $GITHUB_ENV + echo "CRUNCHY_CLI_BIN_x86_64_SHA256=$(sha256sum crunchy-cli-${{ github.ref_name }}-linux-x86_64 | cut -f 1 -d ' ')" >> $GITHUB_ENV + echo "CRUNCHY_CLI_BIN_aarch64_SHA256=$(sha256sum crunchy-cli-${{ github.ref_name }}-linux-aarch64 | cut -f 1 -d ' ')" >> $GITHUB_ENV echo "CRUNCHY_CLI_BIN_COMPLETIONS_SHA256=$(sha256sum crunchy-cli-${{ github.ref_name }}-completions.zip | cut -f 1 -d ' ')" >> $GITHUB_ENV echo "CRUNCHY_CLI_BIN_MANPAGES_SHA256=$(sha256sum crunchy-cli-${{ github.ref_name }}-manpages.zip | cut -f 1 -d ' ')" >> $GITHUB_ENV echo "CRUNCHY_CLI_BIN_LICENSE_SHA256=$(sha256sum LICENSE | cut -f 1 -d ' ')" >> $GITHUB_ENV From 2c370939595149c20ed6ba2fbde3274134be0aad Mon Sep 17 00:00:00 2001 From: bytedream Date: Sun, 19 Nov 2023 19:24:15 +0100 Subject: [PATCH 123/272] Manually burn-in subtitles only if no pre-burned video is available (#268) --- crunchy-cli-core/src/archive/command.rs | 3 +- crunchy-cli-core/src/download/command.rs | 56 +++++++++++++++++++++--- crunchy-cli-core/src/utils/ffmpeg.rs | 2 + crunchy-cli-core/src/utils/format.rs | 4 ++ crunchy-cli-core/src/utils/video.rs | 37 ++++++++++++---- 5 files changed, 88 insertions(+), 14 deletions(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 3585e9c..006bbfa 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -248,7 +248,8 @@ async fn get_format( for single_format in single_formats { let stream = single_format.stream().await?; - let Some((video, audio)) = variant_data_from_stream(&stream, &archive.resolution).await? + let Some((video, audio, _)) = + variant_data_from_stream(&stream, &archive.resolution, None).await? else { if single_format.is_episode() { bail!( diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index 82cb8f8..cf1a049 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -1,7 +1,7 @@ use crate::download::filter::DownloadFilter; use crate::utils::context::Context; use crate::utils::download::{DownloadBuilder, DownloadFormat}; -use crate::utils::ffmpeg::FFmpegPreset; +use crate::utils::ffmpeg::{FFmpegPreset, SOFTSUB_CONTAINERS}; use crate::utils::filter::Filter; use crate::utils::format::{Format, SingleFormat}; use crate::utils::log::progress; @@ -149,6 +149,25 @@ impl Execute for Download { async fn execute(self, ctx: Context) -> Result<()> { let mut parsed_urls = vec![]; + let output_supports_softsubs = SOFTSUB_CONTAINERS.contains( + &Path::new(&self.output) + .extension() + .unwrap_or_default() + .to_string_lossy() + .as_ref(), + ); + let special_output_supports_softsubs = if let Some(so) = &self.output_specials { + SOFTSUB_CONTAINERS.contains( + &Path::new(so) + .extension() + .unwrap_or_default() + .to_string_lossy() + .as_ref(), + ) + } else { + output_supports_softsubs + }; + for (i, url) in self.urls.clone().into_iter().enumerate() { let progress_handler = progress!("Parsing url {}", i + 1); match parse_url(&ctx.crunchy, url.clone(), true).await { @@ -190,7 +209,18 @@ impl Execute for Download { // the vec contains always only one item let single_format = single_formats.remove(0); - let (download_format, format) = get_format(&self, &single_format).await?; + let (download_format, format) = get_format( + &self, + &single_format, + if self.force_hardsub { + true + } else if single_format.is_special() { + !special_output_supports_softsubs + } else { + !output_supports_softsubs + }, + ) + .await?; let mut downloader = download_builder.clone().build(); downloader.add_format(download_format); @@ -227,9 +257,19 @@ impl Execute for Download { async fn get_format( download: &Download, single_format: &SingleFormat, + try_peer_hardsubs: bool, ) -> Result<(DownloadFormat, Format)> { let stream = single_format.stream().await?; - let Some((video, audio)) = variant_data_from_stream(&stream, &download.resolution).await? + let Some((video, audio, contains_hardsub)) = variant_data_from_stream( + &stream, + &download.resolution, + if try_peer_hardsubs { + download.subtitle.clone() + } else { + None + }, + ) + .await? else { if single_format.is_episode() { bail!( @@ -250,7 +290,9 @@ async fn get_format( } }; - let subtitle = if let Some(subtitle_locale) = &download.subtitle { + let subtitle = if contains_hardsub { + None + } else if let Some(subtitle_locale) = &download.subtitle { stream.subtitles.get(subtitle_locale).cloned() } else { None @@ -266,7 +308,7 @@ async fn get_format( )] }), }; - let format = Format::from_single_formats(vec![( + let mut format = Format::from_single_formats(vec![( single_format.clone(), video, subtitle.map_or(vec![], |s| { @@ -276,6 +318,10 @@ async fn get_format( )] }), )]); + if contains_hardsub { + let (_, subs) = format.locales.get_mut(0).unwrap(); + subs.push(download.subtitle.clone().unwrap()) + } Ok((download_format, format)) } diff --git a/crunchy-cli-core/src/utils/ffmpeg.rs b/crunchy-cli-core/src/utils/ffmpeg.rs index 787c79a..7d77833 100644 --- a/crunchy-cli-core/src/utils/ffmpeg.rs +++ b/crunchy-cli-core/src/utils/ffmpeg.rs @@ -2,6 +2,8 @@ use lazy_static::lazy_static; use regex::Regex; use std::str::FromStr; +pub const SOFTSUB_CONTAINERS: [&str; 3] = ["mkv", "mov", "mp4"]; + #[derive(Clone, Debug, Eq, PartialEq)] pub enum FFmpegPreset { Predefined(FFmpegCodec, Option, FFmpegQuality), diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index 4c8d3c8..05ac232 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -172,6 +172,10 @@ impl SingleFormat { pub fn is_episode(&self) -> bool { matches!(self.source, MediaCollection::Episode(_)) } + + pub fn is_special(&self) -> bool { + self.sequence_number == 0.0 || self.sequence_number.fract() != 0.0 + } } struct SingleFormatCollectionEpisodeKey(f32); diff --git a/crunchy-cli-core/src/utils/video.rs b/crunchy-cli-core/src/utils/video.rs index 5b3eaeb..0ae4ba4 100644 --- a/crunchy-cli-core/src/utils/video.rs +++ b/crunchy-cli-core/src/utils/video.rs @@ -1,32 +1,47 @@ -use anyhow::Result; +use anyhow::{bail, Result}; use crunchyroll_rs::media::{Resolution, Stream, VariantData}; use crunchyroll_rs::Locale; pub async fn variant_data_from_stream( stream: &Stream, resolution: &Resolution, -) -> Result> { + subtitle: Option, +) -> Result> { // sometimes Crunchyroll marks episodes without real subtitles that they have subtitles and // reports that only hardsub episode are existing. the following lines are trying to prevent // potential errors which might get caused by this incorrect reporting // (https://github.com/crunchy-labs/crunchy-cli/issues/231) let mut hardsub_locales = stream.streaming_hardsub_locales(); - let hardsub_locale = if !hardsub_locales.contains(&Locale::Custom("".to_string())) + let (hardsub_locale, mut contains_hardsub) = if !hardsub_locales + .contains(&Locale::Custom("".to_string())) && !hardsub_locales.contains(&Locale::Custom(":".to_string())) { // if only one hardsub locale exists, assume that this stream doesn't really contains hardsubs if hardsub_locales.len() == 1 { - Some(hardsub_locales.remove(0)) + (Some(hardsub_locales.remove(0)), false) } else { // fallback to `None`. this should trigger an error message in `stream.dash_streaming_data` // that the requested stream is not available - None + (None, false) } } else { - None + let hardsubs_requested = subtitle.is_some(); + (subtitle, hardsubs_requested) }; - let mut streaming_data = stream.dash_streaming_data(hardsub_locale).await?; + let mut streaming_data = match stream.dash_streaming_data(hardsub_locale).await { + Ok(data) => data, + Err(e) => { + // the error variant is only `crunchyroll_rs::error::Error::Input` when the requested + // hardsub is not available + if let crunchyroll_rs::error::Error::Input { .. } = e { + contains_hardsub = false; + stream.dash_streaming_data(None).await? + } else { + bail!(e) + } + } + }; streaming_data .0 .sort_by(|a, b| a.bandwidth.cmp(&b.bandwidth).reverse()); @@ -42,5 +57,11 @@ pub async fn variant_data_from_stream( .into_iter() .find(|v| resolution.height == v.resolution.height), }; - Ok(video_variant.map(|v| (v, streaming_data.1.first().unwrap().clone()))) + Ok(video_variant.map(|v| { + ( + v, + streaming_data.1.first().unwrap().clone(), + contains_hardsub, + ) + })) } From 440ccd99b5482af43b0cec222d49a45ddd5b43e1 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 20 Nov 2023 22:05:06 +0100 Subject: [PATCH 124/272] Update dependencies and version --- Cargo.lock | 82 +++++++++++++------------ Cargo.toml | 4 +- crunchy-cli-core/Cargo.toml | 6 +- crunchy-cli-core/src/archive/filter.rs | 8 +-- crunchy-cli-core/src/download/filter.rs | 4 +- crunchy-cli-core/src/search/format.rs | 2 +- 6 files changed, 54 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8608f0e..897731f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -238,9 +238,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.7" +version = "4.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64" dependencies = [ "clap_builder", "clap_derive", @@ -248,9 +248,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.7" +version = "4.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc" dependencies = [ "anstream", "anstyle", @@ -369,7 +369,7 @@ dependencies = [ [[package]] name = "crunchy-cli" -version = "3.1.0" +version = "3.1.1" dependencies = [ "chrono", "clap", @@ -382,7 +382,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.1.0" +version = "3.1.1" dependencies = [ "anyhow", "async-trait", @@ -412,9 +412,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs" -version = "0.6.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bdd19b3f1b26e1a45ed32f7b2db68981111a9f5e9551b2d225bf470dca1e11" +checksum = "cc4ce434784eee7892ad8c3d1ecaea0c0858db51bbb295b474db38c256e8d2fb" dependencies = [ "aes", "async-trait", @@ -423,7 +423,6 @@ dependencies = [ "crunchyroll-rs-internal", "dash-mpd", "futures-util", - "http", "lazy_static", "m3u8-rs", "regex", @@ -439,9 +438,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs-internal" -version = "0.6.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0a12fb14fd65dede6da7dad3e4c434f6aee9c18cf2bae0d2cc5021cd5a29fec" +checksum = "be840f8cf2ce6afc9a9eae268d41423093141ec88f664a515d5ed2a85a66fb60" dependencies = [ "darling", "quote", @@ -505,9 +504,9 @@ dependencies = [ [[package]] name = "dash-mpd" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad33027a1ac2f37def4c33a5987a8e047fd34f77ff7cabc14bd437aa6d8d4dd2" +checksum = "5471fc46c0b229c8f2308d83be857c745c9f06cc83a433d7047909722e0453b4" dependencies = [ "base64", "base64-serde", @@ -609,9 +608,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8" dependencies = [ "libc", "windows-sys 0.48.0", @@ -655,9 +654,12 @@ dependencies = [ [[package]] name = "fs-err" -version = "2.9.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] [[package]] name = "fs2" @@ -721,9 +723,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "libc", @@ -738,9 +740,9 @@ checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "h2" -version = "0.3.21" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" dependencies = [ "bytes", "fnv", @@ -748,7 +750,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.1.0", "slab", "tokio", "tokio-util", @@ -787,9 +789,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -1039,9 +1041,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" [[package]] name = "log" @@ -1443,9 +1445,9 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" dependencies = [ "bitflags 2.4.1", "errno", @@ -1456,9 +1458,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.8" +version = "0.21.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" +checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" dependencies = [ "log", "ring", @@ -1480,9 +1482,9 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ "base64", ] @@ -1547,18 +1549,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.191" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a834c4821019838224821468552240d4d95d14e751986442c816572d39a080c9" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.191" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fa52d5646bce91b680189fe5b1c049d2ea38dabb4e2e7c8d00ca12cfbfbcfd" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" dependencies = [ "proc-macro2", "quote", @@ -1810,9 +1812,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.33.0" +version = "1.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" dependencies = [ "backtrace", "bytes", @@ -1827,9 +1829,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index a0c1871..098c048 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.1.0" +version = "3.1.1" edition = "2021" license = "MIT" @@ -18,7 +18,7 @@ openssl = ["openssl-tls"] openssl-static = ["openssl-tls-static"] [dependencies] -tokio = { version = "1.33", features = ["macros", "rt-multi-thread", "time"], default-features = false } +tokio = { version = "1.34", features = ["macros", "rt-multi-thread", "time"], default-features = false } native-tls-crate = { package = "native-tls", version = "0.2.11", optional = true } diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 9103831..5771888 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.1.0" +version = "3.1.1" edition = "2021" license = "MIT" @@ -16,7 +16,7 @@ anyhow = "1.0" async-trait = "0.1" clap = { version = "4.4", features = ["derive", "string"] } chrono = "0.4" -crunchyroll-rs = { version = "0.6.3", features = ["dash-stream"] } +crunchyroll-rs = { version = "0.7.0", features = ["dash-stream"] } ctrlc = "3.4" dialoguer = { version = "0.11", default-features = false } dirs = "5.0" @@ -34,7 +34,7 @@ serde_plain = "1.0" shlex = "1.2" sys-locale = "0.3" tempfile = "3.8" -tokio = { version = "1.33", features = ["macros", "rt-multi-thread", "time"] } +tokio = { version = "1.34", features = ["macros", "rt-multi-thread", "time"] } rustls-native-certs = { version = "0.6", optional = true } [build-dependencies] diff --git a/crunchy-cli-core/src/archive/filter.rs b/crunchy-cli-core/src/archive/filter.rs index 01612b9..1777072 100644 --- a/crunchy-cli-core/src/archive/filter.rs +++ b/crunchy-cli-core/src/archive/filter.rs @@ -223,7 +223,7 @@ impl Filter for ArchiveFilter { "Season {} is only available with {} audio until episode {} ({})", season.season_number, season_locale.unwrap_or(Locale::ja_JP), - last_episode.episode_number, + last_episode.sequence_number, last_episode.title ) } @@ -278,7 +278,7 @@ impl Filter for ArchiveFilter { if !missing_audio.is_empty() { warn!( "Episode {} is not available with {} audio", - episode.episode_number, + episode.sequence_number, missing_audio .into_iter() .map(|l| l.to_string()) @@ -298,7 +298,7 @@ impl Filter for ArchiveFilter { { warn!( "Episode {} is not available with {} subtitles", - episode.episode_number, + episode.sequence_number, missing_subtitles .into_iter() .map(|l| l.to_string()) @@ -343,7 +343,7 @@ impl Filter for ArchiveFilter { if relative_episode_number.is_none() || relative_sequence_number.is_none() { warn!( "Failed to get relative episode number for episode {} ({}) of {} season {}", - episode.episode_number, + episode.sequence_number, episode.title, episode.series_title, episode.season_number, diff --git a/crunchy-cli-core/src/download/filter.rs b/crunchy-cli-core/src/download/filter.rs index fb2e563..51f1ad8 100644 --- a/crunchy-cli-core/src/download/filter.rs +++ b/crunchy-cli-core/src/download/filter.rs @@ -158,7 +158,7 @@ impl Filter for DownloadFilter { { let error_message = format!( "Episode {} ({}) of {} season {} is not available with {} audio", - episode.episode_number, + episode.sequence_number, episode.title, episode.series_title, episode.season_number, @@ -234,7 +234,7 @@ impl Filter for DownloadFilter { if relative_episode_number.is_none() || relative_sequence_number.is_none() { warn!( "Failed to get relative episode number for episode {} ({}) of {} season {}", - episode.episode_number, + episode.sequence_number, episode.title, episode.series_title, episode.season_number, diff --git a/crunchy-cli-core/src/search/format.rs b/crunchy-cli-core/src/search/format.rs index f9746b1..156bd95 100644 --- a/crunchy-cli-core/src/search/format.rs +++ b/crunchy-cli-core/src/search/format.rs @@ -70,7 +70,7 @@ impl From<&Episode> for FormatEpisode { title: value.title.clone(), description: value.description.clone(), locale: value.audio_locale.clone(), - number: value.episode_number, + number: value.episode_number.unwrap_or_default(), sequence_number: value.sequence_number, duration: value.duration.num_milliseconds(), air_date: value.episode_air_date.timestamp(), From d5df3df95f5972495c8c317f0fb243c32ede0b37 Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 1 Dec 2023 01:02:53 +0100 Subject: [PATCH 125/272] Fix fixed subtitle formatting and sorting (#272) --- crunchy-cli-core/src/utils/download.rs | 33 +++++++++++++++++++------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index 945cc14..c65b4d2 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -17,6 +17,7 @@ use std::env; use std::io::Write; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; +use std::str::FromStr; use std::sync::Arc; use std::time::Duration; use tempfile::TempPath; @@ -788,8 +789,10 @@ pub fn get_video_length(path: &Path) -> Result { /// [crunchy-labs/crunchy-cli#208](https://github.com/crunchy-labs/crunchy-cli/issues/208) for more /// information. fn fix_subtitles(raw: &mut Vec, max_length: NaiveTime) { - let re = Regex::new(r"^Dialogue:\s\d+,(?P\d+:\d+:\d+\.\d+),(?P\d+:\d+:\d+\.\d+),") - .unwrap(); + let re = Regex::new( + r"^Dialogue:\s(?P\d+),(?P\d+:\d+:\d+\.\d+),(?P\d+:\d+:\d+\.\d+),", + ) + .unwrap(); // chrono panics if we try to format NaiveTime with `%2f` and the nano seconds has more than 2 // digits so them have to be reduced manually to avoid the panic @@ -804,9 +807,9 @@ fn fix_subtitles(raw: &mut Vec, max_length: NaiveTime) { formatted_time.split_at(2).0.parse().unwrap() } ) + .split_off(1) // <- in the ASS spec, the hour has only one digit } - let length_as_string = format_naive_time(max_length); let mut entries = (vec![], vec![]); let mut as_lines: Vec = String::from_utf8_lossy(raw.as_slice()) @@ -818,21 +821,33 @@ fn fix_subtitles(raw: &mut Vec, max_length: NaiveTime) { if line.trim() == "[Script Info]" { line.push_str("\nScaledBorderAndShadow: yes") } else if let Some(capture) = re.captures(line) { - let start = capture.name("start").map_or(NaiveTime::default(), |s| { + let mut start = capture.name("start").map_or(NaiveTime::default(), |s| { NaiveTime::parse_from_str(s.as_str(), "%H:%M:%S.%f").unwrap() }); - let end = capture.name("end").map_or(NaiveTime::default(), |s| { - NaiveTime::parse_from_str(s.as_str(), "%H:%M:%S.%f").unwrap() + let mut end = capture.name("end").map_or(NaiveTime::default(), |e| { + NaiveTime::parse_from_str(e.as_str(), "%H:%M:%S.%f").unwrap() }); - if end > max_length { + if start > max_length || end > max_length { + let layer = capture + .name("layer") + .map_or(0, |l| i32::from_str(l.as_str()).unwrap()); + + if start > max_length { + start = max_length; + } + if start > max_length || end > max_length { + end = max_length; + } + *line = re .replace( line, format!( - "Dialogue: {},{},", + "Dialogue: {},{},{},", + layer, format_naive_time(start), - &length_as_string + format_naive_time(end) ), ) .to_string() From 8f77028fcb933137d66c4f4fb2e0d3b7f4454843 Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 1 Dec 2023 01:17:49 +0100 Subject: [PATCH 126/272] Show error message instead of panicking when capturing video length of invalid file (#258) --- crunchy-cli-core/src/utils/download.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index c65b4d2..de1aed0 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -768,7 +768,13 @@ pub fn get_video_length(path: &Path) -> Result { .args(["-i", path.to_str().unwrap()]) .output()?; let ffmpeg_output = String::from_utf8(ffmpeg.stderr)?; - let caps = video_length.captures(ffmpeg_output.as_str()).unwrap(); + let caps = video_length.captures(ffmpeg_output.as_str()).map_or( + Err(anyhow::anyhow!( + "failed to get video length: {}", + ffmpeg_output + )), + Ok, + )?; Ok(NaiveTime::parse_from_str(caps.name("time").unwrap().as_str(), "%H:%M:%S%.f").unwrap()) } From 9ca3b79291da1d4d4f3f6abb4c0728f641f75ae7 Mon Sep 17 00:00:00 2001 From: bytedream Date: Sun, 3 Dec 2023 00:15:57 +0100 Subject: [PATCH 127/272] Fix spelling --- crunchy-cli-core/src/utils/ffmpeg.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/crunchy-cli-core/src/utils/ffmpeg.rs b/crunchy-cli-core/src/utils/ffmpeg.rs index 7d77833..39678dc 100644 --- a/crunchy-cli-core/src/utils/ffmpeg.rs +++ b/crunchy-cli-core/src/utils/ffmpeg.rs @@ -229,7 +229,7 @@ impl FFmpegPreset { quality = Some(q) } else { return Err(format!( - "'{}' is not a valid ffmpeg preset (unknown token '{}'", + "'{}' is not a valid ffmpeg preset (unknown token '{}')", s, token )); } @@ -286,12 +286,10 @@ impl FFmpegPreset { output.extend(["-c:v", "h264_nvenc", "-c:a", "copy"]) } FFmpegHwAccel::Apple => { - // Apple's Video Toolbox encoders ignore `-crf`, - // use `-q:v` instead. It's on a scale of 1-100, - // 100 being lossless. Just did some math - // ((-a/51+1)*99+1 where `a` is the old crf value) - // so these settings very likely need some more - // tweeking. + // Apple's Video Toolbox encoders ignore `-crf`, use `-q:v` + // instead. It's on a scale of 1-100, 100 being lossless. Just + // did some math ((-a/51+1)*99+1 where `a` is the old crf value) + // so these settings very likely need some more tweaking match quality { FFmpegQuality::Lossless => output.extend(["-q:v", "65"]), FFmpegQuality::Normal => (), From 9487dd3dbffd4646713ce4e0ec1d6210fc1a1f14 Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 8 Dec 2023 22:27:12 +0100 Subject: [PATCH 128/272] Show ffmpeg progress (#270) --- Cargo.lock | 1 + crunchy-cli-core/Cargo.toml | 5 +- crunchy-cli-core/src/utils/download.rs | 142 +++++++++++++++++++------ crunchy-cli-core/src/utils/os.rs | 60 +++++++++++ 4 files changed, 176 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 897731f..fa5723f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -397,6 +397,7 @@ dependencies = [ "indicatif", "lazy_static", "log", + "nix", "num_cpus", "regex", "reqwest", diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 5771888..4f0912f 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -34,8 +34,11 @@ serde_plain = "1.0" shlex = "1.2" sys-locale = "0.3" tempfile = "3.8" -tokio = { version = "1.34", features = ["macros", "rt-multi-thread", "time"] } +tokio = { version = "1.34", features = ["io-util", "macros", "net", "rt-multi-thread", "time"] } rustls-native-certs = { version = "0.6", optional = true } +[target.'cfg(not(target_os = "windows"))'.dependencies] +nix = { version = "0.27", features = ["fs"] } + [build-dependencies] chrono = "0.4" diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index de1aed0..c154103 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -1,16 +1,14 @@ use crate::utils::context::Context; use crate::utils::ffmpeg::FFmpegPreset; -use crate::utils::log::progress; -use crate::utils::os::{is_special_file, temp_directory, tempfile}; +use crate::utils::os::{is_special_file, temp_directory, temp_named_pipe, tempfile}; use anyhow::{bail, Result}; use chrono::NaiveTime; use crunchyroll_rs::media::{Subtitle, VariantData, VariantSegment}; use crunchyroll_rs::Locale; -use indicatif::{ProgressBar, ProgressFinish, ProgressStyle}; +use indicatif::{ProgressBar, ProgressDrawTarget, ProgressFinish, ProgressStyle}; use log::{debug, warn, LevelFilter}; use regex::Regex; -use std::borrow::Borrow; -use std::borrow::BorrowMut; +use std::borrow::{Borrow, BorrowMut}; use std::cmp::Ordering; use std::collections::BTreeMap; use std::env; @@ -21,6 +19,7 @@ use std::str::FromStr; use std::sync::Arc; use std::time::Duration; use tempfile::TempPath; +use tokio::io::{AsyncBufReadExt, AsyncReadExt, BufReader}; use tokio::sync::mpsc::unbounded_channel; use tokio::sync::Mutex; use tokio::task::JoinSet; @@ -177,15 +176,19 @@ impl Downloader { let mut videos = vec![]; let mut audios = vec![]; let mut subtitles = vec![]; + let mut max_frames = 0f64; + let fmt_space = self + .formats + .iter() + .flat_map(|f| { + f.audios + .iter() + .map(|(_, locale)| format!("Downloading {} audio", locale).len()) + }) + .max() + .unwrap(); for (i, format) in self.formats.iter().enumerate() { - let fmt_space = format - .audios - .iter() - .map(|(_, locale)| format!("Downloading {} audio", locale).len()) - .max() - .unwrap(); - let video_path = self .download_video( ctx, @@ -232,7 +235,11 @@ impl Downloader { None }; - let len = get_video_length(&video_path)?; + let (len, fps) = get_video_stats(&video_path)?; + let frames = len.signed_duration_since(NaiveTime::MIN).num_seconds() as f64 * fps; + if frames > max_frames { + max_frames = frames; + } for (subtitle, not_cc) in format.subtitles.iter() { if let Some(pb) = &progress_spinner { let mut progress_message = pb.message(); @@ -337,8 +344,14 @@ impl Downloader { } let (input_presets, mut output_presets) = self.ffmpeg_preset.into_input_output_args(); + let fifo = temp_named_pipe()?; - let mut command_args = vec!["-y".to_string(), "-hide_banner".to_string()]; + let mut command_args = vec![ + "-y".to_string(), + "-hide_banner".to_string(), + "-vstats_file".to_string(), + fifo.name(), + ]; command_args.extend(input_presets); command_args.extend(input); command_args.extend(maps); @@ -433,8 +446,6 @@ impl Downloader { } } - let progress_handler = progress!("Generating output file"); - let ffmpeg = Command::new("ffmpeg") // pass ffmpeg stdout to real stdout only if output file is stdout .stdout(if dst.to_str().unwrap() == "-" { @@ -444,14 +455,26 @@ impl Downloader { }) .stderr(Stdio::piped()) .args(command_args) - .output()?; - if !ffmpeg.status.success() { - bail!("{}", String::from_utf8_lossy(ffmpeg.stderr.as_slice())) + .spawn()?; + let ffmpeg_progress = tokio::spawn(async move { + ffmpeg_progress( + max_frames as u64, + fifo, + format!("{:<1$}", "Generating output file", fmt_space + 1), + ) + .await + }); + + let result = ffmpeg.wait_with_output()?; + if !result.status.success() { + bail!("{}", String::from_utf8_lossy(result.stderr.as_slice())) + } + ffmpeg_progress.abort(); + match ffmpeg_progress.await { + Ok(r) => Ok(r?), + Err(e) if e.is_cancelled() => Ok(()), + Err(e) => Err(anyhow::Error::from(e)), } - - progress_handler.stop("Output file generated"); - - Ok(()) } async fn check_free_space( @@ -752,13 +775,10 @@ fn estimate_variant_file_size(variant_data: &VariantData, segments: &[VariantSeg (variant_data.bandwidth / 8) * segments.iter().map(|s| s.length.as_secs()).sum::() } -/// Get the length of a video. This is required because sometimes subtitles have an unnecessary entry -/// long after the actual video ends with artificially extends the video length on some video players. -/// To prevent this, the video length must be hard set. See -/// [crunchy-labs/crunchy-cli#32](https://github.com/crunchy-labs/crunchy-cli/issues/32) for more -/// information. -pub fn get_video_length(path: &Path) -> Result { +/// Get the length and fps of a video. +pub fn get_video_stats(path: &Path) -> Result<(NaiveTime, f64)> { let video_length = Regex::new(r"Duration:\s(?P Discord - - CI + + Build

From ab63dcd2e010cccd4b5a99c48d6576fa6c22d664 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 6 May 2024 20:29:22 +0200 Subject: [PATCH 248/272] Update dependencies and version --- Cargo.lock | 30 +++++++++++++++--------------- Cargo.toml | 2 +- crunchy-cli-core/Cargo.toml | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b9dce7b..44a47cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -92,9 +92,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" [[package]] name = "async-speed-limit" @@ -188,9 +188,9 @@ checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cc" -version = "1.0.96" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065a29261d53ba54260972629f9ca6bffa69bac13cd1fed61420f7fa68b9f8bd" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" [[package]] name = "cfg-if" @@ -343,7 +343,7 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "crunchy-cli" -version = "3.6.0" +version = "3.6.1" dependencies = [ "chrono", "clap", @@ -356,7 +356,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.6.0" +version = "3.6.1" dependencies = [ "anyhow", "async-speed-limit", @@ -712,9 +712,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -1511,9 +1511,9 @@ checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" [[package]] name = "rsubs-lib" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0df7559a05635a4132b737c736ee286af83f3969cb98d9028d17d333e6b41cc5" +checksum = "9dcca2a9560fca05de8f95bc3767e46673d4b4c1f2c7a11092e10efd95bbdf62" dependencies = [ "regex", "serde", @@ -1646,11 +1646,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "core-foundation", "core-foundation-sys", "libc", @@ -1659,9 +1659,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" dependencies = [ "core-foundation-sys", "libc", diff --git a/Cargo.toml b/Cargo.toml index fe7b301..26f71f3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.6.0" +version = "3.6.1" edition = "2021" license = "MIT" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 896b68f..8e1ba3a 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.0" +version = "3.6.1" edition = "2021" license = "MIT" @@ -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.2" +rsubs-lib = ">=0.2.1" rusty-chromaprint = "0.2" serde = "1.0" serde_json = "1.0" From 53a710a3732047a1e08d475f6f112b440b8bde8e Mon Sep 17 00:00:00 2001 From: Simon <47527944+Frooastside@users.noreply.github.com> Date: Tue, 7 May 2024 16:13:10 +0200 Subject: [PATCH 249/272] Fix audio syncing using wrong internal index (#407) --- crunchy-cli-core/src/utils/download.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index 565ed7d..8a8ad57 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -321,8 +321,6 @@ impl Downloader { if let Some(offsets) = offsets { let mut root_format_idx = 0; let mut root_format_length = 0; - let mut audio_count: usize = 0; - let mut subtitle_count: usize = 0; for (i, format) in self.formats.iter().enumerate() { let offset = offsets.get(&i).copied().unwrap_or_default(); let format_len = format @@ -340,15 +338,13 @@ impl Downloader { for _ in &format.audios { if let Some(offset) = &offsets.get(&i) { - audio_offsets.insert(audio_count, **offset); + audio_offsets.insert(i, **offset); } - audio_count += 1 } for _ in &format.subtitles { if let Some(offset) = &offsets.get(&i) { - subtitle_offsets.insert(subtitle_count, **offset); + subtitle_offsets.insert(i, **offset); } - subtitle_count += 1 } } From 48bb7a5ef669d3d89ccecfbf02929adeea99a6bd Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 14 May 2024 16:11:55 +0200 Subject: [PATCH 250/272] Fix crashes when converting subtitles (#408) --- Cargo.lock | 6 ++-- crunchy-cli-core/Cargo.toml | 3 +- crunchy-cli-core/src/utils/download.rs | 39 ++++++++++++++++---------- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 44a47cd..cd1f282 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -386,6 +386,7 @@ dependencies = [ "shlex", "sys-locale", "tempfile", + "time", "tokio", "tokio-util", "tower-service", @@ -1511,12 +1512,13 @@ checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" [[package]] name = "rsubs-lib" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dcca2a9560fca05de8f95bc3767e46673d4b4c1f2c7a11092e10efd95bbdf62" +checksum = "f43e1a7f184bc76407dbaa67bd2aeea8a15430d7e1e498070963336d03ebedee" dependencies = [ "regex", "serde", + "time", ] [[package]] diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 8e1ba3a..49f7a5e 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -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.2.1" +rsubs-lib = "0.3" rusty-chromaprint = "0.2" serde = "1.0" serde_json = "1.0" @@ -38,6 +38,7 @@ serde_plain = "1.0" shlex = "1.3" sys-locale = "0.3" tempfile = "3.10" +time = "0.3" tokio = { version = "1.37", features = ["io-util", "macros", "net", "rt-multi-thread", "time"] } tokio-util = "0.7" tower-service = "0.3" diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index 8a8ad57..43d165b 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -13,17 +13,19 @@ use indicatif::{ProgressBar, ProgressDrawTarget, ProgressFinish, ProgressStyle}; use log::{debug, warn, LevelFilter}; use regex::Regex; use reqwest::Client; -use rsubs_lib::{ssa, vtt}; +use rsubs_lib::{SSA, VTT}; use std::borrow::Borrow; use std::cmp::Ordering; use std::collections::{BTreeMap, HashMap}; use std::io::Write; +use std::ops::Add; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::sync::Arc; use std::time::Duration; use std::{env, fs}; use tempfile::TempPath; +use time::Time; use tokio::io::{AsyncBufReadExt, AsyncReadExt, BufReader}; use tokio::select; use tokio::sync::mpsc::unbounded_channel; @@ -929,36 +931,43 @@ impl Downloader { ) -> Result { let buf = subtitle.data().await?; let mut ass = match subtitle.format.as_str() { - "ass" => ssa::parse(String::from_utf8_lossy(&buf).to_string()), - "vtt" => vtt::parse(String::from_utf8_lossy(&buf).to_string()).to_ass(), + "ass" => SSA::parse(String::from_utf8_lossy(&buf))?, + "vtt" => VTT::parse(String::from_utf8_lossy(&buf))?.to_ssa(), _ => bail!("unknown subtitle format: {}", subtitle.format), }; // subtitles aren't always correct sorted and video players may have issues with that. to // prevent issues, the subtitles are sorted - ass.events - .sort_by(|a, b| a.line_start.total_ms().cmp(&b.line_start.total_ms())); + // (https://github.com/crunchy-labs/crunchy-cli/issues/208) + ass.events.sort_by(|a, b| a.start.cmp(&b.start)); // it might be the case that the start and/or end time are greater than the actual video // length. this might also result in issues with video players, thus the times are stripped - // to be maxim + // to be at most as long as `max_length` + // (https://github.com/crunchy-labs/crunchy-cli/issues/32) for i in (0..ass.events.len()).rev() { - if ass.events[i].line_end.total_ms() > max_length.num_milliseconds() as u32 { - if ass.events[i].line_start.total_ms() > max_length.num_milliseconds() as u32 { - ass.events[i] - .line_start - .set_ms(max_length.num_milliseconds() as u32); + let max_len = Time::from_hms(0, 0, 0) + .unwrap() + .add(Duration::from_millis(max_length.num_milliseconds() as u64)); + + if ass.events[i].start > max_len { + if ass.events[i].end > max_len { + ass.events[i].start = max_len } - ass.events[i] - .line_end - .set_ms(max_length.num_milliseconds() as u32); + ass.events[i].end = max_len } else { break; } } + // without this additional info, subtitle look very messy in some video player + // (https://github.com/crunchy-labs/crunchy-cli/issues/66) + ass.info + .additional_fields + .insert("ScaledBorderAndShadows".to_string(), "yes".to_string()); + let tempfile = tempfile(".ass")?; let path = tempfile.into_temp_path(); - ass.to_file(path.to_string_lossy().to_string().as_str())?; + fs::write(&path, ass.to_string())?; Ok(path) } From 817963af4fbf0eef1fde26a02f0771e343ce35d9 Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 14 May 2024 21:22:23 +0200 Subject: [PATCH 251/272] Fix video containing hardsub if not requested (#415) --- crunchy-cli-core/src/download/command.rs | 20 ++++++++++++++------ crunchy-cli-core/src/utils/video.rs | 24 ++++-------------------- 2 files changed, 18 insertions(+), 26 deletions(-) diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index bb0c1fd..a9c3acf 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -384,12 +384,20 @@ async fn get_format( let subtitle = if contains_hardsub { None } else if let Some(subtitle_locale) = &download.subtitle { - stream - .subtitles - .get(subtitle_locale) - .cloned() - // use closed captions as fallback if no actual subtitles are found - .or_else(|| stream.captions.get(subtitle_locale).cloned()) + if download.audio == Locale::ja_JP { + stream + .subtitles + .get(subtitle_locale) + // use closed captions as fallback if no actual subtitles are found + .or_else(|| stream.captions.get(subtitle_locale)) + .cloned() + } else { + stream + .captions + .get(subtitle_locale) + .or_else(|| stream.subtitles.get(subtitle_locale)) + .cloned() + } } else { None }; diff --git a/crunchy-cli-core/src/utils/video.rs b/crunchy-cli-core/src/utils/video.rs index 07f6e76..8b25791 100644 --- a/crunchy-cli-core/src/utils/video.rs +++ b/crunchy-cli-core/src/utils/video.rs @@ -5,28 +5,12 @@ use crunchyroll_rs::Locale; pub async fn stream_data_from_stream( stream: &Stream, resolution: &Resolution, - subtitle: Option, + hardsub_subtitle: Option, ) -> Result> { - // sometimes Crunchyroll marks episodes without real subtitles that they have subtitles and - // reports that only hardsub episode are existing. the following lines are trying to prevent - // potential errors which might get caused by this incorrect reporting - // (https://github.com/crunchy-labs/crunchy-cli/issues/231) - let mut hardsub_locales: Vec = stream.hard_subs.keys().cloned().collect(); - let (hardsub_locale, mut contains_hardsub) = if !hardsub_locales - .contains(&Locale::Custom("".to_string())) - && !hardsub_locales.contains(&Locale::Custom(":".to_string())) - { - // if only one hardsub locale exists, assume that this stream doesn't really contains hardsubs - if hardsub_locales.len() == 1 { - (Some(hardsub_locales.remove(0)), false) - } else { - // fallback to `None`. this should trigger an error message in `stream.dash_streaming_data` - // that the requested stream is not available - (None, false) - } + let (hardsub_locale, mut contains_hardsub) = if hardsub_subtitle.is_some() { + (hardsub_subtitle, true) } else { - let hardsubs_requested = subtitle.is_some(); - (subtitle, hardsubs_requested) + (None, false) }; let (mut videos, mut audios) = match stream.stream_data(hardsub_locale).await { From 590242712b00c90c6c4cd49744764a1b04b64789 Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 14 May 2024 21:36:12 +0200 Subject: [PATCH 252/272] Add warning message the `--skip-existing-method` has no effect without `--skip-existing` (#418) --- crunchy-cli-core/src/archive/command.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 38bddc1..44a30de 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -234,6 +234,10 @@ 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()); From a98e31f959892fed57a0510356a0c6a47a5c8672 Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 14 May 2024 22:36:59 +0200 Subject: [PATCH 253/272] Only include one CC subtitle --- crunchy-cli-core/src/archive/command.rs | 31 +++++++++++-------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 44a30de..113447f 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -501,24 +501,21 @@ async fn get_format( .subtitle .iter() .flat_map(|s| { - 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)); - + 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)) + } + } subtitles - .into_iter() - .chain(cc.into_iter()) - .collect::>() }) .collect(); From 5279a9b75910992ad1731557ad65ce4302bb9208 Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 14 May 2024 23:42:37 +0200 Subject: [PATCH 254/272] Update dependencies and version --- Cargo.lock | 57 +++++++++++++++++++------------------ Cargo.toml | 2 +- crunchy-cli-core/Cargo.toml | 2 +- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cd1f282..198afc9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -343,7 +343,7 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "crunchy-cli" -version = "3.6.1" +version = "3.6.2" dependencies = [ "chrono", "clap", @@ -356,7 +356,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.6.1" +version = "3.6.2" dependencies = [ "anyhow", "async-speed-limit", @@ -476,12 +476,13 @@ dependencies = [ [[package]] name = "dash-mpd" -version = "0.16.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b4bdd5f1c0c7493d780c645f0bff5b9361e6408210fa88910adb181efca64c" +checksum = "876a00c22923799ac46365eb528c10134f979bf58ced5e3113de5b98d9835290" dependencies = [ "base64 0.22.1", "base64-serde", + "bytes", "chrono", "fs-err", "iso8601", @@ -581,9 +582,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1156,9 +1157,9 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ "num-traits", ] @@ -1345,9 +1346,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -1535,9 +1536,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustfft" @@ -1606,9 +1607,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.5.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beb461507cee2c2ff151784c52762cf4d9ff6a61f3e80968600ed24fa837fa54" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" @@ -1633,9 +1634,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "schannel" @@ -1671,18 +1672,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.200" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" +checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.200" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" +checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" dependencies = [ "proc-macro2", "quote", @@ -1691,9 +1692,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", @@ -1841,9 +1842,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.60" +version = "2.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" dependencies = [ "proc-macro2", "quote", @@ -1900,18 +1901,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" +checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" +checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 26f71f3..1a1c76f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.6.1" +version = "3.6.2" edition = "2021" license = "MIT" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 49f7a5e..f3388f7 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.1" +version = "3.6.2" edition = "2021" license = "MIT" From 9819b622594e3cb2164aedcef71827618b421c41 Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 17 May 2024 23:45:41 +0200 Subject: [PATCH 255/272] Fix typo in additional subtitle field (#421) --- crunchy-cli-core/src/utils/download.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index 43d165b..d54b0bc 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -962,7 +962,7 @@ impl Downloader { // (https://github.com/crunchy-labs/crunchy-cli/issues/66) ass.info .additional_fields - .insert("ScaledBorderAndShadows".to_string(), "yes".to_string()); + .insert("ScaledBorderAndShadow".to_string(), "yes".to_string()); let tempfile = tempfile(".ass")?; let path = tempfile.into_temp_path(); From 301dac478f177b70723672effa3f2651ff8419d1 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 20 May 2024 15:57:28 +0200 Subject: [PATCH 256/272] Update dependencies and version --- Cargo.lock | 99 ++++++++++++++++++------------------- Cargo.toml | 5 +- crunchy-cli-core/Cargo.toml | 2 +- 3 files changed, 53 insertions(+), 53 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 198afc9..140125d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -92,9 +92,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.83" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "async-speed-limit" @@ -119,6 +119,12 @@ 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" @@ -188,9 +194,9 @@ checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cc" -version = "1.0.97" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" [[package]] name = "cfg-if" @@ -238,7 +244,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim 0.11.1", + "strsim", ] [[package]] @@ -343,7 +349,7 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "crunchy-cli" -version = "3.6.2" +version = "3.6.3" dependencies = [ "chrono", "clap", @@ -356,7 +362,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.6.2" +version = "3.6.3" dependencies = [ "anyhow", "async-speed-limit", @@ -441,9 +447,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" dependencies = [ "darling_core", "darling_macro", @@ -451,23 +457,23 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "strsim 0.10.0", + "strsim", "syn", ] [[package]] name = "darling_macro" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ "darling_core", "quote", @@ -555,9 +561,9 @@ dependencies = [ [[package]] name = "either" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "encode_unicode" @@ -733,15 +739,15 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "h2" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" dependencies = [ + "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "futures-util", "http", "indexmap 2.2.6", "slab", @@ -979,9 +985,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ "cfg-if", ] @@ -1043,9 +1049,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.154" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libredox" @@ -1059,9 +1065,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "log" @@ -1099,9 +1105,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" dependencies = [ "adler", ] @@ -1120,7 +1126,7 @@ dependencies = [ [[package]] name = "native-tls" version = "0.2.11" -source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=fdba246#fdba246a79986607cbdf573733445498bb6da2a9" +source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=b7969a8#b7969a88210096e0570e29d42fb13533baf62aa6" dependencies = [ "libc", "log", @@ -1346,9 +1352,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" dependencies = [ "unicode-ident", ] @@ -1514,8 +1520,7 @@ checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" [[package]] name = "rsubs-lib" version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43e1a7f184bc76407dbaa67bd2aeea8a15430d7e1e498070963336d03ebedee" +source = "git+https://github.com/crunchy-labs/rsubs-lib.git?rev=1c51f60#1c51f60b8c48f1a8f7b261372b237d89bdc17dd4" dependencies = [ "regex", "serde", @@ -1613,9 +1618,9 @@ checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" -version = "0.102.3" +version = "0.102.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3bce581c0dd41bce533ce695a1437fa16a7ab5ac3ccfa99fe1a620a7885eabf" +checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" dependencies = [ "ring", "rustls-pki-types", @@ -1672,18 +1677,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.201" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.201" +version = "1.0.202" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", @@ -1822,12 +1827,6 @@ 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 +1841,9 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" -version = "2.0.63" +version = "2.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" +checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" dependencies = [ "proc-macro2", "quote", @@ -1901,18 +1900,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.60" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.60" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 1a1c76f..4021ebc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.6.2" +version = "3.6.3" edition = "2021" license = "MIT" @@ -34,7 +34,8 @@ 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 = "fdba246" } +native-tls = { git = "https://github.com/crunchy-labs/rust-not-so-native-tls.git", rev = "b7969a8" } +rsubs-lib = { git = "https://github.com/crunchy-labs/rsubs-lib.git", rev = "1c51f60" } [profile.release] strip = true diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index f3388f7..4b4416b 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.2" +version = "3.6.3" edition = "2021" license = "MIT" From f7ce888329825470a42e13cf6c0dd35826783d6c Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 21 May 2024 21:33:08 +0200 Subject: [PATCH 257/272] Bypass stream limits --- crunchy-cli-core/src/archive/command.rs | 4 ++- crunchy-cli-core/src/download/command.rs | 2 ++ crunchy-cli-core/src/utils/format.rs | 32 +++++++++++++++--------- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 113447f..d34c4b7 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -520,7 +520,9 @@ async fn get_format( .collect(); format_pairs.push((single_format, video.clone(), audio, subtitles.clone())); - single_format_to_format_pairs.push((single_format.clone(), video, subtitles)) + single_format_to_format_pairs.push((single_format.clone(), video, subtitles)); + + stream.invalidate().await? } let mut download_formats = vec![]; diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index a9c3acf..fcf069b 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -434,5 +434,7 @@ async fn get_format( subs.push(download.subtitle.clone().unwrap()) } + stream.invalidate().await?; + Ok((download_format, format)) } diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index 0a71838..325c731 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -2,7 +2,7 @@ use crate::utils::filter::real_dedup_vec; use crate::utils::locale::LanguageTagging; use crate::utils::log::tab_info; use crate::utils::os::{is_special_file, sanitize}; -use anyhow::{bail, Result}; +use anyhow::Result; use chrono::{Datelike, Duration}; use crunchyroll_rs::media::{Resolution, SkipEvents, Stream, StreamData, Subtitle}; use crunchyroll_rs::{Concert, Episode, Locale, MediaCollection, Movie, MusicVideo}; @@ -166,19 +166,27 @@ impl SingleFormat { } pub async fn stream(&self) -> Result { - let stream = match &self.source { - MediaCollection::Episode(e) => e.stream_maybe_without_drm().await?, - MediaCollection::Movie(m) => m.stream_maybe_without_drm().await?, - MediaCollection::MusicVideo(mv) => mv.stream_maybe_without_drm().await?, - MediaCollection::Concert(c) => c.stream_maybe_without_drm().await?, - _ => unreachable!(), - }; + let mut i = 0; + loop { + let stream = match &self.source { + MediaCollection::Episode(e) => e.stream_maybe_without_drm().await, + MediaCollection::Movie(m) => m.stream_maybe_without_drm().await, + MediaCollection::MusicVideo(mv) => mv.stream_maybe_without_drm().await, + MediaCollection::Concert(c) => c.stream_maybe_without_drm().await, + _ => unreachable!(), + }; - if stream.session.uses_stream_limits { - bail!("Found a stream which probably uses DRM. DRM downloads aren't supported") + // sometimes the request to get streams fails with an 403 and the message "JWT error", + // even if the jwt (i guess the auth bearer token is meant by that) is perfectly valid. + // it's retried the request 3 times if this specific error occurs + if let Err(crunchyroll_rs::error::Error::Request { message, .. }) = &stream { + if message == "JWT error" && i < 3 { + i += 1; + continue; + } + }; + return Ok(stream?); } - - Ok(stream) } pub async fn skip_events(&self) -> Result> { From cbe57e2b6e6262c5a94312a9646faea3a9f23ccb Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 21 May 2024 21:34:05 +0200 Subject: [PATCH 258/272] Update dependencies and version --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- crunchy-cli-core/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 140125d..5ea720f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -349,7 +349,7 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "crunchy-cli" -version = "3.6.3" +version = "3.6.4" dependencies = [ "chrono", "clap", @@ -362,7 +362,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.6.3" +version = "3.6.4" dependencies = [ "anyhow", "async-speed-limit", @@ -482,9 +482,9 @@ dependencies = [ [[package]] name = "dash-mpd" -version = "0.16.2" +version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a00c22923799ac46365eb528c10134f979bf58ced5e3113de5b98d9835290" +checksum = "4618a5e165bf47b084963611bcf1d568c681f52d8a237e8862a0cd8c546ba255" dependencies = [ "base64 0.22.1", "base64-serde", @@ -1259,9 +1259,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.2.3+3.2.1" +version = "300.3.0+3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cff92b6f71555b61bb9315f7c64da3ca43d87531622120fea0195fc761b4843" +checksum = "eba8804a1c5765b18c4b3f907e6897ebabeedebc9830e1a0046c4a4cf44663e1" dependencies = [ "cc", ] diff --git a/Cargo.toml b/Cargo.toml index 4021ebc..98d2269 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.6.3" +version = "3.6.4" edition = "2021" license = "MIT" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 4b4416b..8370fdc 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.3" +version = "3.6.4" edition = "2021" license = "MIT" From f8bd0929872f4c78a6d2b54eee7dacb4c94cfb9d Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 21 May 2024 21:51:18 +0200 Subject: [PATCH 259/272] Add custom error message if too many streams are active --- crunchy-cli-core/src/utils/format.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index 325c731..436be78 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -2,7 +2,7 @@ use crate::utils::filter::real_dedup_vec; use crate::utils::locale::LanguageTagging; use crate::utils::log::tab_info; use crate::utils::os::{is_special_file, sanitize}; -use anyhow::Result; +use anyhow::{bail, Result}; use chrono::{Datelike, Duration}; use crunchyroll_rs::media::{Resolution, SkipEvents, Stream, StreamData, Subtitle}; use crunchyroll_rs::{Concert, Episode, Locale, MediaCollection, Movie, MusicVideo}; @@ -176,13 +176,15 @@ impl SingleFormat { _ => unreachable!(), }; - // sometimes the request to get streams fails with an 403 and the message "JWT error", - // even if the jwt (i guess the auth bearer token is meant by that) is perfectly valid. - // it's retried the request 3 times if this specific error occurs if let Err(crunchyroll_rs::error::Error::Request { message, .. }) = &stream { + // sometimes the request to get streams fails with an 403 and the message + // "JWT error", even if the jwt (i guess the auth bearer token is meant by that) is + // perfectly valid. it's retried the request 3 times if this specific error occurs if message == "JWT error" && i < 3 { i += 1; continue; + } else if message.starts_with("TOO_MANY_ACTIVE_STREAMS") { + bail!("Too many active/parallel streams. Please close at least one stream you're watching and try again") } }; return Ok(stream?); From 5593046aae4c399c1f0568c14ff35f3d75d96edc Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 22 May 2024 16:52:43 +0200 Subject: [PATCH 260/272] Update dependencies and version --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- crunchy-cli-core/Cargo.toml | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ea720f..b24bc20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -349,7 +349,7 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "crunchy-cli" -version = "3.6.4" +version = "3.6.5" dependencies = [ "chrono", "clap", @@ -362,7 +362,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.6.4" +version = "3.6.5" dependencies = [ "anyhow", "async-speed-limit", @@ -400,9 +400,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58580acc9c0abf96a231ec8b1a4597ea55d9426ea17f684ce3582e2b26437bbb" +checksum = "7a6754d10e1890089eb733b71aee6f4cbc18374040aedb04c4ca76020bcd9818" dependencies = [ "async-trait", "chrono", @@ -426,9 +426,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs-internal" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce3c844dec8a3390f8c9853b5cf1d65c3d38fd0657b8b5d0e008db8945dea326" +checksum = "ca15fa827cca647852b091006f2b592f8727e1082f812b475b3f9ebe3f59d5bf" dependencies = [ "darling", "quote", diff --git a/Cargo.toml b/Cargo.toml index 98d2269..ccf80ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.6.4" +version = "3.6.5" edition = "2021" license = "MIT" diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 8370fdc..98ff9d7 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.4" +version = "3.6.5" 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.1", features = ["experimental-stabilizations", "tower"] } +crunchyroll-rs = { version = "0.11.2", features = ["experimental-stabilizations", "tower"] } ctrlc = "3.4" dialoguer = { version = "0.11", default-features = false } dirs = "5.0" From 7d2ae719c8fee83f2ba5041f214b87eb53d3c33c Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 22 May 2024 16:54:58 +0200 Subject: [PATCH 261/272] Remove internal jwt error retry --- crunchy-cli-core/src/utils/format.rs | 35 +++++++++++----------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index 436be78..c5e8f3d 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -166,29 +166,20 @@ impl SingleFormat { } pub async fn stream(&self) -> Result { - let mut i = 0; - loop { - let stream = match &self.source { - MediaCollection::Episode(e) => e.stream_maybe_without_drm().await, - MediaCollection::Movie(m) => m.stream_maybe_without_drm().await, - MediaCollection::MusicVideo(mv) => mv.stream_maybe_without_drm().await, - MediaCollection::Concert(c) => c.stream_maybe_without_drm().await, - _ => unreachable!(), - }; + let stream = match &self.source { + MediaCollection::Episode(e) => e.stream_maybe_without_drm().await, + MediaCollection::Movie(m) => m.stream_maybe_without_drm().await, + MediaCollection::MusicVideo(mv) => mv.stream_maybe_without_drm().await, + MediaCollection::Concert(c) => c.stream_maybe_without_drm().await, + _ => unreachable!(), + }; - if let Err(crunchyroll_rs::error::Error::Request { message, .. }) = &stream { - // sometimes the request to get streams fails with an 403 and the message - // "JWT error", even if the jwt (i guess the auth bearer token is meant by that) is - // perfectly valid. it's retried the request 3 times if this specific error occurs - if message == "JWT error" && i < 3 { - i += 1; - continue; - } else if message.starts_with("TOO_MANY_ACTIVE_STREAMS") { - bail!("Too many active/parallel streams. Please close at least one stream you're watching and try again") - } - }; - return Ok(stream?); - } + if let Err(crunchyroll_rs::error::Error::Request { message, .. }) = &stream { + if message.starts_with("TOO_MANY_ACTIVE_STREAMS") { + bail!("Too many active/parallel streams. Please close at least one stream you're watching and try again") + } + }; + Ok(stream?) } pub async fn skip_events(&self) -> Result> { From 74e5e05b0f8b4cb83cd5708747fe81a0183b56f0 Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 22 May 2024 23:59:12 +0200 Subject: [PATCH 262/272] Invalidate stream when using search command (#428) --- crunchy-cli-core/src/search/format.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/search/format.rs b/crunchy-cli-core/src/search/format.rs index 7ea84d8..ee855b2 100644 --- a/crunchy-cli-core/src/search/format.rs +++ b/crunchy-cli-core/src/search/format.rs @@ -464,7 +464,9 @@ impl Format { if !stream_empty { for (_, episodes) in tree.iter_mut() { for (episode, streams) in episodes { - streams.push(episode.stream_maybe_without_drm().await?) + let stream = episode.stream_maybe_without_drm().await?; + stream.clone().invalidate().await?; + streams.push(stream) } } } else { From a1c7b2069d79ecc634e3ba216fb86e63135d9501 Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 23 May 2024 00:01:42 +0200 Subject: [PATCH 263/272] Update dependencies and version --- Cargo.lock | 17 +++++++++-------- Cargo.toml | 3 +-- crunchy-cli-core/Cargo.toml | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b24bc20..8400022 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -349,7 +349,7 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "crunchy-cli" -version = "3.6.5" +version = "3.6.6" dependencies = [ "chrono", "clap", @@ -362,7 +362,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.6.5" +version = "3.6.6" dependencies = [ "anyhow", "async-speed-limit", @@ -400,9 +400,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6754d10e1890089eb733b71aee6f4cbc18374040aedb04c4ca76020bcd9818" +checksum = "1d33b8d77c80dea79e66993cb67963b2171dcf0b8fbc87591c58f2dadfea8da2" dependencies = [ "async-trait", "chrono", @@ -426,9 +426,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs-internal" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca15fa827cca647852b091006f2b592f8727e1082f812b475b3f9ebe3f59d5bf" +checksum = "fa51945265f25c45f7d53bd70e5263dd023c0be45e38eaba886a971cb645d797" dependencies = [ "darling", "quote", @@ -1519,8 +1519,9 @@ checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" [[package]] name = "rsubs-lib" -version = "0.3.0" -source = "git+https://github.com/crunchy-labs/rsubs-lib.git?rev=1c51f60#1c51f60b8c48f1a8f7b261372b237d89bdc17dd4" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d01f7609f0b1bc4fe24b352e8d1792c7d71cc43aea797e14b87974cd009ab402" dependencies = [ "regex", "serde", diff --git a/Cargo.toml b/Cargo.toml index ccf80ec..f263e59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.6.5" +version = "3.6.6" edition = "2021" license = "MIT" @@ -35,7 +35,6 @@ members = ["crunchy-cli-core"] # 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 = "b7969a8" } -rsubs-lib = { git = "https://github.com/crunchy-labs/rsubs-lib.git", rev = "1c51f60" } [profile.release] strip = true diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 98ff9d7..56964ec 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.5" +version = "3.6.6" 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.2", features = ["experimental-stabilizations", "tower"] } +crunchyroll-rs = { version = "0.11.3", 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" +rsubs-lib = "~0.3.1" rusty-chromaprint = "0.2" serde = "1.0" serde_json = "1.0" From 67c267be2005d18d39c814087db905a801d41fc5 Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 24 May 2024 22:05:04 +0200 Subject: [PATCH 264/272] Remove unused variable --- crunchy-cli-core/src/utils/format.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index c5e8f3d..f0a002c 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -4,7 +4,7 @@ use crate::utils::log::tab_info; use crate::utils::os::{is_special_file, sanitize}; use anyhow::{bail, Result}; use chrono::{Datelike, Duration}; -use crunchyroll_rs::media::{Resolution, SkipEvents, Stream, StreamData, Subtitle}; +use crunchyroll_rs::media::{SkipEvents, Stream, StreamData, Subtitle}; use crunchyroll_rs::{Concert, Episode, Locale, MediaCollection, Movie, MusicVideo}; use log::{debug, info}; use std::cmp::Ordering; @@ -354,8 +354,6 @@ pub struct Format { pub locales: Vec<(Locale, Vec)>, - // deprecated - pub resolution: Resolution, pub width: u64, pub height: u64, pub fps: f64, @@ -401,7 +399,6 @@ impl Format { title: first_format.title, description: first_format.description, locales, - resolution: first_stream.resolution().unwrap(), width: first_stream.resolution().unwrap().width, height: first_stream.resolution().unwrap().height, fps: first_stream.fps().unwrap(), @@ -449,11 +446,11 @@ impl Format { ) .replace( "{width}", - &sanitize(self.resolution.width.to_string(), true, universal), + &sanitize(self.width.to_string(), true, universal), ) .replace( "{height}", - &sanitize(self.resolution.height.to_string(), true, universal), + &sanitize(self.height.to_string(), true, universal), ) .replace("{series_id}", &sanitize(&self.series_id, true, universal)) .replace( @@ -589,7 +586,7 @@ impl Format { .collect::>() .join(", ") ); - tab_info!("Resolution: {}", self.resolution); + tab_info!("Resolution: {}x{}", self.height, self.width); tab_info!("FPS: {:.2}", self.fps) } From fb8e53564442653bcaa972bf8143066b42cb49d3 Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 24 May 2024 22:09:23 +0200 Subject: [PATCH 265/272] Fix subtitle title not being human-readable --- crunchy-cli-core/src/utils/download.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index d54b0bc..accefce 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -654,7 +654,7 @@ impl Downloader { metadata.extend([ format!("-metadata:s:s:{}", i), format!("title={}", { - let mut title = meta.locale.to_string(); + let mut title = meta.locale.to_human_readable(); if meta.cc { title += " (CC)" } From e7ac6d8874418c3311d433855f5991ea6f0be187 Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 24 May 2024 22:17:25 +0200 Subject: [PATCH 266/272] Deprecate search stream.is_drm option --- crunchy-cli-core/src/search/command.rs | 4 ++++ crunchy-cli-core/src/search/format.rs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/crunchy-cli-core/src/search/command.rs b/crunchy-cli-core/src/search/command.rs index c29ce34..8032bed 100644 --- a/crunchy-cli-core/src/search/command.rs +++ b/crunchy-cli-core/src/search/command.rs @@ -111,6 +111,10 @@ impl Execute for Search { warn!("Using `search` anonymously or with a non-premium account may return incomplete results") } + if self.output.contains("{{stream.is_drm}}") { + warn!("The `{{{{stream.is_drm}}}}` option is deprecated as it isn't reliable anymore and will be removed soon") + } + let input = if crunchyroll_rs::parse::parse_url(&self.input).is_some() { match parse_url(&ctx.crunchy, self.input.clone(), true).await { Ok(ok) => vec![ok], diff --git a/crunchy-cli-core/src/search/format.rs b/crunchy-cli-core/src/search/format.rs index ee855b2..10f4624 100644 --- a/crunchy-cli-core/src/search/format.rs +++ b/crunchy-cli-core/src/search/format.rs @@ -173,7 +173,7 @@ impl From<&Stream> for FormatStream { Self { locale: value.audio_locale.clone(), dash_url: value.url.clone(), - is_drm: value.session.uses_stream_limits, + is_drm: false, } } } From 287df843828e106d4fef2661c796ffaa69742caf Mon Sep 17 00:00:00 2001 From: bytedream Date: Fri, 14 Jun 2024 00:17:08 +0200 Subject: [PATCH 267/272] Rework episode filtering --- Cargo.lock | 16 +- crunchy-cli-core/Cargo.toml | 2 +- crunchy-cli-core/src/archive/command.rs | 47 ++- crunchy-cli-core/src/archive/filter.rs | 466 ----------------------- crunchy-cli-core/src/archive/mod.rs | 1 - crunchy-cli-core/src/download/command.rs | 53 ++- crunchy-cli-core/src/download/filter.rs | 307 --------------- crunchy-cli-core/src/download/mod.rs | 1 - crunchy-cli-core/src/search/format.rs | 28 +- crunchy-cli-core/src/utils/filter.rs | 425 +++++++++++++++++++-- crunchy-cli-core/src/utils/format.rs | 2 + 11 files changed, 515 insertions(+), 833 deletions(-) delete mode 100644 crunchy-cli-core/src/archive/filter.rs delete mode 100644 crunchy-cli-core/src/download/filter.rs diff --git a/Cargo.lock b/Cargo.lock index 8400022..7fdb3d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -400,9 +400,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d33b8d77c80dea79e66993cb67963b2171dcf0b8fbc87591c58f2dadfea8da2" +checksum = "d6e38c223aecf65c9c9bec50764beea5dc70b6c97cd7f767bf6860f2fc8e0a07" dependencies = [ "async-trait", "chrono", @@ -426,9 +426,9 @@ dependencies = [ [[package]] name = "crunchyroll-rs-internal" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa51945265f25c45f7d53bd70e5263dd023c0be45e38eaba886a971cb645d797" +checksum = "144a38040a21aaa456741a9f6749354527bb68ad3bb14210e0bbc40fbd95186c" dependencies = [ "darling", "quote", @@ -1967,9 +1967,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.37.0" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" dependencies = [ "backtrace", "bytes", @@ -1984,9 +1984,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 56964ec..5c7b901 100644 --- a/crunchy-cli-core/Cargo.toml +++ b/crunchy-cli-core/Cargo.toml @@ -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.3", features = ["experimental-stabilizations", "tower"] } +crunchyroll-rs = { version = "0.11.4", features = ["experimental-stabilizations", "tower"] } ctrlc = "3.4" dialoguer = { version = "0.11", default-features = false } dirs = "5.0" diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index d34c4b7..0d1b3a4 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -1,10 +1,9 @@ -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; +use crate::utils::filter::{Filter, FilterMediaScope}; use crate::utils::format::{Format, SingleFormat}; use crate::utils::locale::{all_locale_in_locales, resolve_locales, LanguageTagging}; use crate::utils::log::progress; @@ -284,9 +283,49 @@ 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 = ArchiveFilter::new( + let single_format_collection = Filter::new( url_filter, - self.clone(), + 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.yes, self.skip_specials, ctx.crunchy.premium().await, diff --git a/crunchy-cli-core/src/archive/filter.rs b/crunchy-cli-core/src/archive/filter.rs deleted file mode 100644 index b08fb6c..0000000 --- a/crunchy-cli-core/src/archive/filter.rs +++ /dev/null @@ -1,466 +0,0 @@ -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> { - if !self - .url_filter - .is_episode_valid(episode.sequence_number, episode.season_number) - { - return Ok(None); - } - - // skip the episode if it's a special - if self.skip_special - && (episode.sequence_number == 0.0 || episode.sequence_number.fract() != 0.0) - { - return Ok(None); - } - - let mut episodes = vec![]; - if !matches!(self.visited, Visited::Series) && !matches!(self.visited, Visited::Season) { - if self.archive.audio.contains(&episode.audio_locale) { - episodes.push((episode.clone(), episode.subtitle_locales.clone())) - } - episodes.extend( - episode - .version(self.archive.audio.clone()) - .await? - .into_iter() - .map(|e| (e.clone(), e.subtitle_locales.clone())), - ); - let audio_locales: Vec = episodes - .iter() - .map(|(e, _)| e.audio_locale.clone()) - .collect(); - let missing_audio = missing_locales(&audio_locales, &self.archive.audio); - if !missing_audio.is_empty() { - warn!( - "Episode {} is not available with {} audio", - episode.sequence_number, - missing_audio - .into_iter() - .map(|l| l.to_string()) - .collect::>() - .join(", ") - ) - } - - let mut subtitle_locales: Vec = - episodes.iter().flat_map(|(_, s)| s.clone()).collect(); - real_dedup_vec(&mut subtitle_locales); - let missing_subtitles = missing_locales(&subtitle_locales, &self.archive.subtitle); - if !missing_subtitles.is_empty() - && !self - .season_subtitles_missing - .contains(&episode.season_number) - { - warn!( - "Episode {} is not available with {} subtitles", - episode.sequence_number, - missing_subtitles - .into_iter() - .map(|l| l.to_string()) - .collect::>() - .join(", ") - ); - self.season_subtitles_missing.push(episode.season_number) - } - } else { - episodes.push((episode.clone(), episode.subtitle_locales.clone())) - } - - if self.seasons_with_premium.is_some() { - let episode_len_before = episodes.len(); - episodes.retain(|(e, _)| !e.is_premium_only); - if episode_len_before < episodes.len() - && !self - .seasons_with_premium - .as_ref() - .unwrap() - .contains(&episode.season_number) - { - warn!( - "Skipping premium episodes in season {}", - episode.season_number - ); - self.seasons_with_premium - .as_mut() - .unwrap() - .push(episode.season_number) - } - - if episodes.is_empty() { - return Ok(None); - } - } - - let mut relative_episode_number = None; - let mut relative_sequence_number = None; - // get the relative episode number. only done if the output string has the pattern to include - // the relative episode number as this requires some extra fetching - if Format::has_relative_fmt(&self.archive.output) { - let season_eps = match self.season_episodes.get(&episode.season_id) { - Some(eps) => eps, - None => { - self.season_episodes.insert( - episode.season_id.clone(), - episode.season().await?.episodes().await?, - ); - self.season_episodes.get(&episode.season_id).unwrap() - } - }; - let mut non_integer_sequence_number_count = 0; - for (i, ep) in season_eps.iter().enumerate() { - if ep.sequence_number.fract() != 0.0 || ep.sequence_number == 0.0 { - non_integer_sequence_number_count += 1; - } - if ep.id == episode.id { - relative_episode_number = Some(i + 1); - relative_sequence_number = Some( - (i + 1 - non_integer_sequence_number_count) as f32 - + fract(ep.sequence_number), - ); - break; - } - } - if relative_episode_number.is_none() || relative_sequence_number.is_none() { - warn!( - "Failed to get relative episode number for episode {} ({}) of {} season {}", - episode.sequence_number, - episode.title, - episode.series_title, - episode.season_number, - ) - } - } - - Ok(Some( - episodes - .into_iter() - .map(|(e, s)| { - SingleFormat::new_from_episode( - e, - s, - relative_episode_number.map(|n| n as u32), - relative_sequence_number, - ) - }) - .collect(), - )) - } - - async fn visit_movie_listing(&mut self, movie_listing: MovieListing) -> Result> { - Ok(movie_listing.movies().await?) - } - - async fn visit_movie(&mut self, movie: Movie) -> Result> { - Ok(Some(vec![SingleFormat::new_from_movie(movie, vec![])])) - } - - async fn visit_music_video(&mut self, music_video: MusicVideo) -> Result> { - Ok(Some(vec![SingleFormat::new_from_music_video(music_video)])) - } - - async fn visit_concert(&mut self, concert: Concert) -> Result> { - Ok(Some(vec![SingleFormat::new_from_concert(concert)])) - } - - async fn finish(self, input: Vec) -> Result { - let flatten_input: Self::T = input.into_iter().flatten().collect(); - - let mut single_format_collection = SingleFormatCollection::new(); - - let mut pre_sorted: BTreeMap = BTreeMap::new(); - for data in flatten_input { - pre_sorted - .entry(data.identifier.clone()) - .or_insert(vec![]) - .push(data) - } - - let mut sorted: Vec<(String, Self::T)> = pre_sorted.into_iter().collect(); - sorted.sort_by(|(_, a), (_, b)| { - self.season_sorting - .iter() - .position(|p| p == &a.first().unwrap().season_id) - .unwrap() - .cmp( - &self - .season_sorting - .iter() - .position(|p| p == &b.first().unwrap().season_id) - .unwrap(), - ) - }); - - for (_, mut data) in sorted { - data.sort_by(|a, b| { - self.archive - .audio - .iter() - .position(|p| p == &a.audio) - .unwrap_or(usize::MAX) - .cmp( - &self - .archive - .audio - .iter() - .position(|p| p == &b.audio) - .unwrap_or(usize::MAX), - ) - }); - single_format_collection.add_single_formats(data) - } - - Ok(single_format_collection) - } -} - -fn missing_locales<'a>(available: &[Locale], searched: &'a [Locale]) -> Vec<&'a Locale> { - searched.iter().filter(|p| !available.contains(p)).collect() -} diff --git a/crunchy-cli-core/src/archive/mod.rs b/crunchy-cli-core/src/archive/mod.rs index c3544a4..670d0c2 100644 --- a/crunchy-cli-core/src/archive/mod.rs +++ b/crunchy-cli-core/src/archive/mod.rs @@ -1,4 +1,3 @@ mod command; -mod filter; pub use command::Archive; diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index fcf069b..8e3794f 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -1,8 +1,7 @@ -use crate::download::filter::DownloadFilter; use crate::utils::context::Context; use crate::utils::download::{DownloadBuilder, DownloadFormat, DownloadFormatMetadata}; use crate::utils::ffmpeg::{FFmpegPreset, SOFTSUB_CONTAINERS}; -use crate::utils::filter::Filter; +use crate::utils::filter::{Filter, FilterMediaScope}; use crate::utils::format::{Format, SingleFormat}; use crate::utils::locale::{resolve_locales, LanguageTagging}; use crate::utils::log::progress; @@ -14,7 +13,7 @@ use anyhow::bail; use anyhow::Result; use crunchyroll_rs::media::Resolution; use crunchyroll_rs::Locale; -use log::{debug, warn}; +use log::{debug, error, warn}; use std::collections::HashMap; use std::path::Path; @@ -250,9 +249,53 @@ impl Execute for Download { for (i, (media_collection, url_filter)) in parsed_urls.into_iter().enumerate() { let progress_handler = progress!("Fetching series details"); - let single_format_collection = DownloadFilter::new( + let single_format_collection = Filter::new( url_filter, - self.clone(), + vec![self.audio.clone()], + self.subtitle.as_ref().map_or(vec![], |s| vec![s.clone()]), + |scope, locales| { + match scope { + FilterMediaScope::Series(series) => bail!("Series {} is not available with {} audio", series.title, locales[0]), + FilterMediaScope::Season(season) => { + error!("Season {} is not available with {} audio", season.season_number, locales[0]); + Ok(false) + } + FilterMediaScope::Episode(episodes) => { + if episodes.len() == 1 { + warn!("Episode {} of season {} is not available with {} audio", episodes[0].sequence_number, episodes[0].season_title, locales[0]) + } else if episodes.len() == 2 { + warn!("Season {} is only available with {} audio from episode {} to {}", episodes[0].season_number, locales[0], episodes[0].sequence_number, episodes[1].sequence_number) + } else { + unimplemented!() + } + Ok(false) + } + } + }, + |scope, locales| { + match scope { + FilterMediaScope::Series(series) => bail!("Series {} is not available with {} subtitles", series.title, locales[0]), + FilterMediaScope::Season(season) => { + warn!("Season {} is not available with {} subtitles", season.season_number, locales[0]); + Ok(false) + }, + FilterMediaScope::Episode(episodes) => { + if episodes.len() == 1 { + warn!("Episode {} of season {} is not available with {} subtitles", episodes[0].sequence_number, episodes[0].season_title, locales[0]) + } else if episodes.len() == 2 { + warn!("Season {} is only available with {} subtitles from episode {} to {}", episodes[0].season_number, locales[0], episodes[0].sequence_number, episodes[1].sequence_number) + } else { + unimplemented!() + } + Ok(false) + } + } + }, + |season| { + warn!("Skipping premium episodes in season {season}"); + Ok(()) + }, + Format::has_relative_fmt(&self.output), !self.yes, self.skip_specials, ctx.crunchy.premium().await, diff --git a/crunchy-cli-core/src/download/filter.rs b/crunchy-cli-core/src/download/filter.rs deleted file mode 100644 index 1c62920..0000000 --- a/crunchy-cli-core/src/download/filter.rs +++ /dev/null @@ -1,307 +0,0 @@ -use crate::download::Download; -use crate::utils::filter::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::{bail, Result}; -use crunchyroll_rs::{Concert, Episode, Movie, MovieListing, MusicVideo, Season, Series}; -use log::{error, info, warn}; -use std::collections::HashMap; -use std::ops::Not; - -pub(crate) struct DownloadFilter { - url_filter: UrlFilter, - download: Download, - interactive_input: bool, - skip_special: bool, - season_episodes: HashMap>, - season_subtitles_missing: Vec, - seasons_with_premium: Option>, - season_visited: bool, -} - -impl DownloadFilter { - pub(crate) fn new( - url_filter: UrlFilter, - download: Download, - interactive_input: bool, - skip_special: bool, - is_premium: bool, - ) -> Self { - Self { - url_filter, - download, - interactive_input, - skip_special, - season_episodes: HashMap::new(), - season_subtitles_missing: vec![], - seasons_with_premium: is_premium.not().then_some(vec![]), - season_visited: false, - } - } -} - -impl Filter for DownloadFilter { - type T = SingleFormat; - 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() && !series.audio_locales.contains(&self.download.audio) - { - error!( - "Series {} is not available with {} audio", - series.title, self.download.audio - ); - return Ok(vec![]); - } - - let mut seasons = vec![]; - for mut season in series.seasons().await? { - if !self.url_filter.is_season_valid(season.season_number) { - continue; - } - - if !season - .audio_locales - .iter() - .any(|l| l == &self.download.audio) - { - if season - .available_versions() - .await? - .iter() - .any(|l| l == &self.download.audio) - { - season = season - .version(vec![self.download.audio.clone()]) - .await? - .remove(0) - } else { - error!( - "Season {} - '{}' is not available with {} audio", - season.season_number, - season.title, - self.download.audio.clone(), - ); - continue; - } - } - - seasons.push(season) - } - - 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, season: Season) -> Result> { - self.season_visited = true; - - let mut episodes = season.episodes().await?; - - if Format::has_relative_fmt(&self.download.output) { - for episode in episodes.iter() { - self.season_episodes - .entry(episode.season_number) - .or_default() - .push(episode.clone()) - } - } - - episodes.retain(|e| { - self.url_filter - .is_episode_valid(e.sequence_number, season.season_number) - }); - - Ok(episodes) - } - - async fn visit_episode(&mut self, mut episode: Episode) -> Result> { - if !self - .url_filter - .is_episode_valid(episode.sequence_number, episode.season_number) - { - return Ok(None); - } - - // skip the episode if it's a special - if self.skip_special - && (episode.sequence_number == 0.0 || episode.sequence_number.fract() != 0.0) - { - return Ok(None); - } - - // check if the audio locale is correct. - // should only be incorrect if the console input was a episode url. otherwise - // `DownloadFilter::visit_season` returns the correct episodes with matching audio - if episode.audio_locale != self.download.audio { - // check if any other version (same episode, other language) of this episode is available - // with the requested audio. if not, return an error - if !episode - .available_versions() - .await? - .contains(&self.download.audio) - { - let error_message = format!( - "Episode {} ({}) of {} season {} is not available with {} audio", - episode.sequence_number, - episode.title, - episode.series_title, - episode.season_number, - self.download.audio - ); - // sometimes a series randomly has episode in an other language. if this is the case, - // only error if the input url was a episode url - if self.season_visited { - warn!("{}", error_message); - return Ok(None); - } else { - bail!("{}", error_message) - } - } - // overwrite the current episode with the other version episode - episode = episode - .version(vec![self.download.audio.clone()]) - .await? - .remove(0) - } - - // check if the subtitles are supported - if let Some(subtitle_locale) = &self.download.subtitle { - if !episode.subtitle_locales.contains(subtitle_locale) { - // if the episode doesn't have the requested subtitles, print a error. to print this - // error only once per season, it's checked if an error got printed before by looking - // up if the season id is present in `self.season_subtitles_missing`. if not, print - // the error and add the season id to `self.season_subtitles_missing`. if it is - // present, skip the error printing - if !self - .season_subtitles_missing - .contains(&episode.season_number) - { - self.season_subtitles_missing.push(episode.season_number); - error!( - "{} season {} is not available with {} subtitles", - episode.series_title, episode.season_number, subtitle_locale - ); - } - return Ok(None); - } - } - - if self.seasons_with_premium.is_some() && episode.is_premium_only { - if !self - .seasons_with_premium - .as_ref() - .unwrap() - .contains(&episode.season_number) - { - warn!( - "Skipping premium episodes in season {}", - episode.season_number - ); - self.seasons_with_premium - .as_mut() - .unwrap() - .push(episode.season_number) - } - - return Ok(None); - } - - let mut relative_episode_number = None; - let mut relative_sequence_number = None; - // get the relative episode number. only done if the output string has the pattern to include - // the relative episode number as this requires some extra fetching - if Format::has_relative_fmt(&self.download.output) { - let season_eps = match self.season_episodes.get(&episode.season_number) { - Some(eps) => eps, - None => { - self.season_episodes.insert( - episode.season_number, - episode.season().await?.episodes().await?, - ); - self.season_episodes.get(&episode.season_number).unwrap() - } - }; - let mut non_integer_sequence_number_count = 0; - for (i, ep) in season_eps.iter().enumerate() { - if ep.sequence_number.fract() != 0.0 || ep.sequence_number == 0.0 { - non_integer_sequence_number_count += 1; - } - if ep.id == episode.id { - relative_episode_number = Some(i + 1); - relative_sequence_number = Some( - (i + 1 - non_integer_sequence_number_count) as f32 - + fract(ep.sequence_number), - ); - break; - } - } - if relative_episode_number.is_none() || relative_sequence_number.is_none() { - warn!( - "Failed to get relative episode number for episode {} ({}) of {} season {}", - episode.sequence_number, - episode.title, - episode.series_title, - episode.season_number, - ) - } - } - - Ok(Some(SingleFormat::new_from_episode( - episode.clone(), - self.download.subtitle.clone().map_or(vec![], |s| { - if episode.subtitle_locales.contains(&s) { - vec![s] - } else { - vec![] - } - }), - relative_episode_number.map(|n| n as u32), - relative_sequence_number, - ))) - } - - async fn visit_movie_listing(&mut self, movie_listing: MovieListing) -> Result> { - Ok(movie_listing.movies().await?) - } - - async fn visit_movie(&mut self, movie: Movie) -> Result> { - Ok(Some(SingleFormat::new_from_movie(movie, vec![]))) - } - - async fn visit_music_video(&mut self, music_video: MusicVideo) -> Result> { - Ok(Some(SingleFormat::new_from_music_video(music_video))) - } - - async fn visit_concert(&mut self, concert: Concert) -> Result> { - Ok(Some(SingleFormat::new_from_concert(concert))) - } - - async fn finish(self, input: Vec) -> Result { - let mut single_format_collection = SingleFormatCollection::new(); - - for data in input { - single_format_collection.add_single_formats(vec![data]) - } - - Ok(single_format_collection) - } -} diff --git a/crunchy-cli-core/src/download/mod.rs b/crunchy-cli-core/src/download/mod.rs index 696872e..47ca304 100644 --- a/crunchy-cli-core/src/download/mod.rs +++ b/crunchy-cli-core/src/download/mod.rs @@ -1,4 +1,3 @@ mod command; -mod filter; pub use command::Download; diff --git a/crunchy-cli-core/src/search/format.rs b/crunchy-cli-core/src/search/format.rs index 10f4624..cf3c5bc 100644 --- a/crunchy-cli-core/src/search/format.rs +++ b/crunchy-cli-core/src/search/format.rs @@ -241,14 +241,6 @@ macro_rules! must_match_if_true { }; } -macro_rules! self_and_versions { - ($var:expr => $audio:expr) => {{ - let mut items = vec![$var.clone()]; - items.extend($var.clone().version($audio).await?); - items - }}; -} - pub struct Format { pattern: Vec<(Range, Scope, String)>, pattern_count: HashMap, @@ -421,7 +413,15 @@ impl Format { }; let mut seasons = vec![]; for season in tmp_seasons { - seasons.extend(self_and_versions!(season => self.filter_options.audio.clone())) + seasons.push(season.clone()); + for version in season.versions { + if season.id == version.id { + continue; + } + if self.filter_options.audio.contains(&version.audio_locale) { + seasons.push(version.season().await?) + } + } } tree.extend( self.filter_options @@ -435,7 +435,15 @@ impl Format { if !episode_empty || !stream_empty { match &media_collection { MediaCollection::Episode(episode) => { - let episodes = self_and_versions!(episode => self.filter_options.audio.clone()); + let mut episodes = vec![episode.clone()]; + for version in &episode.versions { + if episode.id == version.id { + continue; + } + if self.filter_options.audio.contains(&version.audio_locale) { + episodes.push(version.episode().await?) + } + } tree.push(( Season::default(), episodes diff --git a/crunchy-cli-core/src/utils/filter.rs b/crunchy-cli-core/src/utils/filter.rs index 63fac9d..b95596e 100644 --- a/crunchy-cli-core/src/utils/filter.rs +++ b/crunchy-cli-core/src/utils/filter.rs @@ -1,24 +1,397 @@ +use crate::utils::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, MediaCollection, Movie, MovieListing, MusicVideo, Season, Series, + Concert, Episode, Locale, MediaCollection, Movie, MovieListing, MusicVideo, Season, Series, }; +use log::{info, warn}; +use std::collections::{BTreeMap, HashMap}; +use std::ops::Not; -pub trait Filter { - type T: Send + Sized; - type Output: Send + Sized; +pub(crate) enum FilterMediaScope<'a> { + Series(&'a Series), + Season(&'a Season), + /// Always contains 1 or 2 episodes. + /// - 1: The episode's audio is completely missing + /// - 2: The requested audio is only available from first entry to last entry + Episode(Vec<&'a Episode>), +} - async fn visit_series(&mut self, series: Series) -> Result>; - async fn visit_season(&mut self, season: Season) -> Result>; - async fn visit_episode(&mut self, episode: Episode) -> Result>; - async fn visit_movie_listing(&mut self, movie_listing: MovieListing) -> Result>; - async fn visit_movie(&mut self, movie: Movie) -> Result>; - async fn visit_music_video(&mut self, music_video: MusicVideo) -> Result>; - async fn visit_concert(&mut self, concert: Concert) -> Result>; +pub(crate) struct Filter { + url_filter: UrlFilter, - async fn visit(mut self, media_collection: MediaCollection) -> Result - where - Self: Send + Sized, - { + skip_specials: bool, + interactive_input: bool, + + relative_episode_number: bool, + + audio_locales: Vec, + subtitle_locales: Vec, + + audios_missing: fn(FilterMediaScope, Vec<&Locale>) -> Result, + subtitles_missing: fn(FilterMediaScope, Vec<&Locale>) -> Result, + no_premium: fn(u32) -> Result<()>, + + is_premium: bool, + + series_visited: bool, + season_episodes: HashMap>, + season_with_premium: Option>, + season_sorting: Vec, +} + +impl Filter { + #[allow(clippy::too_many_arguments)] + pub(crate) fn new( + url_filter: UrlFilter, + audio_locales: Vec, + subtitle_locales: Vec, + audios_missing: fn(FilterMediaScope, Vec<&Locale>) -> Result, + subtitles_missing: fn(FilterMediaScope, Vec<&Locale>) -> Result, + no_premium: fn(u32) -> Result<()>, + relative_episode_number: bool, + interactive_input: bool, + skip_specials: bool, + is_premium: bool, + ) -> Self { + Self { + url_filter, + audio_locales, + subtitle_locales, + relative_episode_number, + interactive_input, + audios_missing, + subtitles_missing, + no_premium, + is_premium, + series_visited: false, + season_episodes: HashMap::new(), + skip_specials, + season_with_premium: is_premium.not().then_some(vec![]), + season_sorting: vec![], + } + } + + async fn visit_series(&mut self, series: Series) -> Result> { + // the audio locales field isn't always populated + if !series.audio_locales.is_empty() { + let missing_audios = missing_locales(&series.audio_locales, &self.audio_locales); + if !missing_audios.is_empty() + && !(self.audios_missing)(FilterMediaScope::Series(&series), missing_audios)? + { + return Ok(vec![]); + } + let missing_subtitles = + missing_locales(&series.subtitle_locales, &self.subtitle_locales); + if !missing_subtitles.is_empty() + && !(self.subtitles_missing)(FilterMediaScope::Series(&series), missing_subtitles)? + { + return Ok(vec![]); + } + } + + let mut seasons = vec![]; + for season in series.seasons().await? { + if !self.url_filter.is_season_valid(season.season_number) { + continue; + } + let missing_audios = missing_locales( + &season + .versions + .iter() + .map(|l| l.audio_locale.clone()) + .collect::>(), + &self.audio_locales, + ); + if !missing_audios.is_empty() + && !(self.audios_missing)(FilterMediaScope::Season(&season), missing_audios)? + { + return Ok(vec![]); + } + seasons.push(season) + } + + 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(", ") + ) + } + } + + self.series_visited = true; + + Ok(seasons) + } + + async fn visit_season(&mut self, season: Season) -> Result> { + if !self.url_filter.is_season_valid(season.season_number) { + return Ok(vec![]); + } + + let mut seasons = vec![]; + if self + .audio_locales + .iter() + .any(|l| season.audio_locales.contains(l)) + { + seasons.push(season.clone()) + } + for version in season.versions { + if season.id == version.id { + continue; + } + if self.audio_locales.contains(&version.audio_locale) { + seasons.push(version.season().await?) + } + } + + let mut episodes = vec![]; + for season in seasons { + self.season_sorting.push(season.id.clone()); + let mut eps = season.episodes().await?; + + // removes any episode that does not have the audio locale of the season. yes, this is + // the case sometimes + if season.audio_locales.len() < 2 { + let season_locale = season + .audio_locales + .first() + .cloned() + .unwrap_or(Locale::ja_JP); + eps.retain(|e| e.audio_locale == season_locale) + } + + if eps.len() < season.number_of_episodes as usize + && !(self.audios_missing)( + FilterMediaScope::Episode(vec![eps.first().unwrap(), eps.last().unwrap()]), + vec![&eps.first().unwrap().audio_locale], + )? + { + return Ok(vec![]); + } + + episodes.extend(eps) + } + + if self.relative_episode_number { + for episode in &episodes { + self.season_episodes + .entry(episode.season_id.clone()) + .or_default() + .push(episode.clone()) + } + } + + Ok(episodes) + } + + async fn visit_episode(&mut self, episode: Episode) -> Result> { + if !self + .url_filter + .is_episode_valid(episode.sequence_number, episode.season_number) + { + return Ok(vec![]); + } + + // skip the episode if it's a special + if self.skip_specials + && (episode.sequence_number == 0.0 || episode.sequence_number.fract() != 0.0) + { + return Ok(vec![]); + } + + let mut episodes = vec![]; + if !self.series_visited { + if self.audio_locales.contains(&episode.audio_locale) { + episodes.push(episode.clone()) + } + for version in &episode.versions { + // `episode` is also a version of itself. the if block above already adds the + // episode if it matches the requested audio, so it doesn't need to be requested + // here again + if version.id == episode.id { + continue; + } + if self.audio_locales.contains(&version.audio_locale) { + episodes.push(version.episode().await?) + } + } + + let audio_locales: Vec = + episodes.iter().map(|e| e.audio_locale.clone()).collect(); + let missing_audios = missing_locales(&audio_locales, &self.audio_locales); + if !missing_audios.is_empty() + && !(self.audios_missing)( + FilterMediaScope::Episode(vec![&episode]), + missing_audios, + )? + { + return Ok(vec![]); + } + + let mut subtitle_locales: Vec = episodes + .iter() + .flat_map(|e| e.subtitle_locales.clone()) + .collect(); + subtitle_locales.sort(); + subtitle_locales.dedup(); + let missing_subtitles = missing_locales(&subtitle_locales, &self.subtitle_locales); + if !missing_subtitles.is_empty() + && !(self.subtitles_missing)( + FilterMediaScope::Episode(vec![&episode]), + missing_subtitles, + )? + { + return Ok(vec![]); + } + } else { + episodes.push(episode.clone()) + } + + if let Some(seasons_with_premium) = &mut self.season_with_premium { + let episodes_len_before = episodes.len(); + episodes.retain(|e| !e.is_premium_only && !self.is_premium); + if episodes_len_before < episodes.len() + && !seasons_with_premium.contains(&episode.season_number) + { + (self.no_premium)(episode.season_number)?; + seasons_with_premium.push(episode.season_number) + } + + if episodes.is_empty() { + return Ok(vec![]); + } + } + + let mut relative_episode_number = None; + let mut relative_sequence_number = None; + if self.relative_episode_number { + let season_eps = match self.season_episodes.get(&episode.season_id) { + Some(eps) => eps, + None => { + self.season_episodes.insert( + episode.season_id.clone(), + episode.season().await?.episodes().await?, + ); + self.season_episodes.get(&episode.season_id).unwrap() + } + }; + let mut non_integer_sequence_number_count = 0; + for (i, ep) in season_eps.iter().enumerate() { + if ep.sequence_number != 0.0 || ep.sequence_number.fract() == 0.0 { + non_integer_sequence_number_count += 1 + } + if ep.id == episode.id { + relative_episode_number = Some(i + 1); + relative_sequence_number = Some( + (i + 1 - non_integer_sequence_number_count) as f32 + + fract(ep.sequence_number), + ); + break; + } + } + if relative_episode_number.is_none() || relative_sequence_number.is_none() { + warn!( + "Failed to get relative episode number for episode {} ({}) of {} season {}", + episode.sequence_number, + episode.title, + episode.series_title, + episode.season_number, + ) + } + } + + Ok(episodes + .into_iter() + .map(|e| { + SingleFormat::new_from_episode( + e.clone(), + e.subtitle_locales, + relative_episode_number.map(|n| n as u32), + relative_sequence_number, + ) + }) + .collect()) + } + + async fn visit_movie_listing(&mut self, movie_listing: MovieListing) -> Result> { + Ok(movie_listing.movies().await?) + } + + async fn visit_movie(&mut self, movie: Movie) -> Result> { + Ok(vec![SingleFormat::new_from_movie(movie, vec![])]) + } + + async fn visit_music_video(&mut self, music_video: MusicVideo) -> Result> { + Ok(vec![SingleFormat::new_from_music_video(music_video)]) + } + + async fn visit_concert(&mut self, concert: Concert) -> Result> { + Ok(vec![SingleFormat::new_from_concert(concert)]) + } + + async fn finish(self, input: Vec>) -> Result { + let flatten_input: Vec = input.into_iter().flatten().collect(); + + let mut single_format_collection = SingleFormatCollection::new(); + + let mut pre_sorted: BTreeMap> = BTreeMap::new(); + for data in flatten_input { + pre_sorted + .entry(data.identifier.clone()) + .or_default() + .push(data) + } + + let mut sorted: Vec<(String, Vec)> = pre_sorted.into_iter().collect(); + sorted.sort_by(|(_, a), (_, b)| { + self.season_sorting + .iter() + .position(|p| p == &a.first().unwrap().season_id) + .unwrap() + .cmp( + &self + .season_sorting + .iter() + .position(|p| p == &b.first().unwrap().season_id) + .unwrap(), + ) + }); + + for (_, mut data) in sorted { + data.sort_by(|a, b| { + self.audio_locales + .iter() + .position(|p| p == &a.audio) + .unwrap_or(usize::MAX) + .cmp( + &self + .audio_locales + .iter() + .position(|p| p == &b.audio) + .unwrap_or(usize::MAX), + ) + }); + single_format_collection.add_single_formats(data) + } + + Ok(single_format_collection) + } + + pub(crate) async fn visit( + mut self, + media_collection: MediaCollection, + ) -> Result { let mut items = vec![media_collection]; let mut result = vec![]; @@ -42,9 +415,7 @@ pub trait Filter { .collect::>(), ), MediaCollection::Episode(episode) => { - if let Some(t) = self.visit_episode(episode).await? { - result.push(t) - } + result.push(self.visit_episode(episode).await?) } MediaCollection::MovieListing(movie_listing) => new_items.extend( self.visit_movie_listing(movie_listing) @@ -53,20 +424,12 @@ pub trait Filter { .map(|m| m.into()) .collect::>(), ), - MediaCollection::Movie(movie) => { - if let Some(t) = self.visit_movie(movie).await? { - result.push(t) - } - } + MediaCollection::Movie(movie) => result.push(self.visit_movie(movie).await?), MediaCollection::MusicVideo(music_video) => { - if let Some(t) = self.visit_music_video(music_video).await? { - result.push(t) - } + result.push(self.visit_music_video(music_video).await?) } MediaCollection::Concert(concert) => { - if let Some(t) = self.visit_concert(concert).await? { - result.push(t) - } + result.push(self.visit_concert(concert).await?) } } } @@ -76,8 +439,10 @@ pub trait Filter { self.finish(result).await } +} - async fn finish(self, input: Vec) -> Result; +fn missing_locales<'a>(available: &[Locale], searched: &'a [Locale]) -> Vec<&'a Locale> { + searched.iter().filter(|p| !available.contains(p)).collect() } /// Remove all duplicates from a [`Vec`]. diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index f0a002c..33ce261 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -12,6 +12,7 @@ use std::collections::BTreeMap; use std::env; use std::path::{Path, PathBuf}; +#[allow(dead_code)] #[derive(Clone)] pub struct SingleFormat { pub identifier: String, @@ -347,6 +348,7 @@ impl Iterator for SingleFormatCollectionIterator { } } +#[allow(dead_code)] #[derive(Clone)] pub struct Format { pub title: String, From 8047680799d88521232986e83091b06a5253022b Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 19 Jun 2024 23:18:35 +0200 Subject: [PATCH 268/272] Add drm check --- crunchy-cli-core/src/utils/video.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crunchy-cli-core/src/utils/video.rs b/crunchy-cli-core/src/utils/video.rs index 8b25791..a15296c 100644 --- a/crunchy-cli-core/src/utils/video.rs +++ b/crunchy-cli-core/src/utils/video.rs @@ -27,6 +27,11 @@ pub async fn stream_data_from_stream( } } .unwrap(); + + if videos.iter().any(|v| v.drm.is_some()) || audios.iter().any(|v| v.drm.is_some()) { + bail!("Stream is DRM protected") + } + videos.sort_by(|a, b| a.bandwidth.cmp(&b.bandwidth).reverse()); audios.sort_by(|a, b| a.bandwidth.cmp(&b.bandwidth).reverse()); From 509683d23a5689dc958a79440227585c9d383c30 Mon Sep 17 00:00:00 2001 From: bytedream Date: Wed, 19 Jun 2024 23:38:57 +0200 Subject: [PATCH 269/272] Update dependencies and version --- Cargo.lock | 12 ++++++------ Cargo.toml | 8 ++++---- crunchy-cli-core/Cargo.toml | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7fdb3d9..d01a80c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -349,7 +349,7 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "crunchy-cli" -version = "3.6.6" +version = "3.6.7" dependencies = [ "chrono", "clap", @@ -362,7 +362,7 @@ dependencies = [ [[package]] name = "crunchy-cli-core" -version = "3.6.6" +version = "3.6.7" dependencies = [ "anyhow", "async-speed-limit", @@ -1125,8 +1125,8 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.11" -source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=b7969a8#b7969a88210096e0570e29d42fb13533baf62aa6" +version = "0.2.12" +source = "git+https://github.com/crunchy-labs/rust-not-so-native-tls.git?rev=c7ac566#c7ac566559d441bbc3e5e5bd04fb7162c38d88b0" dependencies = [ "libc", "log", @@ -1519,9 +1519,9 @@ checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" [[package]] name = "rsubs-lib" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d01f7609f0b1bc4fe24b352e8d1792c7d71cc43aea797e14b87974cd009ab402" +checksum = "8c9f50e3fbcbf1f0bd109954e2dd813d1715c7b4a92a7bf159a85dea49e9d863" dependencies = [ "regex", "serde", diff --git a/Cargo.toml b/Cargo.toml index f263e59..c1e28bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "crunchy-cli" authors = ["Crunchy Labs Maintainers"] -version = "3.6.6" +version = "3.6.7" 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.37", features = ["macros", "rt-multi-thread", "time"], default-features = false } +tokio = { version = "1.38", features = ["macros", "rt-multi-thread", "time"], default-features = false } -native-tls-crate = { package = "native-tls", version = "0.2.11", optional = true } +native-tls-crate = { package = "native-tls", version = "0.2.12", 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 = "b7969a8" } +native-tls = { git = "https://github.com/crunchy-labs/rust-not-so-native-tls.git", rev = "c7ac566" } [profile.release] strip = true diff --git a/crunchy-cli-core/Cargo.toml b/crunchy-cli-core/Cargo.toml index 5c7b901..399053f 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.6" +version = "3.6.7" edition = "2021" license = "MIT" @@ -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.1" +rsubs-lib = "~0.3.2" rusty-chromaprint = "0.2" serde = "1.0" serde_json = "1.0" @@ -39,7 +39,7 @@ shlex = "1.3" sys-locale = "0.3" tempfile = "3.10" time = "0.3" -tokio = { version = "1.37", features = ["io-util", "macros", "net", "rt-multi-thread", "time"] } +tokio = { version = "1.38", 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 } From 756022b955633c73c2920091b3f02d37ab791004 Mon Sep 17 00:00:00 2001 From: bytedream Date: Thu, 20 Jun 2024 00:12:06 +0200 Subject: [PATCH 270/272] Fix panic when in anonymously --- crunchy-cli-core/src/utils/filter.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/crunchy-cli-core/src/utils/filter.rs b/crunchy-cli-core/src/utils/filter.rs index b95596e..3388741 100644 --- a/crunchy-cli-core/src/utils/filter.rs +++ b/crunchy-cli-core/src/utils/filter.rs @@ -171,13 +171,23 @@ impl Filter { eps.retain(|e| e.audio_locale == season_locale) } - if eps.len() < season.number_of_episodes as usize - && !(self.audios_missing)( - FilterMediaScope::Episode(vec![eps.first().unwrap(), eps.last().unwrap()]), - vec![&eps.first().unwrap().audio_locale], - )? - { - return Ok(vec![]); + #[allow(clippy::if_same_then_else)] + if eps.len() < season.number_of_episodes as usize { + if eps.is_empty() + && !(self.audios_missing)( + FilterMediaScope::Season(&season), + season.audio_locales.iter().collect(), + )? + { + return Ok(vec![]); + } else if !eps.is_empty() + && !(self.audios_missing)( + FilterMediaScope::Episode(vec![eps.first().unwrap(), eps.last().unwrap()]), + vec![&eps.first().unwrap().audio_locale], + )? + { + return Ok(vec![]); + } } episodes.extend(eps) From 2cf9125de3f42052d3fb58f5c3f7325876837c75 Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 1 Jul 2024 16:37:53 +0200 Subject: [PATCH 271/272] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 45b8ea7..1ae2645 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ -> ~~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. +# This project has been sunset as Crunchyroll moved to a DRM-only system. See [#362](https://github.com/crunchy-labs/crunchy-cli/issues/362). # crunchy-cli From 4332b1beef7007129578cc7e253c99c96b5f6e39 Mon Sep 17 00:00:00 2001 From: Simon <47527944+Frooastside@users.noreply.github.com> Date: Mon, 1 Jul 2024 18:43:16 +0200 Subject: [PATCH 272/272] not add start time when syncing (#442) * not add start time when syncing * use itsoffset for all syncing related time shifts --- crunchy-cli-core/src/utils/download.rs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/crunchy-cli-core/src/utils/download.rs b/crunchy-cli-core/src/utils/download.rs index accefce..2e8f321 100644 --- a/crunchy-cli-core/src/utils/download.rs +++ b/crunchy-cli-core/src/utils/download.rs @@ -322,20 +322,14 @@ impl Downloader { if let Some(offsets) = offsets { let mut root_format_idx = 0; - let mut root_format_length = 0; + let mut root_format_offset = u64::MAX; + for (i, format) in self.formats.iter().enumerate() { let offset = offsets.get(&i).copied().unwrap_or_default(); - let format_len = format - .video - .0 - .segments() - .iter() - .map(|s| s.length.as_millis()) - .sum::() as u64 - - offset.num_milliseconds() as u64; - if format_len > root_format_length { + let format_offset = offset.num_milliseconds() as u64; + if format_offset < root_format_offset { root_format_idx = i; - root_format_length = format_len; + root_format_offset = format_offset; } for _ in &format.audios { @@ -567,7 +561,7 @@ impl Downloader { for (i, meta) in videos.iter().enumerate() { if let Some(start_time) = meta.start_time { - input.extend(["-ss".to_string(), format_time_delta(&start_time)]) + input.extend(["-itsoffset".to_string(), format_time_delta(&start_time)]) } input.extend(["-i".to_string(), meta.path.to_string_lossy().to_string()]); maps.extend(["-map".to_string(), i.to_string()]); @@ -588,7 +582,7 @@ impl Downloader { } for (i, meta) in audios.iter().enumerate() { if let Some(start_time) = meta.start_time { - input.extend(["-ss".to_string(), format_time_delta(&start_time)]) + input.extend(["-itsoffset".to_string(), format_time_delta(&start_time)]) } input.extend(["-i".to_string(), meta.path.to_string_lossy().to_string()]); maps.extend(["-map".to_string(), (i + videos.len()).to_string()]); @@ -635,7 +629,7 @@ impl Downloader { if container_supports_softsubs { for (i, meta) in subtitles.iter().enumerate() { if let Some(start_time) = meta.start_time { - input.extend(["-ss".to_string(), format_time_delta(&start_time)]) + input.extend(["-itsoffset".to_string(), format_time_delta(&start_time)]) } input.extend(["-i".to_string(), meta.path.to_string_lossy().to_string()]); maps.extend([