feat: ntfy notifications for imported, needs-decision, broken (#96)
This commit was merged in pull request #96.
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
//! arr — reconcile loop and process entry point. See DESIGN.md §8.
|
||||
|
||||
mod attention;
|
||||
mod broken;
|
||||
mod config;
|
||||
mod grab;
|
||||
mod import;
|
||||
mod indexers;
|
||||
mod jellyfin;
|
||||
mod notify;
|
||||
mod reaper;
|
||||
pub mod reconcile;
|
||||
mod rss;
|
||||
@@ -18,9 +21,12 @@ use arr_api::{AppState, Upstreams};
|
||||
use arr_compat::CompatState;
|
||||
use arr_db::Db;
|
||||
use arr_meta::TmdbClient;
|
||||
use attention::AttentionAction;
|
||||
use broken::BrokenAction;
|
||||
use config::Config;
|
||||
use grab::{GrabAction, SeedingLimits, SeedingRules};
|
||||
use import::ImportAction;
|
||||
use notify::Notifier;
|
||||
use reaper::ReaperAction;
|
||||
use reconcile::{ReconcileLoop, Tick};
|
||||
use rss::RssAction;
|
||||
@@ -85,6 +91,8 @@ enum Error {
|
||||
Transmission(#[from] arr_dl::Error),
|
||||
#[error("jellyfin client: {0}")]
|
||||
Jellyfin(#[from] jellyfin::Error),
|
||||
#[error("ntfy client: {0}")]
|
||||
Notify(#[from] notify::NotifyError),
|
||||
#[error("bind {addr}: {source}")]
|
||||
Bind {
|
||||
addr: std::net::SocketAddr,
|
||||
@@ -111,7 +119,8 @@ async fn run() -> Result<(), Error> {
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let reconcile = reconcile_loop(&database, &config, &transmission, tmdb.as_ref())?;
|
||||
let notifier = Notifier::new(config.ntfy_url.clone())?;
|
||||
let reconcile = reconcile_loop(&database, &config, &transmission, tmdb.as_ref(), ¬ifier)?;
|
||||
|
||||
// Jellyseerr's Radarr shim (DESIGN.md §9.4) reads the same database and
|
||||
// needs its own TMDB client for `movie/lookup`.
|
||||
@@ -176,6 +185,7 @@ fn reconcile_loop(
|
||||
config: &Config,
|
||||
transmission: &arr_dl::TransmissionClient,
|
||||
tmdb: Option<&Arc<TmdbClient>>,
|
||||
notifier: &Notifier,
|
||||
) -> Result<ReconcileLoop, Error> {
|
||||
let mut reconcile = ReconcileLoop::new(database.clone());
|
||||
let seeding = SeedingRules::new(
|
||||
@@ -252,8 +262,42 @@ fn reconcile_loop(
|
||||
// imported on this tick.
|
||||
reconcile = reconcile.register(
|
||||
Tick::Reconcile,
|
||||
ImportAction::new(transmission.clone(), arr_probe::Prober::new(), jellyfin),
|
||||
ImportAction::new(
|
||||
transmission.clone(),
|
||||
arr_probe::Prober::new(),
|
||||
jellyfin,
|
||||
notifier.clone(),
|
||||
config.ntfy_operator_topic.clone(),
|
||||
),
|
||||
);
|
||||
|
||||
// §9.5 *needs a decision* and *broken* both go to the operator alone;
|
||||
// without a topic configured there is nowhere to send them.
|
||||
if let Some(operator_topic) = &config.ntfy_operator_topic {
|
||||
reconcile = reconcile.register(
|
||||
Tick::Reconcile,
|
||||
AttentionAction::new(notifier.clone(), operator_topic.clone()),
|
||||
);
|
||||
let broken_upstreams = broken::Upstreams {
|
||||
prowlarr_url: config.prowlarr_url.clone(),
|
||||
prowlarr_api_key: config.prowlarr_api_key.clone(),
|
||||
transmission_url: config.transmission_url.clone(),
|
||||
tmdb_url: config
|
||||
.tmdb_url
|
||||
.clone()
|
||||
.unwrap_or_else(|| arr_api::DEFAULT_TMDB_URL.to_string()),
|
||||
tmdb_api_key: config.tmdb_api_key.clone(),
|
||||
};
|
||||
reconcile = reconcile.register(
|
||||
Tick::Reconcile,
|
||||
BrokenAction::new(broken_upstreams, notifier.clone(), operator_topic.clone()),
|
||||
);
|
||||
} else {
|
||||
tracing::warn!(
|
||||
"ARR_NTFY_OPERATOR_TOPIC is not configured: needs-a-decision and broken notifications are disabled"
|
||||
);
|
||||
}
|
||||
|
||||
Ok(reconcile.register(Tick::Reaper, ReaperAction::new(transmission.clone())))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user