feat: add download detection job with Prowlarr integration
For each series with missing volumes and an approved metadata link, calls Prowlarr to find available matching releases and stores them in a report (no auto-download). Includes per-series detail page, Telegram notifications with per-event toggles, and stats display in the jobs table. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -51,6 +51,10 @@ pub struct EventToggles {
|
||||
pub reading_status_push_completed: bool,
|
||||
#[serde(default = "default_true")]
|
||||
pub reading_status_push_failed: bool,
|
||||
#[serde(default = "default_true")]
|
||||
pub download_detection_completed: bool,
|
||||
#[serde(default = "default_true")]
|
||||
pub download_detection_failed: bool,
|
||||
}
|
||||
|
||||
fn default_true() -> bool {
|
||||
@@ -75,6 +79,8 @@ fn default_events() -> EventToggles {
|
||||
reading_status_match_failed: true,
|
||||
reading_status_push_completed: true,
|
||||
reading_status_push_failed: true,
|
||||
download_detection_completed: true,
|
||||
download_detection_failed: true,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,6 +286,16 @@ pub enum NotificationEvent {
|
||||
library_name: Option<String>,
|
||||
error: String,
|
||||
},
|
||||
// Download detection (Prowlarr search for missing volumes)
|
||||
DownloadDetectionCompleted {
|
||||
library_name: Option<String>,
|
||||
total_series: i32,
|
||||
found: i64,
|
||||
},
|
||||
DownloadDetectionFailed {
|
||||
library_name: Option<String>,
|
||||
error: String,
|
||||
},
|
||||
}
|
||||
|
||||
/// Classify an indexer job_type string into the right event constructor category.
|
||||
@@ -557,6 +573,37 @@ fn format_event(event: &NotificationEvent) -> String {
|
||||
]
|
||||
.join("\n")
|
||||
}
|
||||
NotificationEvent::DownloadDetectionCompleted {
|
||||
library_name,
|
||||
total_series,
|
||||
found,
|
||||
} => {
|
||||
let lib = library_name.as_deref().unwrap_or("All libraries");
|
||||
[
|
||||
format!("✅ <b>Download detection completed</b>"),
|
||||
String::new(),
|
||||
format!("📂 <b>Library:</b> {lib}"),
|
||||
String::new(),
|
||||
format!("📊 <b>Results</b>"),
|
||||
format!(" 📥 Available: <b>{found}</b> / <b>{total_series}</b> series"),
|
||||
]
|
||||
.join("\n")
|
||||
}
|
||||
NotificationEvent::DownloadDetectionFailed {
|
||||
library_name,
|
||||
error,
|
||||
} => {
|
||||
let lib = library_name.as_deref().unwrap_or("All libraries");
|
||||
let err = truncate(error, 200);
|
||||
[
|
||||
format!("🚨 <b>Download detection failed</b>"),
|
||||
String::new(),
|
||||
format!("📂 <b>Library:</b> {lib}"),
|
||||
String::new(),
|
||||
format!("💬 <code>{err}</code>"),
|
||||
]
|
||||
.join("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -601,6 +648,8 @@ fn is_event_enabled(config: &TelegramConfig, event: &NotificationEvent) -> bool
|
||||
NotificationEvent::ReadingStatusMatchFailed { .. } => config.events.reading_status_match_failed,
|
||||
NotificationEvent::ReadingStatusPushCompleted { .. } => config.events.reading_status_push_completed,
|
||||
NotificationEvent::ReadingStatusPushFailed { .. } => config.events.reading_status_push_failed,
|
||||
NotificationEvent::DownloadDetectionCompleted { .. } => config.events.download_detection_completed,
|
||||
NotificationEvent::DownloadDetectionFailed { .. } => config.events.download_detection_failed,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user