feat: Fixed the Radarr downloads tab to display more than 10 downloads at a time and added a new --count flag to the CLI for specifying the number of downloads to return

This commit is contained in:
2025-07-13 15:04:39 -06:00
parent cb4cd93bcd
commit ef5e702255
8 changed files with 85 additions and 28 deletions
+1 -1
View File
@@ -284,7 +284,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
sync_network_rx.recv().await.unwrap(), sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetDownloads.into() RadarrEvent::GetDownloads(500).into()
); );
assert_eq!( assert_eq!(
sync_network_rx.recv().await.unwrap(), sync_network_rx.recv().await.unwrap(),
+3 -3
View File
@@ -40,7 +40,7 @@ impl App<'_> {
} }
ActiveRadarrBlock::Downloads => { ActiveRadarrBlock::Downloads => {
self self
.dispatch_network_event(RadarrEvent::GetDownloads.into()) .dispatch_network_event(RadarrEvent::GetDownloads(500).into())
.await; .await;
} }
ActiveRadarrBlock::RootFolders => { ActiveRadarrBlock::RootFolders => {
@@ -59,7 +59,7 @@ impl App<'_> {
.dispatch_network_event(RadarrEvent::GetMovies.into()) .dispatch_network_event(RadarrEvent::GetMovies.into())
.await; .await;
self self
.dispatch_network_event(RadarrEvent::GetDownloads.into()) .dispatch_network_event(RadarrEvent::GetDownloads(500).into())
.await; .await;
} }
ActiveRadarrBlock::Indexers => { ActiveRadarrBlock::Indexers => {
@@ -201,7 +201,7 @@ impl App<'_> {
.dispatch_network_event(RadarrEvent::GetRootFolders.into()) .dispatch_network_event(RadarrEvent::GetRootFolders.into())
.await; .await;
self self
.dispatch_network_event(RadarrEvent::GetDownloads.into()) .dispatch_network_event(RadarrEvent::GetDownloads(500).into())
.await; .await;
self self
.dispatch_network_event(RadarrEvent::GetDiskSpace.into()) .dispatch_network_event(RadarrEvent::GetDiskSpace.into())
+8 -8
View File
@@ -140,7 +140,7 @@ mod tests {
assert!(app.is_loading); assert!(app.is_loading);
assert_eq!( assert_eq!(
sync_network_rx.recv().await.unwrap(), sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetDownloads.into() RadarrEvent::GetDownloads(500).into()
); );
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
assert_eq!(app.tick_count, 0); assert_eq!(app.tick_count, 0);
@@ -186,7 +186,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
sync_network_rx.recv().await.unwrap(), sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetDownloads.into() RadarrEvent::GetDownloads(500).into()
); );
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
assert_eq!(app.tick_count, 0); assert_eq!(app.tick_count, 0);
@@ -591,7 +591,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
sync_network_rx.recv().await.unwrap(), sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetDownloads.into() RadarrEvent::GetDownloads(500).into()
); );
assert_eq!( assert_eq!(
sync_network_rx.recv().await.unwrap(), sync_network_rx.recv().await.unwrap(),
@@ -625,7 +625,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
sync_network_rx.recv().await.unwrap(), sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetDownloads.into() RadarrEvent::GetDownloads(500).into()
); );
assert_eq!( assert_eq!(
sync_network_rx.recv().await.unwrap(), sync_network_rx.recv().await.unwrap(),
@@ -650,7 +650,7 @@ mod tests {
assert_eq!( assert_eq!(
sync_network_rx.recv().await.unwrap(), sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetDownloads.into() RadarrEvent::GetDownloads(500).into()
); );
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
} }
@@ -675,7 +675,7 @@ mod tests {
assert_eq!( assert_eq!(
sync_network_rx.recv().await.unwrap(), sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetDownloads.into() RadarrEvent::GetDownloads(500).into()
); );
assert!(app.should_refresh); assert!(app.should_refresh);
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
@@ -692,7 +692,7 @@ mod tests {
assert_eq!( assert_eq!(
sync_network_rx.recv().await.unwrap(), sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetDownloads.into() RadarrEvent::GetDownloads(500).into()
); );
assert!(app.is_loading); assert!(app.is_loading);
assert!(app.should_refresh); assert!(app.should_refresh);
@@ -722,7 +722,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
sync_network_rx.recv().await.unwrap(), sync_network_rx.recv().await.unwrap(),
RadarrEvent::GetDownloads.into() RadarrEvent::GetDownloads(500).into()
); );
assert!(app.is_loading); assert!(app.is_loading);
} }
+6 -3
View File
@@ -23,7 +23,10 @@ pub enum RadarrListCommand {
#[command(about = "List all Radarr collections")] #[command(about = "List all Radarr collections")]
Collections, Collections,
#[command(about = "List all active downloads in Radarr")] #[command(about = "List all active downloads in Radarr")]
Downloads, Downloads {
#[arg(long, help = "How many downloads to fetch", default_value_t = 500)]
count: u64,
},
#[command(about = "List disk space details for all provisioned root folders in Radarr")] #[command(about = "List disk space details for all provisioned root folders in Radarr")]
DiskSpace, DiskSpace,
#[command(about = "List all Radarr indexers")] #[command(about = "List all Radarr indexers")]
@@ -104,10 +107,10 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, RadarrListCommand> for RadarrListCommandH
.await?; .await?;
serde_json::to_string_pretty(&resp)? serde_json::to_string_pretty(&resp)?
} }
RadarrListCommand::Downloads => { RadarrListCommand::Downloads { count } => {
let resp = self let resp = self
.network .network
.handle_network_event(RadarrEvent::GetDownloads.into()) .handle_network_event(RadarrEvent::GetDownloads(count).into())
.await?; .await?;
serde_json::to_string_pretty(&resp)? serde_json::to_string_pretty(&resp)?
} }
+47 -2
View File
@@ -29,7 +29,6 @@ mod tests {
#[values( #[values(
"blocklist", "blocklist",
"collections", "collections",
"downloads",
"disk-space", "disk-space",
"indexers", "indexers",
"movies", "movies",
@@ -59,6 +58,15 @@ mod tests {
); );
} }
#[test]
fn test_list_downloads_count_flag_requires_arguments() {
let result =
Cli::command().try_get_matches_from(["managarr", "radarr", "list", "downloads", "--count"]);
assert!(result.is_err());
assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidValue);
}
#[test] #[test]
fn test_list_logs_events_flag_requires_arguments() { fn test_list_logs_events_flag_requires_arguments() {
let result = let result =
@@ -87,6 +95,18 @@ mod tests {
} }
} }
#[test]
fn test_list_downloads_default_values() {
let expected_args = RadarrListCommand::Downloads { count: 500 };
let result = Cli::try_parse_from(["managarr", "radarr", "list", "downloads"]);
assert!(result.is_ok());
if let Some(Command::Radarr(RadarrCommand::List(refresh_command))) = result.unwrap().command {
assert_eq!(refresh_command, expected_args);
}
}
#[test] #[test]
fn test_list_logs_default_values() { fn test_list_logs_default_values() {
let expected_args = RadarrListCommand::Logs { let expected_args = RadarrListCommand::Logs {
@@ -122,7 +142,6 @@ mod tests {
#[rstest] #[rstest]
#[case(RadarrListCommand::Blocklist, RadarrEvent::GetBlocklist)] #[case(RadarrListCommand::Blocklist, RadarrEvent::GetBlocklist)]
#[case(RadarrListCommand::Collections, RadarrEvent::GetCollections)] #[case(RadarrListCommand::Collections, RadarrEvent::GetCollections)]
#[case(RadarrListCommand::Downloads, RadarrEvent::GetDownloads)]
#[case(RadarrListCommand::DiskSpace, RadarrEvent::GetDiskSpace)] #[case(RadarrListCommand::DiskSpace, RadarrEvent::GetDiskSpace)]
#[case(RadarrListCommand::Indexers, RadarrEvent::GetIndexers)] #[case(RadarrListCommand::Indexers, RadarrEvent::GetIndexers)]
#[case(RadarrListCommand::Movies, RadarrEvent::GetMovies)] #[case(RadarrListCommand::Movies, RadarrEvent::GetMovies)]
@@ -182,6 +201,32 @@ mod tests {
assert!(result.is_ok()); assert!(result.is_ok());
} }
#[tokio::test]
async fn test_handle_list_downloads_command() {
let expected_count = 1000;
let mut mock_network = MockNetworkTrait::new();
mock_network
.expect_handle_network_event()
.with(eq::<NetworkEvent>(
RadarrEvent::GetDownloads(expected_count).into(),
))
.times(1)
.returning(|_| {
Ok(Serdeable::Radarr(RadarrSerdeable::Value(
json!({"testResponse": "response"}),
)))
});
let app_arc = Arc::new(Mutex::new(App::test_default()));
let list_downloads_command = RadarrListCommand::Downloads { count: 1000 };
let result =
RadarrListCommandHandler::with(&app_arc, list_downloads_command, &mut mock_network)
.handle()
.await;
assert!(result.is_ok());
}
#[tokio::test] #[tokio::test]
async fn test_handle_list_logs_command() { async fn test_handle_list_logs_command() {
let expected_events = 1000; let expected_events = 1000;
+1 -1
View File
@@ -102,7 +102,7 @@ mod tests {
} }
#[test] #[test]
fn test_list_downloads_events_flag_requires_arguments() { fn test_list_downloads_count_flag_requires_arguments() {
let result = let result =
Cli::command().try_get_matches_from(["managarr", "sonarr", "list", "downloads", "--count"]); Cli::command().try_get_matches_from(["managarr", "sonarr", "list", "downloads", "--count"]);
+15 -6
View File
@@ -49,7 +49,7 @@ pub enum RadarrEvent {
EditMovie(EditMovieParams), EditMovie(EditMovieParams),
GetBlocklist, GetBlocklist,
GetCollections, GetCollections,
GetDownloads, GetDownloads(u64),
GetHostConfig, GetHostConfig,
GetIndexers, GetIndexers,
GetAllIndexerSettings, GetAllIndexerSettings,
@@ -87,7 +87,7 @@ impl NetworkResource for RadarrEvent {
RadarrEvent::DeleteBlocklistItem(_) => "/blocklist", RadarrEvent::DeleteBlocklistItem(_) => "/blocklist",
RadarrEvent::GetBlocklist => "/blocklist?page=1&pageSize=10000", RadarrEvent::GetBlocklist => "/blocklist?page=1&pageSize=10000",
RadarrEvent::GetCollections | RadarrEvent::EditCollection(_) => "/collection", RadarrEvent::GetCollections | RadarrEvent::EditCollection(_) => "/collection",
RadarrEvent::GetDownloads | RadarrEvent::DeleteDownload(_) => "/queue", RadarrEvent::GetDownloads(_) | RadarrEvent::DeleteDownload(_) => "/queue",
RadarrEvent::GetHostConfig | RadarrEvent::GetSecurityConfig => "/config/host", RadarrEvent::GetHostConfig | RadarrEvent::GetSecurityConfig => "/config/host",
RadarrEvent::GetIndexers | RadarrEvent::EditIndexer(_) | RadarrEvent::DeleteIndexer(_) => { RadarrEvent::GetIndexers | RadarrEvent::EditIndexer(_) | RadarrEvent::DeleteIndexer(_) => {
"/indexer" "/indexer"
@@ -196,7 +196,10 @@ impl Network<'_, '_> {
.map(RadarrSerdeable::from), .map(RadarrSerdeable::from),
RadarrEvent::GetBlocklist => self.get_radarr_blocklist().await.map(RadarrSerdeable::from), RadarrEvent::GetBlocklist => self.get_radarr_blocklist().await.map(RadarrSerdeable::from),
RadarrEvent::GetCollections => self.get_collections().await.map(RadarrSerdeable::from), RadarrEvent::GetCollections => self.get_collections().await.map(RadarrSerdeable::from),
RadarrEvent::GetDownloads => self.get_radarr_downloads().await.map(RadarrSerdeable::from), RadarrEvent::GetDownloads(count) => self
.get_radarr_downloads(count)
.await
.map(RadarrSerdeable::from),
RadarrEvent::GetHostConfig => self RadarrEvent::GetHostConfig => self
.get_radarr_host_config() .get_radarr_host_config()
.await .await
@@ -1036,12 +1039,18 @@ impl Network<'_, '_> {
.await .await
} }
async fn get_radarr_downloads(&mut self) -> Result<DownloadsResponse> { async fn get_radarr_downloads(&mut self, count: u64) -> Result<DownloadsResponse> {
info!("Fetching Radarr downloads"); info!("Fetching Radarr downloads");
let event = RadarrEvent::GetDownloads; let event = RadarrEvent::GetDownloads(count);
let request_props = self let request_props = self
.request_props_from(event, RequestMethod::Get, None::<()>, None, None) .request_props_from(
event,
RequestMethod::Get,
None::<()>,
None,
Some(format!("pageSize={count}")),
)
.await; .await;
self self
+4 -4
View File
@@ -198,7 +198,7 @@ mod test {
#[rstest] #[rstest]
fn test_resource_queue( fn test_resource_queue(
#[values(RadarrEvent::GetDownloads, RadarrEvent::DeleteDownload(0))] event: RadarrEvent, #[values(RadarrEvent::GetDownloads(0), RadarrEvent::DeleteDownload(0))] event: RadarrEvent,
) { ) {
assert_str_eq!(event.resource(), "/queue"); assert_str_eq!(event.resource(), "/queue");
} }
@@ -1859,15 +1859,15 @@ mod test {
None, None,
Some(downloads_response_json), Some(downloads_response_json),
None, None,
RadarrEvent::GetDownloads, RadarrEvent::GetDownloads(500),
None,
None, None,
Some("pageSize=500"),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::DownloadsResponse(downloads) = network if let RadarrSerdeable::DownloadsResponse(downloads) = network
.handle_radarr_event(RadarrEvent::GetDownloads) .handle_radarr_event(RadarrEvent::GetDownloads(500))
.await .await
.unwrap() .unwrap()
{ {