feat: wire person enrichment handler, update API DTOs
This commit is contained in:
@@ -70,6 +70,21 @@ pub struct PersonDto {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
pub known_for_department: Option<String>,
|
pub known_for_department: Option<String>,
|
||||||
pub profile_path: Option<String>,
|
pub profile_path: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub biography: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub birthday: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub deathday: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub place_of_birth: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||||
|
pub also_known_as: Vec<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub homepage: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub imdb_url: Option<String>,
|
||||||
|
pub enriched: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, ToSchema)]
|
#[derive(Debug, Serialize, ToSchema)]
|
||||||
|
|||||||
@@ -108,6 +108,14 @@ pub async fn get_person_handler(
|
|||||||
name: person.name().to_string(),
|
name: person.name().to_string(),
|
||||||
known_for_department: person.known_for_department().map(str::to_string),
|
known_for_department: person.known_for_department().map(str::to_string),
|
||||||
profile_path: person.profile_path().map(str::to_string),
|
profile_path: person.profile_path().map(str::to_string),
|
||||||
|
biography: person.biography().map(str::to_string),
|
||||||
|
birthday: person.birthday().map(|d| d.to_string()),
|
||||||
|
deathday: person.deathday().map(|d| d.to_string()),
|
||||||
|
place_of_birth: person.place_of_birth().map(str::to_string),
|
||||||
|
also_known_as: person.also_known_as().to_vec(),
|
||||||
|
homepage: person.homepage().map(str::to_string),
|
||||||
|
imdb_url: person.imdb_id().map(|id| format!("https://www.imdb.com/name/{id}")),
|
||||||
|
enriched: person.enriched_at().is_some(),
|
||||||
})
|
})
|
||||||
.into_response(),
|
.into_response(),
|
||||||
Ok(None) => StatusCode::NOT_FOUND.into_response(),
|
Ok(None) => StatusCode::NOT_FOUND.into_response(),
|
||||||
@@ -136,6 +144,14 @@ pub async fn get_person_credits_handler(
|
|||||||
name: credits.person.name().to_string(),
|
name: credits.person.name().to_string(),
|
||||||
known_for_department: credits.person.known_for_department().map(str::to_string),
|
known_for_department: credits.person.known_for_department().map(str::to_string),
|
||||||
profile_path: credits.person.profile_path().map(str::to_string),
|
profile_path: credits.person.profile_path().map(str::to_string),
|
||||||
|
biography: credits.person.biography().map(str::to_string),
|
||||||
|
birthday: credits.person.birthday().map(|d| d.to_string()),
|
||||||
|
deathday: credits.person.deathday().map(|d| d.to_string()),
|
||||||
|
place_of_birth: credits.person.place_of_birth().map(str::to_string),
|
||||||
|
also_known_as: credits.person.also_known_as().to_vec(),
|
||||||
|
homepage: credits.person.homepage().map(str::to_string),
|
||||||
|
imdb_url: credits.person.imdb_id().map(|id| format!("https://www.imdb.com/name/{id}")),
|
||||||
|
enriched: credits.person.enriched_at().is_some(),
|
||||||
},
|
},
|
||||||
cast: credits
|
cast: credits
|
||||||
.cast
|
.cast
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ use export::ExportAdapter;
|
|||||||
use importer::ImporterDocumentParser;
|
use importer::ImporterDocumentParser;
|
||||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
|
|
||||||
use domain::ports::{DiaryExporter, DocumentParser, EventHandler, PeriodicJob};
|
use domain::ports::{
|
||||||
|
DiaryExporter, DocumentParser, EventHandler, MovieEnrichmentClient, PeriodicJob,
|
||||||
|
PersonEnrichmentClient,
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(not(any(feature = "sqlite", feature = "postgres")))]
|
#[cfg(not(any(feature = "sqlite", feature = "postgres")))]
|
||||||
compile_error!(
|
compile_error!(
|
||||||
@@ -74,7 +77,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
Arc::clone(&event_publisher_arc),
|
Arc::clone(&event_publisher_arc),
|
||||||
));
|
));
|
||||||
|
|
||||||
let ctx = AppContext {
|
let mut ctx = AppContext {
|
||||||
repos: Repositories {
|
repos: Repositories {
|
||||||
movie: db.movie,
|
movie: db.movie,
|
||||||
review: db.review,
|
review: db.review,
|
||||||
@@ -125,26 +128,38 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
// Both the event handler and the staleness job are gated on TMDB_API_KEY.
|
// Both the event handler and the staleness job are gated on TMDB_API_KEY.
|
||||||
// Without a key, no MovieEnrichmentRequested events are produced or handled.
|
// Without a key, no MovieEnrichmentRequested events are produced or handled.
|
||||||
|
|
||||||
type OptionalPair = (Option<Arc<dyn EventHandler>>, Option<Arc<dyn PeriodicJob>>);
|
type EnrichmentParts = (
|
||||||
let (enrichment_handler, enrichment_job): OptionalPair =
|
Option<Arc<dyn EventHandler>>,
|
||||||
|
Option<Arc<dyn EventHandler>>,
|
||||||
|
Option<Arc<dyn PeriodicJob>>,
|
||||||
|
);
|
||||||
|
let (enrichment_handler, person_enrichment_handler, enrichment_job): EnrichmentParts =
|
||||||
match tmdb_enrichment::TmdbEnrichmentClient::from_env() {
|
match tmdb_enrichment::TmdbEnrichmentClient::from_env() {
|
||||||
Ok(client) => {
|
Ok(client) => {
|
||||||
tracing::info!("TMDb enrichment enabled");
|
tracing::info!("TMDb enrichment enabled");
|
||||||
|
let client = Arc::new(client);
|
||||||
let handler = Arc::new(tmdb_enrichment::EnrichmentHandler::new(
|
let handler = Arc::new(tmdb_enrichment::EnrichmentHandler::new(
|
||||||
Arc::new(client),
|
Arc::clone(&client) as Arc<dyn MovieEnrichmentClient>,
|
||||||
Arc::clone(&ctx.repos.movie),
|
Arc::clone(&ctx.repos.movie),
|
||||||
Arc::clone(&ctx.repos.movie_profile),
|
Arc::clone(&ctx.repos.movie_profile),
|
||||||
Arc::clone(&ctx.repos.person_command),
|
Arc::clone(&ctx.repos.person_command),
|
||||||
Arc::clone(&ctx.repos.search_command),
|
Arc::clone(&ctx.repos.search_command),
|
||||||
Arc::clone(&ctx.services.object_storage),
|
Arc::clone(&ctx.services.object_storage),
|
||||||
)) as Arc<dyn EventHandler>;
|
)) as Arc<dyn EventHandler>;
|
||||||
|
let person_handler = Arc::new(tmdb_enrichment::PersonEnrichmentHandler::new(
|
||||||
|
Arc::clone(&client) as Arc<dyn PersonEnrichmentClient>,
|
||||||
|
Arc::clone(&ctx.repos.person_query),
|
||||||
|
Arc::clone(&ctx.repos.person_command),
|
||||||
|
)) as Arc<dyn EventHandler>;
|
||||||
|
ctx.services.person_enrichment =
|
||||||
|
Some(Arc::clone(&client) as Arc<dyn PersonEnrichmentClient>);
|
||||||
let job = Arc::new(application::jobs::EnrichmentStalenessJob::new(ctx.clone()))
|
let job = Arc::new(application::jobs::EnrichmentStalenessJob::new(ctx.clone()))
|
||||||
as Arc<dyn PeriodicJob>;
|
as Arc<dyn PeriodicJob>;
|
||||||
(Some(handler), Some(job))
|
(Some(handler), Some(person_handler), Some(job))
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::warn!("TMDb enrichment disabled: {e}");
|
tracing::warn!("TMDb enrichment disabled: {e}");
|
||||||
(None, None)
|
(None, None, None)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -226,6 +241,9 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
if let Some(e) = enrichment_handler {
|
if let Some(e) = enrichment_handler {
|
||||||
h.push(e);
|
h.push(e);
|
||||||
}
|
}
|
||||||
|
if let Some(e) = person_enrichment_handler {
|
||||||
|
h.push(e);
|
||||||
|
}
|
||||||
if let Some((ref conv_handler, _)) = conversion {
|
if let Some((ref conv_handler, _)) = conversion {
|
||||||
h.push(Arc::clone(conv_handler));
|
h.push(Arc::clone(conv_handler));
|
||||||
}
|
}
|
||||||
@@ -282,6 +300,9 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
if let Some(e) = enrichment_handler {
|
if let Some(e) = enrichment_handler {
|
||||||
h.push(e);
|
h.push(e);
|
||||||
}
|
}
|
||||||
|
if let Some(e) = person_enrichment_handler {
|
||||||
|
h.push(e);
|
||||||
|
}
|
||||||
if let Some((ref conv_handler, _)) = conversion {
|
if let Some((ref conv_handler, _)) = conversion {
|
||||||
h.push(Arc::clone(conv_handler));
|
h.push(Arc::clone(conv_handler));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user