feat: Jellyfin/Plex auto-import via watch queue
Some checks failed
CI / Check / Test (push) Failing after 6m5s
Some checks failed
CI / Check / Test (push) Failing after 6m5s
Webhook ingestion from media servers — movies land in a pending watch queue, user rates and confirms to create diary entries. - domain: WatchEvent, WebhookToken models, MediaServerParser port - adapters: jellyfin + plex parser crates, SQLite + Postgres repos - application: ingest/confirm/dismiss/cleanup use cases, token mgmt - presentation: webhook endpoints (bearer + query param auth), watch queue + integrations settings HTML pages, OpenAPI docs - worker: WatchEventCleanupJob (daily, 30d retention) Movie resolution deferred to confirm — single canonical path through log_review for enrichment, poster fetch, federation.
This commit is contained in:
@@ -2,8 +2,9 @@ use application::ports::{
|
||||
ActivityFeedPageData, BlockedActorEntry, BlockedActorsPageData, BlockedDomainEntry,
|
||||
BlockedDomainsPageData, FollowersPageData, FollowingPageData, HtmlPageContext, HtmlRenderer,
|
||||
ImportMappingPageData, ImportPreviewPageData, ImportPreviewRow, ImportProfileView,
|
||||
ImportRowStatus, ImportUploadPageData, LoginPageData, MovieDetailPageData, NewReviewPageData,
|
||||
ProfilePageData, ProfileSettingsPageData, RegisterPageData, UsersPageData, WatchlistPageData,
|
||||
ImportRowStatus, ImportUploadPageData, IntegrationsPageData, LoginPageData,
|
||||
MovieDetailPageData, NewReviewPageData, ProfilePageData, ProfileSettingsPageData,
|
||||
RegisterPageData, UsersPageData, WatchQueuePageData, WatchlistPageData, WebhookTokenView,
|
||||
};
|
||||
use askama::Template;
|
||||
use chrono::Datelike;
|
||||
@@ -366,6 +367,23 @@ struct ProfileSettingsTemplate<'a> {
|
||||
saved: bool,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "integrations.html")]
|
||||
struct IntegrationsTemplate<'a> {
|
||||
ctx: &'a HtmlPageContext,
|
||||
tokens: &'a [WebhookTokenView],
|
||||
webhook_base_url: &'a str,
|
||||
new_token: Option<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "watch_queue.html")]
|
||||
struct WatchQueueTemplate<'a> {
|
||||
ctx: &'a HtmlPageContext,
|
||||
entries: &'a [application::ports::WatchQueueDisplayEntry],
|
||||
error: Option<&'a str>,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "import_upload.html")]
|
||||
struct ImportUploadTemplate<'a> {
|
||||
@@ -750,4 +768,25 @@ impl HtmlRenderer for AskamaHtmlRenderer {
|
||||
.render()
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
fn render_integrations_page(&self, data: IntegrationsPageData) -> Result<String, String> {
|
||||
IntegrationsTemplate {
|
||||
ctx: &data.ctx,
|
||||
tokens: &data.tokens,
|
||||
webhook_base_url: &data.webhook_base_url,
|
||||
new_token: data.new_token.as_deref(),
|
||||
}
|
||||
.render()
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
fn render_watch_queue_page(&self, data: WatchQueuePageData) -> Result<String, String> {
|
||||
WatchQueueTemplate {
|
||||
ctx: &data.ctx,
|
||||
entries: &data.entries,
|
||||
error: data.error.as_deref(),
|
||||
}
|
||||
.render()
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user