From ca561aca0f1b07a4d545481b1338b70f5c51be7d Mon Sep 17 00:00:00 2001 From: bytedream Date: Tue, 20 Jun 2023 00:06:09 +0200 Subject: [PATCH] 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, } } }