diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 4210828..7fe3796 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -286,10 +286,15 @@ 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, self.skip_specials) - .visit(media_collection) - .await?; + let single_format_collection = ArchiveFilter::new( + url_filter, + self.clone(), + !self.yes, + self.skip_specials, + ctx.crunchy.premium().await, + ) + .visit(media_collection) + .await?; if single_format_collection.is_empty() { progress_handler.stop(format!("Skipping url {} (no matching videos found)", i + 1)); diff --git a/crunchy-cli-core/src/archive/filter.rs b/crunchy-cli-core/src/archive/filter.rs index 90ab373..287bcc0 100644 --- a/crunchy-cli-core/src/archive/filter.rs +++ b/crunchy-cli-core/src/archive/filter.rs @@ -7,6 +7,7 @@ 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, @@ -21,6 +22,7 @@ pub(crate) struct ArchiveFilter { skip_special: bool, season_episodes: HashMap>, season_subtitles_missing: Vec, + seasons_with_premium: Option>, season_sorting: Vec, visited: Visited, } @@ -31,6 +33,7 @@ impl ArchiveFilter { archive: Archive, interactive_input: bool, skip_special: bool, + is_premium: bool, ) -> Self { Self { url_filter, @@ -39,6 +42,7 @@ impl ArchiveFilter { 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, } @@ -310,6 +314,29 @@ impl Filter for ArchiveFilter { 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) + } + + 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 diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index 58055bd..87c0e07 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -246,10 +246,15 @@ 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, self.skip_specials) - .visit(media_collection) - .await?; + let single_format_collection = DownloadFilter::new( + url_filter, + self.clone(), + !self.yes, + self.skip_specials, + ctx.crunchy.premium().await, + ) + .visit(media_collection) + .await?; if single_format_collection.is_empty() { progress_handler.stop(format!("Skipping url {} (no matching videos found)", i + 1)); diff --git a/crunchy-cli-core/src/download/filter.rs b/crunchy-cli-core/src/download/filter.rs index 5076a33..1c62920 100644 --- a/crunchy-cli-core/src/download/filter.rs +++ b/crunchy-cli-core/src/download/filter.rs @@ -7,6 +7,7 @@ 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, @@ -15,6 +16,7 @@ pub(crate) struct DownloadFilter { skip_special: bool, season_episodes: HashMap>, season_subtitles_missing: Vec, + seasons_with_premium: Option>, season_visited: bool, } @@ -24,6 +26,7 @@ impl DownloadFilter { download: Download, interactive_input: bool, skip_special: bool, + is_premium: bool, ) -> Self { Self { url_filter, @@ -32,6 +35,7 @@ impl DownloadFilter { skip_special, season_episodes: HashMap::new(), season_subtitles_missing: vec![], + seasons_with_premium: is_premium.not().then_some(vec![]), season_visited: false, } } @@ -201,6 +205,26 @@ impl Filter for DownloadFilter { } } + 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