feat(readarr): trigger automatic author searches and expose the command on the CLI

Posts the AuthorSearch command to the command endpoint with the author ID, queueing an indexer search for that author. The response is returned verbatim and no app state is mutated.

Introduces ReadarrCommandBody, the request body shared by the author and book command calls. Both ID fields are omitted from the payload when absent rather than sent as null.
This commit is contained in:
Dark-Alex-17 committed 2026-08-27 10:35:04 -06:00
1 parent f896b65fd9
commit e9b9aa3a14
8 files changed
+292 -2

No files matched your search

@@ -0,0 +1,72 @@
use std::sync::Arc;
use anyhow::Result;
use clap::Subcommand;
use tokio::sync::Mutex;
use crate::{
app::App,
cli::{CliCommandHandler, Command},
network::{NetworkTrait, readarr_network::ReadarrEvent},
};
use super::ReadarrCommand;
#[cfg(test)]
#[path = "trigger_automatic_search_command_handler_tests.rs"]
mod trigger_automatic_search_command_handler_tests;
#[derive(Debug, Clone, PartialEq, Eq, Subcommand)]
pub enum ReadarrTriggerAutomaticSearchCommand {
#[command(about = "Trigger an automatic search for the author with the specified ID")]
Author {
#[arg(
long,
help = "The ID of the author you want to trigger an automatic search for",
required = true
)]
author_id: i64,
},
}
impl From<ReadarrTriggerAutomaticSearchCommand> for Command {
fn from(value: ReadarrTriggerAutomaticSearchCommand) -> Self {
Command::Readarr(ReadarrCommand::TriggerAutomaticSearch(value))
}
}
pub(super) struct ReadarrTriggerAutomaticSearchCommandHandler<'a, 'b> {
_app: &'a Arc<Mutex<App<'b>>>,
command: ReadarrTriggerAutomaticSearchCommand,
network: &'a mut dyn NetworkTrait,
}
impl<'a, 'b> CliCommandHandler<'a, 'b, ReadarrTriggerAutomaticSearchCommand>
for ReadarrTriggerAutomaticSearchCommandHandler<'a, 'b>
{
fn with(
_app: &'a Arc<Mutex<App<'b>>>,
command: ReadarrTriggerAutomaticSearchCommand,
network: &'a mut dyn NetworkTrait,
) -> Self {
ReadarrTriggerAutomaticSearchCommandHandler {
_app,
command,
network,
}
}
async fn handle(self) -> Result<String> {
let result = match self.command {
ReadarrTriggerAutomaticSearchCommand::Author { author_id } => {
let resp = self
.network
.handle_network_event(ReadarrEvent::TriggerAutomaticAuthorSearch(author_id).into())
.await?;
serde_json::to_string_pretty(&resp)?
}
};
Ok(result)
}
}