diff --git a/src/cli/radarr/mod.rs b/src/cli/radarr/mod.rs index c4b1675..6789380 100644 --- a/src/cli/radarr/mod.rs +++ b/src/cli/radarr/mod.rs @@ -12,7 +12,7 @@ use tokio::sync::Mutex; use crate::app::App; use crate::cli::CliCommandHandler; -use crate::models::radarr_models::{RadarrTaskName, ReleaseDownloadBody}; +use crate::models::radarr_models::{RadarrReleaseDownloadBody, RadarrTaskName}; use crate::network::radarr_network::RadarrEvent; use crate::network::NetworkTrait; use anyhow::Result; @@ -202,7 +202,7 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, RadarrCommand> for RadarrCliHandler<'a, ' indexer_id, movie_id, } => { - let params = ReleaseDownloadBody { + let params = RadarrReleaseDownloadBody { guid, indexer_id, movie_id, diff --git a/src/cli/radarr/radarr_command_tests.rs b/src/cli/radarr/radarr_command_tests.rs index fcb59d2..546dd70 100644 --- a/src/cli/radarr/radarr_command_tests.rs +++ b/src/cli/radarr/radarr_command_tests.rs @@ -261,8 +261,8 @@ mod tests { }, models::{ radarr_models::{ - BlocklistItem, BlocklistResponse, IndexerSettings, RadarrSerdeable, RadarrTaskName, - ReleaseDownloadBody, + BlocklistItem, BlocklistResponse, IndexerSettings, RadarrReleaseDownloadBody, + RadarrSerdeable, RadarrTaskName, }, Serdeable, }, @@ -304,7 +304,7 @@ mod tests { #[tokio::test] async fn test_download_release_command() { - let expected_release_download_body = ReleaseDownloadBody { + let expected_release_download_body = RadarrReleaseDownloadBody { guid: "guid".to_owned(), indexer_id: 1, movie_id: 1, diff --git a/src/models/radarr_models.rs b/src/models/radarr_models.rs index 080ae3f..5675502 100644 --- a/src/models/radarr_models.rs +++ b/src/models/radarr_models.rs @@ -414,7 +414,7 @@ pub struct RatingsList { #[derive(Default, Serialize, Debug, PartialEq, Eq, Clone)] #[serde(rename_all = "camelCase")] -pub struct ReleaseDownloadBody { +pub struct RadarrReleaseDownloadBody { pub guid: String, pub indexer_id: i64, pub movie_id: i64, diff --git a/src/models/sonarr_models.rs b/src/models/sonarr_models.rs index 5758bba..92cd9e8 100644 --- a/src/models/sonarr_models.rs +++ b/src/models/sonarr_models.rs @@ -401,6 +401,19 @@ pub struct SonarrCommandBody { pub episode_ids: Option>, } +#[derive(Default, Serialize, Debug, PartialEq, Eq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct SonarrReleaseDownloadBody { + pub guid: String, + pub indexer_id: i64, + #[serde(skip_serializing_if = "Option::is_none")] + pub series_id: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub episode_id: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub season_number: Option, +} + #[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct SonarrTask { diff --git a/src/network/radarr_network.rs b/src/network/radarr_network.rs index 51b3441..e195118 100644 --- a/src/network/radarr_network.rs +++ b/src/network/radarr_network.rs @@ -10,7 +10,8 @@ use crate::models::radarr_models::{ AddMovieBody, AddMovieSearchResult, AddOptions, BlocklistResponse, Collection, CollectionMovie, Credit, CreditType, DeleteMovieParams, DownloadRecord, DownloadsResponse, EditCollectionParams, EditIndexerParams, EditMovieParams, IndexerSettings, IndexerTestResult, Movie, MovieCommandBody, - MovieHistoryItem, RadarrSerdeable, RadarrTask, RadarrTaskName, ReleaseDownloadBody, SystemStatus, + MovieHistoryItem, RadarrReleaseDownloadBody, RadarrSerdeable, RadarrTask, RadarrTaskName, + SystemStatus, }; use crate::models::servarr_data::modals::IndexerTestResultModalItem; use crate::models::servarr_data::radarr::modals::{ @@ -44,7 +45,7 @@ pub enum RadarrEvent { DeleteMovie(Option), DeleteRootFolder(Option), DeleteTag(i64), - DownloadRelease(Option), + DownloadRelease(Option), EditAllIndexerSettings(Option), EditCollection(Option), EditIndexer(Option), @@ -176,7 +177,7 @@ impl<'a, 'b> Network<'a, 'b> { .await .map(RadarrSerdeable::from), RadarrEvent::DownloadRelease(params) => self - .download_release(params) + .download_radarr_release(params) .await .map(RadarrSerdeable::from), RadarrEvent::EditAllIndexerSettings(params) => self @@ -662,10 +663,13 @@ impl<'a, 'b> Network<'a, 'b> { .await } - async fn download_release(&mut self, params: Option) -> Result { + async fn download_radarr_release( + &mut self, + params: Option, + ) -> Result { let event = RadarrEvent::DownloadRelease(None); let body = if let Some(release_download_body) = params { - info!("Downloading release with params: {release_download_body:?}"); + info!("Downloading Radarr release with params: {release_download_body:?}"); release_download_body } else { let (movie_id, _) = self.extract_movie_id(None).await; @@ -690,7 +694,7 @@ impl<'a, 'b> Network<'a, 'b> { info!("Downloading release: {title}"); - ReleaseDownloadBody { + RadarrReleaseDownloadBody { guid, indexer_id, movie_id, @@ -702,7 +706,7 @@ impl<'a, 'b> Network<'a, 'b> { .await; self - .handle_request::(request_props, |_, _| ()) + .handle_request::(request_props, |_, _| ()) .await } diff --git a/src/network/radarr_network_tests.rs b/src/network/radarr_network_tests.rs index 33e6f1e..75703eb 100644 --- a/src/network/radarr_network_tests.rs +++ b/src/network/radarr_network_tests.rs @@ -4805,7 +4805,7 @@ mod test { } #[tokio::test] - async fn test_handle_download_release_event() { + async fn test_handle_download_radarr_release_event() { let (async_server, app_arc, _server) = mock_servarr_api( RequestMethod::Post, Some(json!({ @@ -4843,7 +4843,7 @@ mod test { } #[tokio::test] - async fn test_handle_download_release_event_uses_provided_params() { + async fn test_handle_download_radarr_release_event_uses_provided_params() { let (async_server, app_arc, _server) = mock_servarr_api( RequestMethod::Post, Some(json!({ @@ -4859,7 +4859,7 @@ mod test { ) .await; let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); - let params = ReleaseDownloadBody { + let params = RadarrReleaseDownloadBody { guid: "1234".to_owned(), indexer_id: 2, movie_id: 1, diff --git a/src/network/sonarr_network.rs b/src/network/sonarr_network.rs index 4603f88..1facb66 100644 --- a/src/network/sonarr_network.rs +++ b/src/network/sonarr_network.rs @@ -19,8 +19,8 @@ use crate::{ }, sonarr_models::{ BlocklistResponse, DownloadRecord, DownloadsResponse, Episode, IndexerSettings, Series, - SonarrCommandBody, SonarrHistoryItem, SonarrHistoryWrapper, SonarrSerdeable, SonarrTask, - SonarrTaskName, SystemStatus, + SonarrCommandBody, SonarrHistoryItem, SonarrHistoryWrapper, SonarrReleaseDownloadBody, + SonarrSerdeable, SonarrTask, SonarrTaskName, SystemStatus, }, stateful_table::StatefulTable, HorizontallyScrollableText, Route, Scrollable, ScrollableText, @@ -44,6 +44,7 @@ pub enum SonarrEvent { DeleteIndexer(Option), DeleteRootFolder(Option), DeleteTag(i64), + DownloadRelease(SonarrReleaseDownloadBody), GetAllIndexerSettings, GetBlocklist, GetDownloads, @@ -86,6 +87,7 @@ impl NetworkResource for SonarrEvent { match &self { SonarrEvent::AddTag(_) | SonarrEvent::DeleteTag(_) | SonarrEvent::GetTags => "/tag", SonarrEvent::ClearBlocklist => "/blocklist/bulk", + SonarrEvent::DownloadRelease(_) => "/release", SonarrEvent::DeleteBlocklistItem(_) => "/blocklist", SonarrEvent::GetAllIndexerSettings => "/config/indexer", SonarrEvent::GetBlocklist => "/blocklist?page=1&pageSize=10000", @@ -167,6 +169,10 @@ impl<'a, 'b> Network<'a, 'b> { .delete_sonarr_tag(tag_id) .await .map(SonarrSerdeable::from), + SonarrEvent::DownloadRelease(sonarr_release_download_body) => self + .download_sonarr_release(sonarr_release_download_body) + .await + .map(SonarrSerdeable::from), SonarrEvent::GetBlocklist => self.get_sonarr_blocklist().await.map(SonarrSerdeable::from), SonarrEvent::GetDownloads => self.get_sonarr_downloads().await.map(SonarrSerdeable::from), SonarrEvent::GetEpisodes(series_id) => self @@ -511,6 +517,28 @@ impl<'a, 'b> Network<'a, 'b> { .await } + async fn download_sonarr_release( + &mut self, + sonarr_release_download_body: SonarrReleaseDownloadBody, + ) -> Result { + let event = SonarrEvent::DownloadRelease(sonarr_release_download_body.clone()); + info!("Downloading Sonarr release with params: {sonarr_release_download_body:?}"); + + let request_props = self + .request_props_from( + event, + RequestMethod::Post, + Some(sonarr_release_download_body), + None, + None, + ) + .await; + + self + .handle_request::(request_props, |_, _| ()) + .await + } + async fn get_all_sonarr_indexer_settings(&mut self) -> Result { info!("Fetching Sonarr indexer settings"); let event = SonarrEvent::GetAllIndexerSettings; diff --git a/src/network/sonarr_network_tests.rs b/src/network/sonarr_network_tests.rs index aa3a254..260d44a 100644 --- a/src/network/sonarr_network_tests.rs +++ b/src/network/sonarr_network_tests.rs @@ -25,7 +25,7 @@ mod test { }; use crate::models::sonarr_models::{ BlocklistItem, DownloadRecord, DownloadsResponse, Episode, EpisodeFile, MediaInfo, - SonarrTaskName, + SonarrReleaseDownloadBody, SonarrTaskName, }; use crate::models::sonarr_models::{ BlocklistResponse, SonarrHistoryData, SonarrHistoryItem, SonarrHistoryWrapper, @@ -599,6 +599,38 @@ mod test { async_server.assert_async().await; } + #[tokio::test] + async fn test_handle_download_sonarr_release_event_uses_provided_params() { + let params = SonarrReleaseDownloadBody { + guid: "1234".to_owned(), + indexer_id: 2, + series_id: Some(1), + ..SonarrReleaseDownloadBody::default() + }; + let (async_server, app_arc, _server) = mock_servarr_api( + RequestMethod::Post, + Some(json!({ + "guid": "1234", + "indexerId": 2, + "seriesId": 1 + })), + Some(json!({})), + None, + SonarrEvent::DownloadRelease(params.clone()), + None, + None, + ) + .await; + let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); + + assert!(network + .handle_sonarr_event(SonarrEvent::DownloadRelease(params)) + .await + .is_ok()); + + async_server.assert_async().await; + } + #[rstest] #[tokio::test] async fn test_handle_get_sonarr_blocklist_event(#[values(true, false)] use_custom_sorting: bool) {