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:
8 files changed
+292
-2
No files matched your search
@@ -4,7 +4,7 @@ use serde_json::{Value, json};
|
||||
|
||||
use crate::models::Route;
|
||||
use crate::models::readarr_models::{
|
||||
AddAuthorBody, AddAuthorSearchResult, Author, DeleteParams, EditAuthorParams,
|
||||
AddAuthorBody, AddAuthorSearchResult, Author, DeleteParams, EditAuthorParams, ReadarrCommandBody,
|
||||
};
|
||||
use crate::models::servarr_data::readarr::readarr_data::ActiveReadarrBlock;
|
||||
use crate::models::stateful_table::StatefulTable;
|
||||
@@ -340,4 +340,25 @@ impl Network<'_, '_> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(in crate::network::readarr_network) async fn trigger_automatic_author_search(
|
||||
&mut self,
|
||||
author_id: i64,
|
||||
) -> Result<Value> {
|
||||
let event = ReadarrEvent::TriggerAutomaticAuthorSearch(author_id);
|
||||
info!("Searching indexers for author with ID: {author_id}");
|
||||
let body = ReadarrCommandBody {
|
||||
name: "AuthorSearch".to_owned(),
|
||||
author_id: Some(author_id),
|
||||
..ReadarrCommandBody::default()
|
||||
};
|
||||
|
||||
let request_props = self
|
||||
.request_props_from(event, RequestMethod::Post, Some(body), None, None)
|
||||
.await;
|
||||
|
||||
self
|
||||
.handle_request::<ReadarrCommandBody, Value>(request_props, |_, _| ())
|
||||
.await
|
||||
}
|
||||
}
|
||||
@@ -757,4 +757,47 @@ mod tests {
|
||||
async_toggle_server.assert_async().await;
|
||||
assert_err!(result);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_handle_trigger_automatic_author_search_event() {
|
||||
let (mock, app, _server) = MockServarrApi::post()
|
||||
.with_request_body(json!({
|
||||
"name": "AuthorSearch",
|
||||
"authorId": 1
|
||||
}))
|
||||
.returns(json!({}))
|
||||
.build_for(ReadarrEvent::TriggerAutomaticAuthorSearch(1))
|
||||
.await;
|
||||
app.lock().await.server_tabs.set_index(3);
|
||||
let mut network = test_network(&app);
|
||||
|
||||
let result = network
|
||||
.handle_readarr_event(ReadarrEvent::TriggerAutomaticAuthorSearch(1))
|
||||
.await;
|
||||
|
||||
mock.assert_async().await;
|
||||
assert_ok!(result);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_handle_trigger_automatic_author_search_event_failure() {
|
||||
let (mock, app, _server) = MockServarrApi::post()
|
||||
.with_request_body(json!({
|
||||
"name": "AuthorSearch",
|
||||
"authorId": 1
|
||||
}))
|
||||
.returns(json!({"name": "AuthorSearch", "status": "queued"}))
|
||||
.status(500)
|
||||
.build_for(ReadarrEvent::TriggerAutomaticAuthorSearch(1))
|
||||
.await;
|
||||
app.lock().await.server_tabs.set_index(3);
|
||||
let mut network = test_network(&app);
|
||||
|
||||
let result = network
|
||||
.handle_readarr_event(ReadarrEvent::TriggerAutomaticAuthorSearch(1))
|
||||
.await;
|
||||
|
||||
mock.assert_async().await;
|
||||
assert_err!(result);
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,7 @@ pub enum ReadarrEvent {
|
||||
SearchNewAuthor(String),
|
||||
StartTask(ReadarrTaskName),
|
||||
ToggleAuthorMonitoring(i64),
|
||||
TriggerAutomaticAuthorSearch(i64),
|
||||
}
|
||||
|
||||
impl NetworkResource for ReadarrEvent {
|
||||
@@ -61,7 +62,9 @@ impl NetworkResource for ReadarrEvent {
|
||||
| ReadarrEvent::ListAuthors
|
||||
| ReadarrEvent::ToggleAuthorMonitoring(_) => "/author",
|
||||
ReadarrEvent::SearchNewAuthor(_) => "/author/lookup",
|
||||
ReadarrEvent::GetQueuedEvents | ReadarrEvent::StartTask(_) => "/command",
|
||||
ReadarrEvent::GetQueuedEvents
|
||||
| ReadarrEvent::StartTask(_)
|
||||
| ReadarrEvent::TriggerAutomaticAuthorSearch(_) => "/command",
|
||||
ReadarrEvent::GetHostConfig | ReadarrEvent::GetSecurityConfig => "/config/host",
|
||||
ReadarrEvent::GetDiskSpace => "/diskspace",
|
||||
ReadarrEvent::HealthCheck => "/health",
|
||||
@@ -169,6 +172,10 @@ impl Network<'_, '_> {
|
||||
.toggle_author_monitoring(author_id)
|
||||
.await
|
||||
.map(ReadarrSerdeable::from),
|
||||
ReadarrEvent::TriggerAutomaticAuthorSearch(author_id) => self
|
||||
.trigger_automatic_author_search(author_id)
|
||||
.await
|
||||
.map(ReadarrSerdeable::from),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ mod tests {
|
||||
#[case(ReadarrEvent::SearchNewAuthor(String::new()), "/author/lookup")]
|
||||
#[case(ReadarrEvent::GetQueuedEvents, "/command")]
|
||||
#[case(ReadarrEvent::StartTask(Default::default()), "/command")]
|
||||
#[case(ReadarrEvent::TriggerAutomaticAuthorSearch(1), "/command")]
|
||||
#[case(ReadarrEvent::GetHostConfig, "/config/host")]
|
||||
#[case(ReadarrEvent::GetSecurityConfig, "/config/host")]
|
||||
#[case(ReadarrEvent::GetDiskSpace, "/diskspace")]
|
||||
|
||||
Reference in new issue
Block a user