@@ -5,7 +5,7 @@ use domain::{
|
|||||||
errors::DomainError,
|
errors::DomainError,
|
||||||
events::DomainEvent,
|
events::DomainEvent,
|
||||||
ports::{
|
ports::{
|
||||||
EventHandler, EventPublisher, ObjectStorage, MetadataClient, MovieRepository,
|
EventHandler, EventPublisher, MetadataClient, MovieRepository, ObjectStorage,
|
||||||
PosterFetcherClient,
|
PosterFetcherClient,
|
||||||
},
|
},
|
||||||
value_objects::{ExternalMetadataId, MovieId, PosterPath},
|
value_objects::{ExternalMetadataId, MovieId, PosterPath},
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ use domain::{
|
|||||||
events::DomainEvent,
|
events::DomainEvent,
|
||||||
models::{CastMember, CrewMember, Genre, Keyword, MovieProfile},
|
models::{CastMember, CrewMember, Genre, Keyword, MovieProfile},
|
||||||
ports::{
|
ports::{
|
||||||
EventHandler, ObjectStorage, MovieEnrichmentClient, MovieProfileRepository, MovieRepository,
|
EventHandler, MovieEnrichmentClient, MovieProfileRepository, MovieRepository,
|
||||||
PersonCommand, SearchCommand,
|
ObjectStorage, PersonCommand, SearchCommand,
|
||||||
},
|
},
|
||||||
value_objects::MovieId,
|
value_objects::MovieId,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -56,10 +56,12 @@ impl WrapUpVideoRenderer for FfmpegWrapUpRenderer {
|
|||||||
)?);
|
)?);
|
||||||
}
|
}
|
||||||
if !report.top_actors.is_empty() {
|
if !report.top_actors.is_empty() {
|
||||||
slide_pngs.push(
|
slide_pngs.push(self.slide_renderer.render_actors(
|
||||||
self.slide_renderer
|
report,
|
||||||
.render_actors(report, &assets.cast_images, width, height)?,
|
&assets.cast_images,
|
||||||
);
|
width,
|
||||||
|
height,
|
||||||
|
)?);
|
||||||
}
|
}
|
||||||
if !report.top_genres.is_empty() {
|
if !report.top_genres.is_empty() {
|
||||||
slide_pngs.push(self.slide_renderer.render_genres(report, width, height)?);
|
slide_pngs.push(self.slide_renderer.render_genres(report, width, height)?);
|
||||||
@@ -71,10 +73,11 @@ impl WrapUpVideoRenderer for FfmpegWrapUpRenderer {
|
|||||||
height,
|
height,
|
||||||
)?);
|
)?);
|
||||||
if !assets.poster_images.is_empty() {
|
if !assets.poster_images.is_empty() {
|
||||||
slide_pngs.push(
|
slide_pngs.push(self.slide_renderer.render_mosaic(
|
||||||
self.slide_renderer
|
&assets.poster_images,
|
||||||
.render_mosaic(&assets.poster_images, width, height)?,
|
width,
|
||||||
);
|
height,
|
||||||
|
)?);
|
||||||
} else {
|
} else {
|
||||||
tracing::warn!("no poster images resolved, skipping mosaic slide");
|
tracing::warn!("no poster images resolved, skipping mosaic slide");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use domain::ports::{
|
use domain::ports::{
|
||||||
AuthService, DiaryExporter, DiaryRepository, DocumentParser, EventPublisher, ObjectStorage,
|
AuthService, DiaryExporter, DiaryRepository, DocumentParser, EventPublisher,
|
||||||
ImportProfileRepository, ImportSessionRepository, MetadataClient, MovieProfileRepository,
|
ImportProfileRepository, ImportSessionRepository, MetadataClient, MovieProfileRepository,
|
||||||
MovieRepository, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
MovieRepository, ObjectStorage, PasswordHasher, PersonCommand, PersonQuery,
|
||||||
RemoteWatchlistRepository, ReviewRepository, SearchCommand, SearchPort, SocialQueryPort,
|
PosterFetcherClient, RemoteWatchlistRepository, ReviewRepository, SearchCommand, SearchPort,
|
||||||
StatsRepository, UserProfileFieldsRepository, UserRepository, WatchEventRepository,
|
SocialQueryPort, StatsRepository, UserProfileFieldsRepository, UserRepository,
|
||||||
WatchlistRepository, WebhookTokenRepository, WrapUpRepository, WrapUpStatsQuery,
|
WatchEventRepository, WatchlistRepository, WebhookTokenRepository, WrapUpRepository,
|
||||||
WrapUpVideoRenderer,
|
WrapUpStatsQuery, WrapUpVideoRenderer,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::config::AppConfig;
|
use crate::config::AppConfig;
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ use domain::testing::{
|
|||||||
};
|
};
|
||||||
use domain::{
|
use domain::{
|
||||||
ports::{
|
ports::{
|
||||||
AuthService, DiaryExporter, DiaryRepository, DocumentParser, EventPublisher, ObjectStorage,
|
AuthService, DiaryExporter, DiaryRepository, DocumentParser, EventPublisher,
|
||||||
ImportProfileRepository, ImportSessionRepository, MetadataClient, MovieProfileRepository,
|
ImportProfileRepository, ImportSessionRepository, MetadataClient, MovieProfileRepository,
|
||||||
MovieRepository, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
MovieRepository, ObjectStorage, PasswordHasher, PersonCommand, PersonQuery,
|
||||||
ReviewRepository, SearchCommand, SearchPort, StatsRepository, UserProfileFieldsRepository,
|
PosterFetcherClient, ReviewRepository, SearchCommand, SearchPort, StatsRepository,
|
||||||
UserRepository, WatchEventRepository, WatchlistRepository, WebhookTokenRepository,
|
UserProfileFieldsRepository, UserRepository, WatchEventRepository, WatchlistRepository,
|
||||||
WrapUpRepository, WrapUpStatsQuery,
|
WebhookTokenRepository, WrapUpRepository, WrapUpStatsQuery,
|
||||||
},
|
},
|
||||||
testing::{
|
testing::{
|
||||||
FakeAuthService, FakeMetadataClient, FakePasswordHasher, InMemoryMovieRepository,
|
FakeAuthService, FakeMetadataClient, FakePasswordHasher, InMemoryMovieRepository,
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ pub async fn execute(
|
|||||||
|
|
||||||
if let Some(ref renderer) = ctx.services.video_renderer {
|
if let Some(ref renderer) = ctx.services.video_renderer {
|
||||||
let asset_storage = WrapUpStorage::new(ctx.services.object_storage.clone());
|
let asset_storage = WrapUpStorage::new(ctx.services.object_storage.clone());
|
||||||
let poster_images = asset_storage.resolve_poster_images(&report.poster_paths).await;
|
let poster_images = asset_storage
|
||||||
|
.resolve_poster_images(&report.poster_paths)
|
||||||
|
.await;
|
||||||
let cast_images = asset_storage
|
let cast_images = asset_storage
|
||||||
.resolve_cast_images(&report.top_cast_profile_paths)
|
.resolve_cast_images(&report.top_cast_profile_paths)
|
||||||
.await;
|
.await;
|
||||||
|
|||||||
@@ -27,10 +27,7 @@ impl WrapUpStorage {
|
|||||||
format!("cast{profile_path}")
|
format!("cast{profile_path}")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn resolve_cast_images(
|
pub async fn resolve_cast_images(&self, profile_paths: &[String]) -> Vec<(String, Vec<u8>)> {
|
||||||
&self,
|
|
||||||
profile_paths: &[String],
|
|
||||||
) -> Vec<(String, Vec<u8>)> {
|
|
||||||
let mut images = Vec::new();
|
let mut images = Vec::new();
|
||||||
for path in profile_paths.iter().take(20) {
|
for path in profile_paths.iter().take(20) {
|
||||||
let key = Self::cast_image_key(path);
|
let key = Self::cast_image_key(path);
|
||||||
@@ -39,14 +36,15 @@ impl WrapUpStorage {
|
|||||||
Err(e) => tracing::debug!("cast fetch skipped for {key}: {e}"),
|
Err(e) => tracing::debug!("cast fetch skipped for {key}: {e}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tracing::info!("resolved {}/{} cast images", images.len(), profile_paths.len());
|
tracing::info!(
|
||||||
|
"resolved {}/{} cast images",
|
||||||
|
images.len(),
|
||||||
|
profile_paths.len()
|
||||||
|
);
|
||||||
images
|
images
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn resolve_poster_images(
|
pub async fn resolve_poster_images(&self, paths: &[String]) -> Vec<(String, Vec<u8>)> {
|
||||||
&self,
|
|
||||||
paths: &[String],
|
|
||||||
) -> Vec<(String, Vec<u8>)> {
|
|
||||||
let mut images = Vec::new();
|
let mut images = Vec::new();
|
||||||
for path in paths.iter().take(20) {
|
for path in paths.iter().take(20) {
|
||||||
match self.inner.get(path).await {
|
match self.inner.get(path).await {
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ use crate::{
|
|||||||
},
|
},
|
||||||
ports::{
|
ports::{
|
||||||
AuthService, DiaryExporter, DiaryRepository, DocumentParser, EventPublisher, FeedSortBy,
|
AuthService, DiaryExporter, DiaryRepository, DocumentParser, EventPublisher, FeedSortBy,
|
||||||
FollowingFilter, GeneratedToken, ObjectStorage, ImportProfileRepository,
|
FollowingFilter, GeneratedToken, ImportProfileRepository, ImportSessionRepository,
|
||||||
ImportSessionRepository, MetadataClient, MetadataSearchCriteria, MovieProfileRepository,
|
MetadataClient, MetadataSearchCriteria, MovieProfileRepository, MovieRepository,
|
||||||
MovieRepository, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
ObjectStorage, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
||||||
ReviewRepository, SearchCommand, SearchPort, StatsRepository, UserProfileFieldsRepository,
|
ReviewRepository, SearchCommand, SearchPort, StatsRepository, UserProfileFieldsRepository,
|
||||||
UserRepository, WatchlistRepository, WrapUpRepository,
|
UserRepository, WatchlistRepository, WrapUpRepository,
|
||||||
},
|
},
|
||||||
@@ -1099,7 +1099,11 @@ impl WrapUpRepository for InMemoryWrapUpRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_complete(&self, id: &WrapUpId, report: &crate::models::wrapup::WrapUpReport) -> Result<(), DomainError> {
|
async fn set_complete(
|
||||||
|
&self,
|
||||||
|
id: &WrapUpId,
|
||||||
|
report: &crate::models::wrapup::WrapUpReport,
|
||||||
|
) -> Result<(), DomainError> {
|
||||||
let mut store = self.store.lock().unwrap();
|
let mut store = self.store.lock().unwrap();
|
||||||
if let Some(rec) = store.iter_mut().find(|r| r.id == *id) {
|
if let Some(rec) = store.iter_mut().find(|r| r.id == *id) {
|
||||||
rec.status = crate::models::wrapup::WrapUpStatus::Ready;
|
rec.status = crate::models::wrapup::WrapUpStatus::Ready;
|
||||||
@@ -1189,7 +1193,11 @@ impl WrapUpRepository for PanicWrapUpRepository {
|
|||||||
) -> Result<(), DomainError> {
|
) -> Result<(), DomainError> {
|
||||||
panic!("PanicWrapUpRepository called")
|
panic!("PanicWrapUpRepository called")
|
||||||
}
|
}
|
||||||
async fn set_complete(&self, _: &WrapUpId, _: &crate::models::wrapup::WrapUpReport) -> Result<(), DomainError> {
|
async fn set_complete(
|
||||||
|
&self,
|
||||||
|
_: &WrapUpId,
|
||||||
|
_: &crate::models::wrapup::WrapUpReport,
|
||||||
|
) -> Result<(), DomainError> {
|
||||||
panic!("PanicWrapUpRepository called")
|
panic!("PanicWrapUpRepository called")
|
||||||
}
|
}
|
||||||
async fn get_by_id(
|
async fn get_by_id(
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use domain::ports::{
|
use domain::ports::{
|
||||||
AuthService, ObjectStorage, LocalApContentQuery, MetadataClient, PasswordHasher,
|
AuthService, LocalApContentQuery, MetadataClient, ObjectStorage, PasswordHasher,
|
||||||
PosterFetcherClient, UserProfileFieldsRepository, WatchEventRepository, WebhookTokenRepository,
|
PosterFetcherClient, UserProfileFieldsRepository, WatchEventRepository, WebhookTokenRepository,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ use domain::{
|
|||||||
collections::{PageParams, Paginated},
|
collections::{PageParams, Paginated},
|
||||||
},
|
},
|
||||||
ports::{
|
ports::{
|
||||||
AuthService, DiaryRepository, EventPublisher, GeneratedToken, ObjectStorage, MetadataClient,
|
AuthService, DiaryRepository, EventPublisher, GeneratedToken, MetadataClient,
|
||||||
MovieRepository, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
MovieRepository, ObjectStorage, PasswordHasher, PersonCommand, PersonQuery,
|
||||||
ReviewRepository, SearchCommand, SearchPort, StatsRepository, UserRepository,
|
PosterFetcherClient, ReviewRepository, SearchCommand, SearchPort, StatsRepository,
|
||||||
WatchlistRepository,
|
UserRepository, WatchlistRepository,
|
||||||
},
|
},
|
||||||
value_objects::{
|
value_objects::{
|
||||||
Email, ExternalMetadataId, MovieId, MovieTitle, PasswordHash, PosterUrl, ReleaseYear,
|
Email, ExternalMetadataId, MovieId, MovieTitle, PasswordHash, PosterUrl, ReleaseYear,
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ use domain::{
|
|||||||
SearchQuery, SearchResults, User,
|
SearchQuery, SearchResults, User,
|
||||||
},
|
},
|
||||||
ports::{
|
ports::{
|
||||||
AuthService, EventPublisher, GeneratedToken, ObjectStorage, MetadataClient,
|
AuthService, EventPublisher, GeneratedToken, MetadataClient, MetadataSearchCriteria,
|
||||||
MetadataSearchCriteria, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
ObjectStorage, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
||||||
SearchCommand, SearchPort, UserRepository,
|
SearchCommand, SearchPort, UserRepository,
|
||||||
},
|
},
|
||||||
value_objects::{Email, ExternalMetadataId, PasswordHash, PosterUrl, UserId},
|
value_objects::{Email, ExternalMetadataId, PasswordHash, PosterUrl, UserId},
|
||||||
|
|||||||
Reference in New Issue
Block a user