feat(cli): Added sonarr support for listing downloads, listing quality profiles, and fetching detailed information about an episode

This commit is contained in:
2024-11-15 18:41:13 -07:00
parent e14b7072c6
commit 003f319385
10 changed files with 201 additions and 11 deletions
+2 -2
View File
@@ -191,7 +191,7 @@ impl<'a, 'b> Network<'a, 'b> {
.map(RadarrSerdeable::from),
RadarrEvent::GetBlocklist => self.get_radarr_blocklist().await.map(RadarrSerdeable::from),
RadarrEvent::GetCollections => self.get_collections().await.map(RadarrSerdeable::from),
RadarrEvent::GetDownloads => self.get_downloads().await.map(RadarrSerdeable::from),
RadarrEvent::GetDownloads => self.get_radarr_downloads().await.map(RadarrSerdeable::from),
RadarrEvent::GetHostConfig => self.get_host_config().await.map(RadarrSerdeable::from),
RadarrEvent::GetIndexers => self.get_indexers().await.map(RadarrSerdeable::from),
RadarrEvent::GetLogs(events) => self
@@ -1363,7 +1363,7 @@ impl<'a, 'b> Network<'a, 'b> {
.await
}
async fn get_downloads(&mut self) -> Result<DownloadsResponse> {
async fn get_radarr_downloads(&mut self) -> Result<DownloadsResponse> {
info!("Fetching Radarr downloads");
let event = RadarrEvent::GetDownloads;
+1 -1
View File
@@ -2182,7 +2182,7 @@ mod test {
}
#[tokio::test]
async fn test_handle_get_downloads_event() {
async fn test_handle_get_radarr_downloads_event() {
let downloads_response_json = json!({
"records": [{
"title": "Test Download Title",
+24 -2
View File
@@ -10,8 +10,8 @@ use crate::{
models::{
servarr_data::sonarr::{modals::EpisodeDetailsModal, sonarr_data::ActiveSonarrBlock},
sonarr_models::{
BlocklistResponse, DownloadRecord, Episode, LogResponse, QualityProfile, Series,
SonarrSerdeable, SystemStatus,
BlocklistResponse, DownloadRecord, DownloadsResponse, Episode, LogResponse, QualityProfile,
Series, SonarrSerdeable, SystemStatus,
},
HorizontallyScrollableText, Route, Scrollable, ScrollableText,
},
@@ -29,6 +29,7 @@ pub enum SonarrEvent {
ClearBlocklist,
DeleteBlocklistItem(Option<i64>),
GetBlocklist,
GetDownloads,
GetEpisodeDetails(Option<i64>),
GetEpisodes(Option<i64>),
GetLogs(Option<u64>),
@@ -44,6 +45,7 @@ impl NetworkResource for SonarrEvent {
SonarrEvent::ClearBlocklist => "/blocklist/bulk",
SonarrEvent::DeleteBlocklistItem(_) => "/blocklist",
SonarrEvent::GetBlocklist => "/blocklist?page=1&pageSize=10000",
SonarrEvent::GetDownloads => "/queue",
SonarrEvent::GetEpisodes(_) | SonarrEvent::GetEpisodeDetails(_) => "/episode",
SonarrEvent::GetLogs(_) => "/log",
SonarrEvent::GetQualityProfiles => "/qualityprofile",
@@ -75,6 +77,7 @@ impl<'a, 'b> Network<'a, 'b> {
.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
.get_episodes(series_id)
.await
@@ -200,6 +203,25 @@ impl<'a, 'b> Network<'a, 'b> {
.await
}
async fn get_sonarr_downloads(&mut self) -> Result<DownloadsResponse> {
info!("Fetching Sonarr downloads");
let event = SonarrEvent::GetDownloads;
let request_props = self
.request_props_from(event, RequestMethod::Get, None::<()>, None, None)
.await;
self
.handle_request::<(), DownloadsResponse>(request_props, |queue_response, mut app| {
app
.data
.sonarr_data
.downloads
.set_items(queue_response.records);
})
.await
}
async fn get_episodes(&mut self, series_id: Option<i64>) -> Result<Vec<Episode>> {
let event = SonarrEvent::GetEpisodes(series_id);
let (id, series_id_param) = self.extract_series_id(series_id).await;
+68 -2
View File
@@ -23,8 +23,8 @@ mod test {
use crate::app::App;
use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock;
use crate::models::sonarr_models::{
BlocklistItem, DownloadRecord, Episode, EpisodeFile, Language, LogResponse, MediaInfo,
QualityProfile,
BlocklistItem, DownloadRecord, DownloadsResponse, Episode, EpisodeFile, Language, LogResponse,
MediaInfo, QualityProfile,
};
use crate::models::sonarr_models::{BlocklistResponse, Quality};
use crate::models::sonarr_models::{QualityWrapper, SystemStatus};
@@ -142,6 +142,7 @@ mod test {
#[case(SonarrEvent::DeleteBlocklistItem(None), "/blocklist")]
#[case(SonarrEvent::HealthCheck, "/health")]
#[case(SonarrEvent::GetBlocklist, "/blocklist?page=1&pageSize=10000")]
#[case(SonarrEvent::GetDownloads, "/queue")]
#[case(SonarrEvent::GetLogs(Some(500)), "/log")]
#[case(SonarrEvent::GetQualityProfiles, "/qualityprofile")]
#[case(SonarrEvent::GetStatus, "/system/status")]
@@ -322,6 +323,49 @@ mod test {
}
}
#[tokio::test]
async fn test_handle_get_sonarr_downloads_event() {
let downloads_response_json = json!({
"records": [{
"title": "Test Download Title",
"status": "downloading",
"id": 1,
"episodeId": 1,
"size": 3543348019u64,
"sizeleft": 1771674009,
"outputPath": "/nfs/tv/Test show/season 1/",
"indexer": "kickass torrents",
"downloadClient": "transmission",
}]
});
let response: DownloadsResponse =
serde_json::from_value(downloads_response_json.clone()).unwrap();
let (async_server, app_arc, _server) = mock_servarr_api(
RequestMethod::Get,
None,
Some(downloads_response_json),
None,
SonarrEvent::GetDownloads,
None,
None,
)
.await;
let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let SonarrSerdeable::DownloadsResponse(downloads) = network
.handle_sonarr_event(SonarrEvent::GetDownloads)
.await
.unwrap()
{
async_server.assert_async().await;
assert_eq!(
app_arc.lock().await.data.sonarr_data.downloads.items,
downloads_response().records
);
assert_eq!(downloads, response);
}
}
#[tokio::test]
async fn test_handle_get_sonarr_healthcheck_event() {
let (async_server, app_arc, _server) = mock_servarr_api(
@@ -1403,6 +1447,28 @@ mod test {
}
}
fn download_record() -> DownloadRecord {
DownloadRecord {
title: "Test Download Title".to_owned(),
status: "downloading".to_owned(),
id: 1,
episode_id: 1,
size: 3543348019,
sizeleft: 1771674009,
output_path: Some(HorizontallyScrollableText::from(
"/nfs/tv/Test show/season 1/",
)),
indexer: "kickass torrents".to_owned(),
download_client: "transmission".to_owned(),
}
}
fn downloads_response() -> DownloadsResponse {
DownloadsResponse {
records: vec![download_record()],
}
}
fn episode() -> Episode {
Episode {
id: 1,