This commit is contained in:
2026-06-11 13:51:33 +02:00
parent 0fdc79af23
commit c05087a6c7
9 changed files with 76 additions and 36 deletions

View File

@@ -158,16 +158,47 @@ impl MovieEnrichmentClient for TmdbEnrichmentClient {
vote_count: d.vote_count,
original_language: d.original_language,
collection_name: d.belongs_to_collection.map(|c| c.name),
genres: d.genres.into_iter().map(|g| Genre { tmdb_id: g.id, name: g.name }).collect(),
keywords: d.keywords.keywords.into_iter().map(|k| Keyword { tmdb_id: k.id, name: k.name }).collect(),
cast: d.credits.cast.into_iter().map(|c| CastMember {
tmdb_person_id: c.id, name: c.name, character: c.character,
billing_order: c.order, profile_path: c.profile_path,
}).collect(),
crew: d.credits.crew.into_iter().map(|c| CrewMember {
tmdb_person_id: c.id, name: c.name, job: c.job,
department: c.department, profile_path: c.profile_path,
}).collect(),
genres: d
.genres
.into_iter()
.map(|g| Genre {
tmdb_id: g.id,
name: g.name,
})
.collect(),
keywords: d
.keywords
.keywords
.into_iter()
.map(|k| Keyword {
tmdb_id: k.id,
name: k.name,
})
.collect(),
cast: d
.credits
.cast
.into_iter()
.map(|c| CastMember {
tmdb_person_id: c.id,
name: c.name,
character: c.character,
billing_order: c.order,
profile_path: c.profile_path,
})
.collect(),
crew: d
.credits
.crew
.into_iter()
.map(|c| CrewMember {
tmdb_person_id: c.id,
name: c.name,
job: c.job,
department: c.department,
profile_path: c.profile_path,
})
.collect(),
enriched_at: Utc::now(),
})
}
@@ -201,8 +232,12 @@ impl PersonEnrichmentClient for TmdbEnrichmentClient {
Ok(PersonEnrichmentData {
biography: d.biography.filter(|s| !s.is_empty()),
birthday: d.birthday.and_then(|s| chrono::NaiveDate::parse_from_str(&s, "%Y-%m-%d").ok()),
deathday: d.deathday.and_then(|s| chrono::NaiveDate::parse_from_str(&s, "%Y-%m-%d").ok()),
birthday: d
.birthday
.and_then(|s| chrono::NaiveDate::parse_from_str(&s, "%Y-%m-%d").ok()),
deathday: d
.deathday
.and_then(|s| chrono::NaiveDate::parse_from_str(&s, "%Y-%m-%d").ok()),
place_of_birth: d.place_of_birth.filter(|s| !s.is_empty()),
also_known_as: d.also_known_as.unwrap_or_default(),
homepage: d.homepage.filter(|s| !s.is_empty()),

View File

@@ -9,5 +9,8 @@ pub async fn execute(
person_id: PersonId,
data: PersonEnrichmentData,
) -> Result<(), DomainError> {
ctx.repos.person_command.update_enrichment(&person_id, &data).await
ctx.repos
.person_command
.update_enrichment(&person_id, &data)
.await
}

View File

@@ -11,12 +11,14 @@ const ENRICHMENT_TTL_DAYS: i64 = 90;
pub async fn execute(ctx: &AppContext, id: PersonId) -> Result<PersonCredits, DomainError> {
let credits = ctx.repos.person_query.get_credits(&id).await?;
if should_enrich(&credits.person) {
let _ = ctx.services.event_publisher.publish(
&DomainEvent::PersonEnrichmentRequested {
let _ = ctx
.services
.event_publisher
.publish(&DomainEvent::PersonEnrichmentRequested {
person_id: id,
external_person_id: credits.person.external_id().value().to_string(),
},
).await;
})
.await;
}
Ok(credits)
}

View File

@@ -294,10 +294,7 @@ pub trait MovieEnrichmentClient: Send + Sync {
#[async_trait]
pub trait PersonEnrichmentClient: Send + Sync {
async fn fetch_details(
&self,
external_id: &str,
) -> Result<PersonEnrichmentData, DomainError>;
async fn fetch_details(&self, external_id: &str) -> Result<PersonEnrichmentData, DomainError>;
}
#[async_trait]

View File

@@ -6,8 +6,8 @@ use crate::{
AnnotatedRow, DiaryEntry, DiaryFilter, EntityType, ExportFormat, ExternalPersonId,
FeedEntry, FieldMapping, FileFormat, ImportError, ImportProfile, ImportSession,
IndexableDocument, MovieProfile, MovieStats, ParsedFile, Person, PersonCredits,
PersonEnrichmentData, PersonId,
ReviewHistory, SearchQuery, SearchResults, UserStats, UserTrends,
PersonEnrichmentData, PersonId, ReviewHistory, SearchQuery, SearchResults, UserStats,
UserTrends,
collections::{PageParams, Paginated},
},
ports::{

View File

@@ -13,8 +13,7 @@ use std::collections::HashMap;
use crate::render::render_page;
use application::import::{
apply_mapping as apply_import_mapping,
apply_profile as apply_import_profile,
apply_mapping as apply_import_mapping, apply_profile as apply_import_profile,
commands::{
ApplyImportMappingCommand, ApplyImportProfileCommand, CreateImportSessionCommand,
DeleteImportProfileCommand, ExecuteImportCommand, SaveImportProfileCommand,
@@ -911,17 +910,18 @@ pub async fn api_apply_profile(
} else {
StatusCode::UNPROCESSABLE_ENTITY
};
return (status, axum::Json(serde_json::json!({"error": e.to_string()}))).into_response();
return (
status,
axum::Json(serde_json::json!({"error": e.to_string()})),
)
.into_response();
}
let session = match state
.app_ctx
.repos
.import_session
.get(
&ImportSessionId::from_uuid(session_id),
&user_id,
)
.get(&ImportSessionId::from_uuid(session_id), &user_id)
.await
{
Ok(Some(s)) => s,

View File

@@ -114,7 +114,9 @@ pub async fn get_person_handler(
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}")),
imdb_url: person
.imdb_id()
.map(|id| format!("https://www.imdb.com/name/{id}")),
enriched: person.enriched_at().is_some(),
})
.into_response(),
@@ -150,7 +152,10 @@ pub async fn get_person_credits_handler(
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}")),
imdb_url: credits
.person
.imdb_id()
.map(|id| format!("https://www.imdb.com/name/{id}")),
enriched: credits.person.enriched_at().is_some(),
},
cast: credits

View File

@@ -15,8 +15,7 @@ use domain::{
models::{
DiaryEntry, DiaryFilter, EntityType, FeedEntry, IndexableDocument, Movie, Person,
PersonCredits, PersonEnrichmentData, PersonId, Review, ReviewHistory, SearchQuery,
SearchResults, UserStats,
UserTrends,
SearchResults, UserStats, UserTrends,
collections::{PageParams, Paginated},
},
ports::{

View File

@@ -15,8 +15,7 @@ use domain::{
events::DomainEvent,
models::{
EntityType, ExternalPersonId, IndexableDocument, Movie, Person, PersonCredits,
PersonEnrichmentData, PersonId,
SearchQuery, SearchResults, User,
PersonEnrichmentData, PersonId, SearchQuery, SearchResults, User,
},
ports::{
AuthService, EventPublisher, GeneratedToken, MetadataClient, MetadataSearchCriteria,