From 8125bd5ae0d8920fbfccb8bc61852a276efcc73d Mon Sep 17 00:00:00 2001 From: Alex Clarke Date: Sun, 24 Nov 2024 14:29:13 -0700 Subject: [PATCH] feat(cli): Support for adding a series to Sonarr --- src/cli/radarr/add_command_handler.rs | 10 +- src/cli/radarr/add_command_handler_tests.rs | 16 +- src/cli/sonarr/add_command_handler.rs | 94 ++++- src/cli/sonarr/add_command_handler_tests.rs | 373 +++++++++++++++++- .../library/add_movie_handler_tests.rs | 6 +- src/models/radarr_models.rs | 22 +- src/models/radarr_models_tests.rs | 14 +- src/models/servarr_data/radarr/modals.rs | 6 +- .../servarr_data/radarr/modals_tests.rs | 4 +- src/models/servarr_data/sonarr/sonarr_data.rs | 7 + src/network/radarr_network.rs | 12 +- src/network/radarr_network_tests.rs | 10 +- 12 files changed, 523 insertions(+), 51 deletions(-) diff --git a/src/cli/radarr/add_command_handler.rs b/src/cli/radarr/add_command_handler.rs index 70efb70..0c35a7e 100644 --- a/src/cli/radarr/add_command_handler.rs +++ b/src/cli/radarr/add_command_handler.rs @@ -7,7 +7,7 @@ use tokio::sync::Mutex; use crate::{ app::App, cli::{CliCommandHandler, Command}, - models::radarr_models::{AddMovieBody, AddOptions, MinimumAvailability, Monitor}, + models::radarr_models::{AddMovieBody, AddMovieOptions, MinimumAvailability, MovieMonitor}, network::{radarr_network::RadarrEvent, NetworkTrait}, }; @@ -46,7 +46,7 @@ pub enum RadarrAddCommand { default_value_t = MinimumAvailability::default() )] minimum_availability: MinimumAvailability, - #[arg(long, help = "Should Radarr monitor this film")] + #[arg(long, help = "Disable monitoring for this film")] disable_monitoring: bool, #[arg( long, @@ -59,9 +59,9 @@ pub enum RadarrAddCommand { long, help = "What Radarr should monitor", value_enum, - default_value_t = Monitor::default() + default_value_t = MovieMonitor::default() )] - monitor: Monitor, + monitor: MovieMonitor, #[arg( long, help = "Tell Radarr to not start a search for this film once it's added to your library" @@ -125,7 +125,7 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, RadarrAddCommand> for RadarrAddCommandHan minimum_availability: minimum_availability.to_string(), monitored: !disable_monitoring, tags, - add_options: AddOptions { + add_options: AddMovieOptions { monitor: monitor.to_string(), search_for_movie: !no_search_for_movie, }, diff --git a/src/cli/radarr/add_command_handler_tests.rs b/src/cli/radarr/add_command_handler_tests.rs index 59c9e29..754abd2 100644 --- a/src/cli/radarr/add_command_handler_tests.rs +++ b/src/cli/radarr/add_command_handler_tests.rs @@ -7,7 +7,7 @@ mod tests { radarr::{add_command_handler::RadarrAddCommand, RadarrCommand}, Command, }, - models::radarr_models::{MinimumAvailability, Monitor}, + models::radarr_models::{MinimumAvailability, MovieMonitor}, Cli, }; use pretty_assertions::assert_eq; @@ -112,6 +112,8 @@ mod tests { "/test", "--quality-profile-id", "1", + "--tmdb-id", + "1", flag, ]); @@ -188,7 +190,7 @@ mod tests { minimum_availability: MinimumAvailability::default(), disable_monitoring: false, tag: vec![], - monitor: Monitor::default(), + monitor: MovieMonitor::default(), no_search_for_movie: false, }; @@ -220,7 +222,7 @@ mod tests { minimum_availability: MinimumAvailability::default(), disable_monitoring: false, tag: vec![1, 2], - monitor: Monitor::default(), + monitor: MovieMonitor::default(), no_search_for_movie: false, }; @@ -256,7 +258,7 @@ mod tests { minimum_availability: MinimumAvailability::Released, disable_monitoring: true, tag: vec![1, 2], - monitor: Monitor::MovieAndCollection, + monitor: MovieMonitor::MovieAndCollection, no_search_for_movie: true, }; @@ -357,7 +359,7 @@ mod tests { app::App, cli::{radarr::add_command_handler::RadarrAddCommandHandler, CliCommandHandler}, models::{ - radarr_models::{AddMovieBody, AddOptions, RadarrSerdeable}, + radarr_models::{AddMovieBody, AddMovieOptions, RadarrSerdeable}, Serdeable, }, network::{radarr_network::RadarrEvent, MockNetworkTrait, NetworkEvent}, @@ -379,7 +381,7 @@ mod tests { minimum_availability: "released".to_owned(), monitored: false, tags: vec![1, 2], - add_options: AddOptions { + add_options: AddMovieOptions { monitor: "movieAndCollection".to_owned(), search_for_movie: false, }, @@ -404,7 +406,7 @@ mod tests { minimum_availability: MinimumAvailability::Released, disable_monitoring: true, tag: vec![1, 2], - monitor: Monitor::MovieAndCollection, + monitor: MovieMonitor::MovieAndCollection, no_search_for_movie: true, }; diff --git a/src/cli/sonarr/add_command_handler.rs b/src/cli/sonarr/add_command_handler.rs index 3cb3978..b1ae7b5 100644 --- a/src/cli/sonarr/add_command_handler.rs +++ b/src/cli/sonarr/add_command_handler.rs @@ -1,12 +1,13 @@ use std::sync::Arc; use anyhow::Result; -use clap::Subcommand; +use clap::{ArgAction, Subcommand}; use tokio::sync::Mutex; use crate::{ app::App, cli::{CliCommandHandler, Command}, + models::sonarr_models::{AddSeriesBody, AddSeriesOptions, SeriesMonitor, SeriesType}, network::{sonarr_network::SonarrEvent, NetworkTrait}, }; @@ -18,6 +19,63 @@ mod add_command_handler_tests; #[derive(Debug, Clone, PartialEq, Eq, Subcommand)] pub enum SonarrAddCommand { + #[command(about = "Add a new series to your Sonarr library")] + Series { + #[arg( + long, + help = "The TVDB ID of the series you wish to add to your library", + required = true + )] + tvdb_id: i64, + #[arg( + long, + help = "The root folder path where all series data and metadata should live", + required = true + )] + root_folder_path: String, + #[arg( + long, + help = "The ID of the quality profile to use for this series", + required = true + )] + quality_profile_id: i64, + #[arg( + long, + help = "The ID of the language profile to use for this series", + required = true + )] + language_profile_id: i64, + #[arg( + long, + help = "The type of series", + value_enum, + default_value_t = SeriesType::default() + )] + series_type: SeriesType, + #[arg(long, help = "Disable monitoring for this series")] + disable_monitoring: bool, + #[arg(long, help = "Don't use season folders for this series")] + disable_season_folders: bool, + #[arg( + long, + help = "Tag IDs to tag the series with", + value_parser, + action = ArgAction::Append + )] + tag: Vec, + #[arg( + long, + help = "What Sonarr should monitor", + value_enum, + default_value_t = SeriesMonitor::default() + )] + monitor: SeriesMonitor, + #[arg( + long, + help = "Tell Sonarr to not start a search for this series once it's added to your library" + )] + no_search_for_series: bool, + }, #[command(about = "Add a new root folder")] RootFolder { #[arg(long, help = "The path of the new root folder", required = true)] @@ -57,6 +115,40 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, SonarrAddCommand> for SonarrAddCommandHan async fn handle(self) -> Result { let result = match self.command { + SonarrAddCommand::Series { + tvdb_id, + root_folder_path, + quality_profile_id, + language_profile_id, + series_type, + disable_monitoring, + disable_season_folders, + tag: tags, + monitor, + no_search_for_series, + } => { + let body = AddSeriesBody { + tvdb_id, + title: String::new(), + monitored: !disable_monitoring, + root_folder_path, + quality_profile_id, + language_profile_id, + series_type: series_type.to_string(), + season_folder: !disable_season_folders, + tags, + add_options: AddSeriesOptions { + monitor: monitor.to_string(), + search_for_cutoff_unmet_episodes: !no_search_for_series, + search_for_missing_episodes: !no_search_for_series, + }, + }; + let resp = self + .network + .handle_network_event(SonarrEvent::AddSeries(Some(body)).into()) + .await?; + serde_json::to_string_pretty(&resp)? + } SonarrAddCommand::RootFolder { root_folder_path } => { let resp = self .network diff --git a/src/cli/sonarr/add_command_handler_tests.rs b/src/cli/sonarr/add_command_handler_tests.rs index 9a6f251..03b4016 100644 --- a/src/cli/sonarr/add_command_handler_tests.rs +++ b/src/cli/sonarr/add_command_handler_tests.rs @@ -23,8 +23,11 @@ mod tests { } mod cli { + use crate::models::sonarr_models::{SeriesMonitor, SeriesType}; + use super::*; use pretty_assertions::assert_eq; + use rstest::rstest; #[test] fn test_add_root_folder_requires_arguments() { @@ -60,6 +63,318 @@ mod tests { } } + #[test] + fn test_add_series_requires_arguments() { + let result = Cli::command().try_get_matches_from(["managarr", "sonarr", "add", "series"]); + + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().kind(), + ErrorKind::MissingRequiredArgument + ); + } + + #[test] + fn test_add_series_requires_tvdb_id() { + let result = Cli::command().try_get_matches_from([ + "managarr", + "sonarr", + "add", + "series", + "--root-folder-path", + "test", + "--quality-profile-id", + "1", + "--language-profile-id", + "1", + ]); + + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().kind(), + ErrorKind::MissingRequiredArgument + ); + } + + #[test] + fn test_add_series_requires_root_folder_path() { + let result = Cli::command().try_get_matches_from([ + "managarr", + "sonarr", + "add", + "series", + "--tvdb-id", + "1", + "--quality-profile-id", + "1", + "--language-profile-id", + "1", + ]); + + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().kind(), + ErrorKind::MissingRequiredArgument + ); + } + + #[test] + fn test_add_series_requires_quality_profile_id() { + let result = Cli::command().try_get_matches_from([ + "managarr", + "sonarr", + "add", + "series", + "--tvdb-id", + "1", + "--root-folder-path", + "test", + "--language-profile-id", + "1", + ]); + + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().kind(), + ErrorKind::MissingRequiredArgument + ); + } + + #[test] + fn test_add_series_requires_language_profile_id() { + let result = Cli::command().try_get_matches_from([ + "managarr", + "sonarr", + "add", + "series", + "--tvdb-id", + "1", + "--root-folder-path", + "test", + "--quality-profile-id", + "1", + ]); + + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().kind(), + ErrorKind::MissingRequiredArgument + ); + } + + #[rstest] + fn test_add_series_assert_argument_flags_require_args( + #[values("--series-type", "--tag", "--monitor")] flag: &str, + ) { + let result = Cli::command().try_get_matches_from([ + "managarr", + "sonarr", + "add", + "series", + "--tvdb-id", + "1", + "--root-folder-path", + "/test", + "--quality-profile-id", + "1", + "--language-profile-id", + "1", + flag, + ]); + + assert!(result.is_err()); + assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidValue); + } + + #[test] + fn test_add_series_all_arguments_satisfied() { + let result = Cli::command().try_get_matches_from([ + "managarr", + "sonarr", + "add", + "series", + "--root-folder-path", + "/test", + "--quality-profile-id", + "1", + "--language-profile-id", + "1", + "--tvdb-id", + "1", + ]); + + assert!(result.is_ok()); + } + + #[test] + fn test_add_series_series_type_validation() { + let result = Cli::command().try_get_matches_from([ + "managarr", + "sonarr", + "add", + "series", + "--root-folder-path", + "/test", + "--quality-profile-id", + "1", + "--language-profile-id", + "1", + "--tvdb-id", + "1", + "--series-type", + "test", + ]); + + assert!(result.is_err()); + assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidValue); + } + + #[test] + fn test_add_series_monitor_validation() { + let result = Cli::command().try_get_matches_from([ + "managarr", + "sonarr", + "add", + "series", + "--root-folder-path", + "/test", + "--quality-profile-id", + "1", + "--language-profile-id", + "1", + "--tvdb-id", + "1", + "--monitor", + "test", + ]); + + assert!(result.is_err()); + assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidValue); + } + + #[test] + fn test_add_series_defaults() { + let expected_args = SonarrAddCommand::Series { + tvdb_id: 1, + root_folder_path: "/test".to_owned(), + quality_profile_id: 1, + language_profile_id: 1, + series_type: SeriesType::default(), + disable_monitoring: false, + disable_season_folders: false, + tag: vec![], + monitor: SeriesMonitor::default(), + no_search_for_series: false, + }; + + let result = Cli::try_parse_from([ + "managarr", + "sonarr", + "add", + "series", + "--root-folder-path", + "/test", + "--quality-profile-id", + "1", + "--language-profile-id", + "1", + "--tvdb-id", + "1", + ]); + + assert!(result.is_ok()); + if let Some(Command::Sonarr(SonarrCommand::Add(add_command))) = result.unwrap().command { + assert_eq!(add_command, expected_args); + } + } + + #[test] + fn test_add_series_tags_is_repeatable() { + let expected_args = SonarrAddCommand::Series { + tvdb_id: 1, + root_folder_path: "/test".to_owned(), + quality_profile_id: 1, + language_profile_id: 1, + series_type: SeriesType::default(), + disable_monitoring: false, + disable_season_folders: false, + tag: vec![1, 2], + monitor: SeriesMonitor::default(), + no_search_for_series: false, + }; + + let result = Cli::try_parse_from([ + "managarr", + "sonarr", + "add", + "series", + "--root-folder-path", + "/test", + "--quality-profile-id", + "1", + "--language-profile-id", + "1", + "--tvdb-id", + "1", + "--tag", + "1", + "--tag", + "2", + ]); + + assert!(result.is_ok()); + if let Some(Command::Sonarr(SonarrCommand::Add(add_command))) = result.unwrap().command { + assert_eq!(add_command, expected_args); + } + } + + #[test] + fn test_add_series_all_args_defined() { + let expected_args = SonarrAddCommand::Series { + tvdb_id: 1, + root_folder_path: "/test".to_owned(), + quality_profile_id: 1, + language_profile_id: 1, + series_type: SeriesType::Anime, + disable_monitoring: true, + disable_season_folders: true, + tag: vec![1, 2], + monitor: SeriesMonitor::Future, + no_search_for_series: true, + }; + + let result = Cli::try_parse_from([ + "managarr", + "sonarr", + "add", + "series", + "--root-folder-path", + "/test", + "--quality-profile-id", + "1", + "--language-profile-id", + "1", + "--series-type", + "anime", + "--disable-monitoring", + "--disable-season-folders", + "--tvdb-id", + "1", + "--tag", + "1", + "--tag", + "2", + "--monitor", + "future", + "--no-search-for-series", + ]); + + assert!(result.is_ok()); + if let Some(Command::Sonarr(SonarrCommand::Add(add_command))) = result.unwrap().command { + assert_eq!(add_command, expected_args); + } + } + #[test] fn test_add_tag_requires_arguments() { let result = Cli::command().try_get_matches_from(["managarr", "sonarr", "add", "tag"]); @@ -93,7 +408,12 @@ mod tests { use crate::{ app::App, cli::{sonarr::add_command_handler::SonarrAddCommandHandler, CliCommandHandler}, - models::{sonarr_models::SonarrSerdeable, Serdeable}, + models::{ + sonarr_models::{ + AddSeriesBody, AddSeriesOptions, SeriesMonitor, SeriesType, SonarrSerdeable, + }, + Serdeable, + }, network::{sonarr_network::SonarrEvent, MockNetworkTrait, NetworkEvent}, }; @@ -131,6 +451,57 @@ mod tests { assert!(result.is_ok()); } + #[tokio::test] + async fn test_handle_add_series_command() { + let expected_add_series_body = AddSeriesBody { + tvdb_id: 1, + title: String::new(), + root_folder_path: "/test".to_owned(), + quality_profile_id: 1, + language_profile_id: 1, + series_type: "anime".to_owned(), + monitored: false, + tags: vec![1, 2], + season_folder: false, + add_options: AddSeriesOptions { + monitor: "future".to_owned(), + search_for_cutoff_unmet_episodes: false, + search_for_missing_episodes: false, + }, + }; + let mut mock_network = MockNetworkTrait::new(); + mock_network + .expect_handle_network_event() + .with(eq::( + SonarrEvent::AddSeries(Some(expected_add_series_body)).into(), + )) + .times(1) + .returning(|_| { + Ok(Serdeable::Sonarr(SonarrSerdeable::Value( + json!({"testResponse": "response"}), + ))) + }); + let app_arc = Arc::new(Mutex::new(App::default())); + let add_series_command = SonarrAddCommand::Series { + tvdb_id: 1, + root_folder_path: "/test".to_owned(), + quality_profile_id: 1, + language_profile_id: 1, + series_type: SeriesType::Anime, + disable_monitoring: true, + disable_season_folders: true, + tag: vec![1, 2], + monitor: SeriesMonitor::Future, + no_search_for_series: true, + }; + + let result = SonarrAddCommandHandler::with(&app_arc, add_series_command, &mut mock_network) + .handle() + .await; + + assert!(result.is_ok()); + } + #[tokio::test] async fn test_handle_add_tag_command() { let expected_tag_name = "test".to_owned(); diff --git a/src/handlers/radarr_handlers/library/add_movie_handler_tests.rs b/src/handlers/radarr_handlers/library/add_movie_handler_tests.rs index c0797ec..2800832 100644 --- a/src/handlers/radarr_handlers/library/add_movie_handler_tests.rs +++ b/src/handlers/radarr_handlers/library/add_movie_handler_tests.rs @@ -8,7 +8,7 @@ mod tests { use crate::event::Key; use crate::handlers::radarr_handlers::library::add_movie_handler::AddMovieHandler; use crate::handlers::KeyEventHandler; - use crate::models::radarr_models::{AddMovieSearchResult, MinimumAvailability, Monitor}; + use crate::models::radarr_models::{AddMovieSearchResult, MinimumAvailability, MovieMonitor}; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ADD_MOVIE_BLOCKS}; use crate::models::servarr_models::RootFolder; use crate::models::HorizontallyScrollableText; @@ -141,7 +141,7 @@ mod tests { fn test_add_movie_select_monitor_scroll( #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, ) { - let monitor_vec = Vec::from_iter(Monitor::iter()); + let monitor_vec = Vec::from_iter(MovieMonitor::iter()); let mut app = App::default(); app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); app @@ -534,7 +534,7 @@ mod tests { #[test] fn test_add_movie_select_monitor_home_end() { - let monitor_vec = Vec::from_iter(Monitor::iter()); + let monitor_vec = Vec::from_iter(MovieMonitor::iter()); let mut app = App::default(); app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); app diff --git a/src/models/radarr_models.rs b/src/models/radarr_models.rs index cf37f7c..6049e5f 100644 --- a/src/models/radarr_models.rs +++ b/src/models/radarr_models.rs @@ -29,7 +29,7 @@ pub struct AddMovieBody { pub minimum_availability: String, pub monitored: bool, pub tags: Vec, - pub add_options: AddOptions, + pub add_options: AddMovieOptions, } #[derive(Derivative, Serialize, Deserialize, Debug, Default, Clone, PartialEq, Eq)] @@ -51,7 +51,7 @@ pub struct AddMovieSearchResult { #[derive(Default, Clone, Serialize, Debug, PartialEq, Eq)] #[serde(rename_all = "camelCase")] -pub struct AddOptions { +pub struct AddMovieOptions { pub monitor: String, pub search_for_movie: bool, } @@ -305,30 +305,30 @@ impl<'a> EnumDisplayStyle<'a> for MinimumAvailability { } #[derive(Default, PartialEq, Eq, Clone, Copy, Debug, EnumIter, ValueEnum)] -pub enum Monitor { +pub enum MovieMonitor { #[default] MovieOnly, MovieAndCollection, None, } -impl Display for Monitor { +impl Display for MovieMonitor { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { let monitor = match self { - Monitor::MovieOnly => "movieOnly", - Monitor::MovieAndCollection => "movieAndCollection", - Monitor::None => "none", + MovieMonitor::MovieOnly => "movieOnly", + MovieMonitor::MovieAndCollection => "movieAndCollection", + MovieMonitor::None => "none", }; write!(f, "{monitor}") } } -impl<'a> EnumDisplayStyle<'a> for Monitor { +impl<'a> EnumDisplayStyle<'a> for MovieMonitor { fn to_display_str(self) -> &'a str { match self { - Monitor::MovieOnly => "Movie only", - Monitor::MovieAndCollection => "Movie and Collection", - Monitor::None => "None", + MovieMonitor::MovieOnly => "Movie only", + MovieMonitor::MovieAndCollection => "Movie and Collection", + MovieMonitor::None => "None", } } } diff --git a/src/models/radarr_models_tests.rs b/src/models/radarr_models_tests.rs index d49c3cd..b260344 100644 --- a/src/models/radarr_models_tests.rs +++ b/src/models/radarr_models_tests.rs @@ -7,7 +7,7 @@ mod tests { radarr_models::{ AddMovieSearchResult, BlocklistItem, BlocklistResponse, Collection, Credit, DiskSpace, DownloadRecord, DownloadsResponse, Indexer, IndexerSettings, IndexerTestResult, - MinimumAvailability, Monitor, Movie, MovieHistoryItem, QualityProfile, RadarrRelease, + MinimumAvailability, Movie, MovieHistoryItem, MovieMonitor, QualityProfile, RadarrRelease, RadarrSerdeable, RadarrTask, RadarrTaskName, SystemStatus, Tag, Update, }, servarr_models::{HostConfig, Log, LogResponse, QueueEvent, RootFolder, SecurityConfig}, @@ -43,22 +43,22 @@ mod tests { #[test] fn test_monitor_display() { - assert_str_eq!(Monitor::MovieOnly.to_string(), "movieOnly"); + assert_str_eq!(MovieMonitor::MovieOnly.to_string(), "movieOnly"); assert_str_eq!( - Monitor::MovieAndCollection.to_string(), + MovieMonitor::MovieAndCollection.to_string(), "movieAndCollection" ); - assert_str_eq!(Monitor::None.to_string(), "none"); + assert_str_eq!(MovieMonitor::None.to_string(), "none"); } #[test] fn test_monitor_to_display_str() { - assert_str_eq!(Monitor::MovieOnly.to_display_str(), "Movie only"); + assert_str_eq!(MovieMonitor::MovieOnly.to_display_str(), "Movie only"); assert_str_eq!( - Monitor::MovieAndCollection.to_display_str(), + MovieMonitor::MovieAndCollection.to_display_str(), "Movie and Collection" ); - assert_str_eq!(Monitor::None.to_display_str(), "None"); + assert_str_eq!(MovieMonitor::None.to_display_str(), "None"); } #[test] diff --git a/src/models/servarr_data/radarr/modals.rs b/src/models/servarr_data/radarr/modals.rs index 9a98c4e..843d5ea 100644 --- a/src/models/servarr_data/radarr/modals.rs +++ b/src/models/servarr_data/radarr/modals.rs @@ -1,7 +1,7 @@ use strum::IntoEnumIterator; use crate::models::radarr_models::{ - Collection, Credit, MinimumAvailability, Monitor, Movie, MovieHistoryItem, RadarrRelease, + Collection, Credit, MinimumAvailability, Movie, MovieHistoryItem, MovieMonitor, RadarrRelease, }; use crate::models::servarr_data::radarr::radarr_data::RadarrData; use crate::models::servarr_models::{Indexer, RootFolder}; @@ -195,7 +195,7 @@ impl From<&RadarrData<'_>> for EditMovieModal { #[derive(Default)] pub struct AddMovieModal { pub root_folder_list: StatefulList, - pub monitor_list: StatefulList, + pub monitor_list: StatefulList, pub minimum_availability_list: StatefulList, pub quality_profile_list: StatefulList, pub tags: HorizontallyScrollableText, @@ -206,7 +206,7 @@ impl From<&RadarrData<'_>> for AddMovieModal { let mut add_movie_modal = AddMovieModal::default(); add_movie_modal .monitor_list - .set_items(Vec::from_iter(Monitor::iter())); + .set_items(Vec::from_iter(MovieMonitor::iter())); add_movie_modal .minimum_availability_list .set_items(Vec::from_iter(MinimumAvailability::iter())); diff --git a/src/models/servarr_data/radarr/modals_tests.rs b/src/models/servarr_data/radarr/modals_tests.rs index 62faa71..96e36ad 100644 --- a/src/models/servarr_data/radarr/modals_tests.rs +++ b/src/models/servarr_data/radarr/modals_tests.rs @@ -1,6 +1,6 @@ #[cfg(test)] mod test { - use crate::models::radarr_models::{Collection, MinimumAvailability, Monitor, Movie}; + use crate::models::radarr_models::{Collection, MinimumAvailability, Movie, MovieMonitor}; use crate::models::servarr_data::radarr::modals::{ AddMovieModal, EditCollectionModal, EditIndexerModal, EditMovieModal, }; @@ -185,7 +185,7 @@ mod test { assert_eq!( add_movie_modal.monitor_list.items, - Vec::from_iter(Monitor::iter()) + Vec::from_iter(MovieMonitor::iter()) ); assert_eq!( add_movie_modal.minimum_availability_list.items, diff --git a/src/models/servarr_data/sonarr/sonarr_data.rs b/src/models/servarr_data/sonarr/sonarr_data.rs index 4af41d6..acf0552 100644 --- a/src/models/servarr_data/sonarr/sonarr_data.rs +++ b/src/models/servarr_data/sonarr/sonarr_data.rs @@ -102,6 +102,13 @@ pub enum ActiveSonarrBlock { AddSeriesPrompt, AddSeriesSearchInput, AddSeriesSearchResults, + AddSeriesSelectLanguageProfile, + AddSeriesSelectMonitor, + AddSeriesSelectQualityProfile, + AddSeriesSelectRootFolder, + AddSeriesSelectSeriesType, + AddSeriesTagsInput, + AddSeriesToggleUseSeasonFolder, AllIndexerSettingsPrompt, AutomaticallySearchEpisodePrompt, AutomaticallySearchSeasonPrompt, diff --git a/src/network/radarr_network.rs b/src/network/radarr_network.rs index cbf8ae6..3e3c124 100644 --- a/src/network/radarr_network.rs +++ b/src/network/radarr_network.rs @@ -7,11 +7,11 @@ use serde_json::{json, Value}; use urlencoding::encode; use crate::models::radarr_models::{ - AddMovieBody, AddMovieSearchResult, AddOptions, BlocklistResponse, Collection, CollectionMovie, - Credit, CreditType, DeleteMovieParams, DownloadRecord, DownloadsResponse, EditCollectionParams, - EditIndexerParams, EditMovieParams, IndexerSettings, IndexerTestResult, Movie, MovieCommandBody, - MovieHistoryItem, RadarrRelease, RadarrReleaseDownloadBody, RadarrSerdeable, RadarrTask, - RadarrTaskName, SystemStatus, + AddMovieBody, AddMovieOptions, AddMovieSearchResult, BlocklistResponse, Collection, + CollectionMovie, Credit, CreditType, DeleteMovieParams, DownloadRecord, DownloadsResponse, + EditCollectionParams, EditIndexerParams, EditMovieParams, IndexerSettings, IndexerTestResult, + Movie, MovieCommandBody, MovieHistoryItem, RadarrRelease, RadarrReleaseDownloadBody, + RadarrSerdeable, RadarrTask, RadarrTaskName, SystemStatus, }; use crate::models::servarr_data::modals::IndexerTestResultModalItem; use crate::models::servarr_data::radarr::modals::{ @@ -365,7 +365,7 @@ impl<'a, 'b> Network<'a, 'b> { monitored: true, quality_profile_id, tags: tag_ids_vec, - add_options: AddOptions { + add_options: AddMovieOptions { monitor, search_for_movie: true, }, diff --git a/src/network/radarr_network_tests.rs b/src/network/radarr_network_tests.rs index be349a0..5093477 100644 --- a/src/network/radarr_network_tests.rs +++ b/src/network/radarr_network_tests.rs @@ -15,8 +15,8 @@ mod test { use crate::app::ServarrConfig; use crate::models::radarr_models::{ - BlocklistItem, BlocklistItemMovie, CollectionMovie, MediaInfo, MinimumAvailability, Monitor, - MovieCollection, MovieFile, Rating, RatingsList, + BlocklistItem, BlocklistItemMovie, CollectionMovie, MediaInfo, MinimumAvailability, + MovieCollection, MovieFile, MovieMonitor, Rating, RatingsList, }; use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::models::servarr_models::{ @@ -3450,7 +3450,7 @@ mod test { .set_items(vec!["HD - 1080p".to_owned()]); add_movie_modal .monitor_list - .set_items(Vec::from_iter(Monitor::iter())); + .set_items(Vec::from_iter(MovieMonitor::iter())); add_movie_modal .minimum_availability_list .set_items(Vec::from_iter(MinimumAvailability::iter())); @@ -3521,7 +3521,7 @@ mod test { monitored: true, quality_profile_id: 2222, tags: vec![1, 2], - add_options: AddOptions { + add_options: AddMovieOptions { monitor: "movieOnly".to_owned(), search_for_movie: true, }, @@ -3597,7 +3597,7 @@ mod test { .set_items(vec!["HD - 1080p".to_owned()]); add_movie_modal .monitor_list - .set_items(Vec::from_iter(Monitor::iter())); + .set_items(Vec::from_iter(MovieMonitor::iter())); add_movie_modal .minimum_availability_list .set_items(Vec::from_iter(MinimumAvailability::iter()));