refactor: rename ImageStorage → ObjectStorage
Some checks failed
CI / Check / Test (push) Failing after 46s
Some checks failed
CI / Check / Test (push) Failing after 46s
This commit is contained in:
@@ -4,20 +4,20 @@ use async_trait::async_trait;
|
|||||||
use domain::{
|
use domain::{
|
||||||
errors::DomainError,
|
errors::DomainError,
|
||||||
events::DomainEvent,
|
events::DomainEvent,
|
||||||
ports::{EventHandler, ImageRefCommand, ImageStorage},
|
ports::{EventHandler, ImageRefCommand, ObjectStorage},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::Format;
|
use crate::Format;
|
||||||
|
|
||||||
pub struct ImageConversionHandler {
|
pub struct ImageConversionHandler {
|
||||||
storage: Arc<dyn ImageStorage>,
|
storage: Arc<dyn ObjectStorage>,
|
||||||
image_ref: Arc<dyn ImageRefCommand>,
|
image_ref: Arc<dyn ImageRefCommand>,
|
||||||
format: Format,
|
format: Format,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImageConversionHandler {
|
impl ImageConversionHandler {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
storage: Arc<dyn ImageStorage>,
|
storage: Arc<dyn ObjectStorage>,
|
||||||
image_ref: Arc<dyn ImageRefCommand>,
|
image_ref: Arc<dyn ImageRefCommand>,
|
||||||
format: Format,
|
format: Format,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ pub use config::{ConversionConfig, Format};
|
|||||||
pub use handler::ImageConversionHandler;
|
pub use handler::ImageConversionHandler;
|
||||||
|
|
||||||
use domain::ports::{
|
use domain::ports::{
|
||||||
EventHandler, EventPublisher, ImageRefCommand, ImageRefQuery, ImageStorage, PeriodicJob,
|
EventHandler, EventPublisher, ImageRefCommand, ImageRefQuery, ObjectStorage, PeriodicJob,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
type ConversionPair = (Arc<dyn EventHandler>, Arc<dyn PeriodicJob>);
|
type ConversionPair = (Arc<dyn EventHandler>, Arc<dyn PeriodicJob>);
|
||||||
|
|
||||||
pub fn build(
|
pub fn build(
|
||||||
image_storage: Arc<dyn ImageStorage>,
|
object_storage: Arc<dyn ObjectStorage>,
|
||||||
image_ref_command: Arc<dyn ImageRefCommand>,
|
image_ref_command: Arc<dyn ImageRefCommand>,
|
||||||
image_ref_query: Arc<dyn ImageRefQuery>,
|
image_ref_query: Arc<dyn ImageRefQuery>,
|
||||||
event_publisher: Arc<dyn EventPublisher>,
|
event_publisher: Arc<dyn EventPublisher>,
|
||||||
@@ -27,7 +27,7 @@ pub fn build(
|
|||||||
let format = config.format;
|
let format = config.format;
|
||||||
|
|
||||||
let handler = Arc::new(ImageConversionHandler::new(
|
let handler = Arc::new(ImageConversionHandler::new(
|
||||||
Arc::clone(&image_storage),
|
Arc::clone(&object_storage),
|
||||||
image_ref_command,
|
image_ref_command,
|
||||||
format,
|
format,
|
||||||
)) as Arc<dyn EventHandler>;
|
)) as Arc<dyn EventHandler>;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use image_storage::ImageStorageAdapter;
|
use object_storage::ObjectStorageAdapter;
|
||||||
use object_store::memory::InMemory;
|
use object_store::memory::InMemory;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
@@ -27,8 +27,8 @@ impl ImageRefCommand for MockImageRef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn in_memory_storage() -> Arc<ImageStorageAdapter> {
|
fn in_memory_storage() -> Arc<ObjectStorageAdapter> {
|
||||||
Arc::new(ImageStorageAdapter::new(Arc::new(InMemory::new())))
|
Arc::new(ObjectStorageAdapter::new(Arc::new(InMemory::new())))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tiny_jpeg() -> Vec<u8> {
|
fn tiny_jpeg() -> Vec<u8> {
|
||||||
@@ -44,7 +44,7 @@ async fn ignores_non_image_stored_events() {
|
|||||||
let storage = in_memory_storage();
|
let storage = in_memory_storage();
|
||||||
let image_ref = MockImageRef::new();
|
let image_ref = MockImageRef::new();
|
||||||
let handler = ImageConversionHandler::new(
|
let handler = ImageConversionHandler::new(
|
||||||
Arc::clone(&storage) as Arc<dyn ImageStorage>,
|
Arc::clone(&storage) as Arc<dyn ObjectStorage>,
|
||||||
Arc::clone(&image_ref) as Arc<dyn ImageRefCommand>,
|
Arc::clone(&image_ref) as Arc<dyn ImageRefCommand>,
|
||||||
Format::Avif,
|
Format::Avif,
|
||||||
);
|
);
|
||||||
@@ -68,7 +68,7 @@ async fn skips_already_converted_avif_key() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let image_ref = MockImageRef::new();
|
let image_ref = MockImageRef::new();
|
||||||
let handler = ImageConversionHandler::new(
|
let handler = ImageConversionHandler::new(
|
||||||
Arc::clone(&storage) as Arc<dyn ImageStorage>,
|
Arc::clone(&storage) as Arc<dyn ObjectStorage>,
|
||||||
Arc::clone(&image_ref) as Arc<dyn ImageRefCommand>,
|
Arc::clone(&image_ref) as Arc<dyn ImageRefCommand>,
|
||||||
Format::Avif,
|
Format::Avif,
|
||||||
);
|
);
|
||||||
@@ -92,7 +92,7 @@ async fn skips_already_converted_webp_key() {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let image_ref = MockImageRef::new();
|
let image_ref = MockImageRef::new();
|
||||||
let handler = ImageConversionHandler::new(
|
let handler = ImageConversionHandler::new(
|
||||||
Arc::clone(&storage) as Arc<dyn ImageStorage>,
|
Arc::clone(&storage) as Arc<dyn ObjectStorage>,
|
||||||
Arc::clone(&image_ref) as Arc<dyn ImageRefCommand>,
|
Arc::clone(&image_ref) as Arc<dyn ImageRefCommand>,
|
||||||
Format::Webp,
|
Format::Webp,
|
||||||
);
|
);
|
||||||
@@ -113,7 +113,7 @@ async fn converts_jpeg_to_avif_and_swaps_key() {
|
|||||||
storage.store("avatars/u1", &tiny_jpeg()).await.unwrap();
|
storage.store("avatars/u1", &tiny_jpeg()).await.unwrap();
|
||||||
let image_ref = MockImageRef::new();
|
let image_ref = MockImageRef::new();
|
||||||
let handler = ImageConversionHandler::new(
|
let handler = ImageConversionHandler::new(
|
||||||
Arc::clone(&storage) as Arc<dyn ImageStorage>,
|
Arc::clone(&storage) as Arc<dyn ObjectStorage>,
|
||||||
Arc::clone(&image_ref) as Arc<dyn ImageRefCommand>,
|
Arc::clone(&image_ref) as Arc<dyn ImageRefCommand>,
|
||||||
Format::Avif,
|
Format::Avif,
|
||||||
);
|
);
|
||||||
@@ -139,7 +139,7 @@ async fn converts_jpeg_to_webp_and_swaps_key() {
|
|||||||
storage.store("avatars/u1", &tiny_jpeg()).await.unwrap();
|
storage.store("avatars/u1", &tiny_jpeg()).await.unwrap();
|
||||||
let image_ref = MockImageRef::new();
|
let image_ref = MockImageRef::new();
|
||||||
let handler = ImageConversionHandler::new(
|
let handler = ImageConversionHandler::new(
|
||||||
Arc::clone(&storage) as Arc<dyn ImageStorage>,
|
Arc::clone(&storage) as Arc<dyn ObjectStorage>,
|
||||||
Arc::clone(&image_ref) as Arc<dyn ImageRefCommand>,
|
Arc::clone(&image_ref) as Arc<dyn ImageRefCommand>,
|
||||||
Format::Webp,
|
Format::Webp,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,17 +5,17 @@ use async_trait::async_trait;
|
|||||||
use domain::{
|
use domain::{
|
||||||
errors::DomainError,
|
errors::DomainError,
|
||||||
events::DomainEvent,
|
events::DomainEvent,
|
||||||
ports::{EventHandler, ImageStorage},
|
ports::{EventHandler, ObjectStorage},
|
||||||
};
|
};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use object_store::{ObjectStore, path::Path};
|
use object_store::{ObjectStore, path::Path};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct ImageStorageAdapter {
|
pub struct ObjectStorageAdapter {
|
||||||
store: Arc<dyn ObjectStore>,
|
store: Arc<dyn ObjectStore>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImageStorageAdapter {
|
impl ObjectStorageAdapter {
|
||||||
pub fn new(store: Arc<dyn ObjectStore>) -> Self {
|
pub fn new(store: Arc<dyn ObjectStore>) -> Self {
|
||||||
Self { store }
|
Self { store }
|
||||||
}
|
}
|
||||||
@@ -26,7 +26,7 @@ impl ImageStorageAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl ImageStorage for ImageStorageAdapter {
|
impl ObjectStorage for ObjectStorageAdapter {
|
||||||
async fn store(&self, key: &str, image_bytes: &[u8]) -> Result<String, DomainError> {
|
async fn store(&self, key: &str, image_bytes: &[u8]) -> Result<String, DomainError> {
|
||||||
let path = Path::from(key);
|
let path = Path::from(key);
|
||||||
self.store
|
self.store
|
||||||
@@ -78,12 +78,12 @@ impl ImageStorage for ImageStorageAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct ImageCleanupHandler {
|
pub struct ImageCleanupHandler {
|
||||||
image_storage: Arc<dyn ImageStorage>,
|
object_storage: Arc<dyn ObjectStorage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ImageCleanupHandler {
|
impl ImageCleanupHandler {
|
||||||
pub fn new(image_storage: Arc<dyn ImageStorage>) -> Self {
|
pub fn new(object_storage: Arc<dyn ObjectStorage>) -> Self {
|
||||||
Self { image_storage }
|
Self { object_storage }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,15 +97,15 @@ impl EventHandler for ImageCleanupHandler {
|
|||||||
let Some(path) = poster_path else {
|
let Some(path) = poster_path else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
if let Err(e) = self.image_storage.delete(path.value()).await {
|
if let Err(e) = self.object_storage.delete(path.value()).await {
|
||||||
tracing::warn!("image cleanup failed for {}: {e}", path.value());
|
tracing::warn!("image cleanup failed for {}: {e}", path.value());
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create() -> anyhow::Result<Arc<dyn ImageStorage>> {
|
pub fn create() -> anyhow::Result<Arc<dyn ObjectStorage>> {
|
||||||
Ok(Arc::new(ImageStorageAdapter::from_config(
|
Ok(Arc::new(ObjectStorageAdapter::from_config(
|
||||||
StorageConfig::from_env()?,
|
StorageConfig::from_env()?,
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use object_store::memory::InMemory;
|
use object_store::memory::InMemory;
|
||||||
|
|
||||||
fn adapter() -> ImageStorageAdapter {
|
fn adapter() -> ObjectStorageAdapter {
|
||||||
ImageStorageAdapter::new(Arc::new(InMemory::new()))
|
ObjectStorageAdapter::new(Arc::new(InMemory::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -46,7 +46,7 @@ async fn cleanup_handler_deletes_on_movie_deleted() {
|
|||||||
let inner = Arc::new(adapter());
|
let inner = Arc::new(adapter());
|
||||||
inner.store("some-uuid", b"img").await.unwrap();
|
inner.store("some-uuid", b"img").await.unwrap();
|
||||||
let path = PosterPath::new("some-uuid".to_string()).unwrap();
|
let path = PosterPath::new("some-uuid".to_string()).unwrap();
|
||||||
let handler = ImageCleanupHandler::new(Arc::clone(&inner) as Arc<dyn ImageStorage>);
|
let handler = ImageCleanupHandler::new(Arc::clone(&inner) as Arc<dyn ObjectStorage>);
|
||||||
handler
|
handler
|
||||||
.handle(&DomainEvent::MovieDeleted {
|
.handle(&DomainEvent::MovieDeleted {
|
||||||
movie_id: MovieId::from_uuid(uuid::Uuid::new_v4()),
|
movie_id: MovieId::from_uuid(uuid::Uuid::new_v4()),
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use domain::{
|
|||||||
errors::DomainError,
|
errors::DomainError,
|
||||||
events::DomainEvent,
|
events::DomainEvent,
|
||||||
ports::{
|
ports::{
|
||||||
EventHandler, EventPublisher, ImageStorage, MetadataClient, MovieRepository,
|
EventHandler, EventPublisher, ObjectStorage, MetadataClient, MovieRepository,
|
||||||
PosterFetcherClient,
|
PosterFetcherClient,
|
||||||
},
|
},
|
||||||
value_objects::{ExternalMetadataId, MovieId, PosterPath},
|
value_objects::{ExternalMetadataId, MovieId, PosterPath},
|
||||||
@@ -15,7 +15,7 @@ pub struct PosterSyncHandler {
|
|||||||
movie_repository: Arc<dyn MovieRepository>,
|
movie_repository: Arc<dyn MovieRepository>,
|
||||||
metadata_client: Arc<dyn MetadataClient>,
|
metadata_client: Arc<dyn MetadataClient>,
|
||||||
poster_fetcher: Arc<dyn PosterFetcherClient>,
|
poster_fetcher: Arc<dyn PosterFetcherClient>,
|
||||||
image_storage: Arc<dyn ImageStorage>,
|
object_storage: Arc<dyn ObjectStorage>,
|
||||||
event_publisher: Arc<dyn EventPublisher>,
|
event_publisher: Arc<dyn EventPublisher>,
|
||||||
max_retries: u32,
|
max_retries: u32,
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,7 @@ impl PosterSyncHandler {
|
|||||||
movie_repository: Arc<dyn MovieRepository>,
|
movie_repository: Arc<dyn MovieRepository>,
|
||||||
metadata_client: Arc<dyn MetadataClient>,
|
metadata_client: Arc<dyn MetadataClient>,
|
||||||
poster_fetcher: Arc<dyn PosterFetcherClient>,
|
poster_fetcher: Arc<dyn PosterFetcherClient>,
|
||||||
image_storage: Arc<dyn ImageStorage>,
|
object_storage: Arc<dyn ObjectStorage>,
|
||||||
event_publisher: Arc<dyn EventPublisher>,
|
event_publisher: Arc<dyn EventPublisher>,
|
||||||
max_retries: u32,
|
max_retries: u32,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@@ -33,7 +33,7 @@ impl PosterSyncHandler {
|
|||||||
movie_repository,
|
movie_repository,
|
||||||
metadata_client,
|
metadata_client,
|
||||||
poster_fetcher,
|
poster_fetcher,
|
||||||
image_storage,
|
object_storage,
|
||||||
event_publisher,
|
event_publisher,
|
||||||
max_retries,
|
max_retries,
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ impl PosterSyncHandler {
|
|||||||
|
|
||||||
let image_bytes = self.poster_fetcher.fetch_poster_bytes(&poster_url).await?;
|
let image_bytes = self.poster_fetcher.fetch_poster_bytes(&poster_url).await?;
|
||||||
let stored_path = self
|
let stored_path = self
|
||||||
.image_storage
|
.object_storage
|
||||||
.store(&movie_id.value().to_string(), &image_bytes)
|
.store(&movie_id.value().to_string(), &image_bytes)
|
||||||
.await?;
|
.await?;
|
||||||
if let Err(e) = self
|
if let Err(e) = self
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use domain::{
|
|||||||
events::DomainEvent,
|
events::DomainEvent,
|
||||||
models::{CastMember, CrewMember, Genre, Keyword, MovieProfile},
|
models::{CastMember, CrewMember, Genre, Keyword, MovieProfile},
|
||||||
ports::{
|
ports::{
|
||||||
EventHandler, ImageStorage, MovieEnrichmentClient, MovieProfileRepository, MovieRepository,
|
EventHandler, ObjectStorage, MovieEnrichmentClient, MovieProfileRepository, MovieRepository,
|
||||||
PersonCommand, SearchCommand,
|
PersonCommand, SearchCommand,
|
||||||
},
|
},
|
||||||
value_objects::MovieId,
|
value_objects::MovieId,
|
||||||
@@ -229,7 +229,7 @@ pub struct EnrichmentHandler {
|
|||||||
pub profile_repo: Arc<dyn MovieProfileRepository>,
|
pub profile_repo: Arc<dyn MovieProfileRepository>,
|
||||||
pub person_command: Arc<dyn PersonCommand>,
|
pub person_command: Arc<dyn PersonCommand>,
|
||||||
pub search_command: Arc<dyn SearchCommand>,
|
pub search_command: Arc<dyn SearchCommand>,
|
||||||
pub image_storage: Arc<dyn ImageStorage>,
|
pub object_storage: Arc<dyn ObjectStorage>,
|
||||||
http: reqwest::Client,
|
http: reqwest::Client,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ impl EnrichmentHandler {
|
|||||||
profile_repo: Arc<dyn MovieProfileRepository>,
|
profile_repo: Arc<dyn MovieProfileRepository>,
|
||||||
person_command: Arc<dyn PersonCommand>,
|
person_command: Arc<dyn PersonCommand>,
|
||||||
search_command: Arc<dyn SearchCommand>,
|
search_command: Arc<dyn SearchCommand>,
|
||||||
image_storage: Arc<dyn ImageStorage>,
|
object_storage: Arc<dyn ObjectStorage>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
enrichment_client,
|
enrichment_client,
|
||||||
@@ -248,7 +248,7 @@ impl EnrichmentHandler {
|
|||||||
profile_repo,
|
profile_repo,
|
||||||
person_command,
|
person_command,
|
||||||
search_command,
|
search_command,
|
||||||
image_storage,
|
object_storage,
|
||||||
http: reqwest::Client::new(),
|
http: reqwest::Client::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -259,14 +259,14 @@ impl EnrichmentHandler {
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let key = format!("cast{path}");
|
let key = format!("cast{path}");
|
||||||
if self.image_storage.get(&key).await.is_ok() {
|
if self.object_storage.get(&key).await.is_ok() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let url = format!("https://image.tmdb.org/t/p/w185{path}");
|
let url = format!("https://image.tmdb.org/t/p/w185{path}");
|
||||||
match self.http.get(&url).send().await {
|
match self.http.get(&url).send().await {
|
||||||
Ok(resp) if resp.status().is_success() => {
|
Ok(resp) if resp.status().is_success() => {
|
||||||
if let Ok(bytes) = resp.bytes().await
|
if let Ok(bytes) = resp.bytes().await
|
||||||
&& let Err(e) = self.image_storage.store(&key, &bytes).await
|
&& let Err(e) = self.object_storage.store(&key, &bytes).await
|
||||||
{
|
{
|
||||||
tracing::debug!("cast photo store failed for {path}: {e}");
|
tracing::debug!("cast photo store failed for {path}: {e}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use domain::ports::{
|
use domain::ports::{
|
||||||
AuthService, DiaryExporter, DiaryRepository, DocumentParser, EventPublisher, ImageStorage,
|
AuthService, DiaryExporter, DiaryRepository, DocumentParser, EventPublisher, ObjectStorage,
|
||||||
ImportProfileRepository, ImportSessionRepository, MetadataClient, MovieProfileRepository,
|
ImportProfileRepository, ImportSessionRepository, MetadataClient, MovieProfileRepository,
|
||||||
MovieRepository, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
MovieRepository, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
||||||
RemoteWatchlistRepository, ReviewRepository, SearchCommand, SearchPort, SocialQueryPort,
|
RemoteWatchlistRepository, ReviewRepository, SearchCommand, SearchPort, SocialQueryPort,
|
||||||
@@ -42,7 +42,7 @@ pub struct Services {
|
|||||||
pub password_hasher: Arc<dyn PasswordHasher>,
|
pub password_hasher: Arc<dyn PasswordHasher>,
|
||||||
pub metadata: Arc<dyn MetadataClient>,
|
pub metadata: Arc<dyn MetadataClient>,
|
||||||
pub poster_fetcher: Arc<dyn PosterFetcherClient>,
|
pub poster_fetcher: Arc<dyn PosterFetcherClient>,
|
||||||
pub image_storage: Arc<dyn ImageStorage>,
|
pub object_storage: Arc<dyn ObjectStorage>,
|
||||||
pub event_publisher: Arc<dyn EventPublisher>,
|
pub event_publisher: Arc<dyn EventPublisher>,
|
||||||
pub diary_exporter: Arc<dyn DiaryExporter>,
|
pub diary_exporter: Arc<dyn DiaryExporter>,
|
||||||
pub document_parser: Arc<dyn DocumentParser>,
|
pub document_parser: Arc<dyn DocumentParser>,
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ pub async fn execute(ctx: &AppContext, cmd: SyncPosterCommand) -> Result<(), Dom
|
|||||||
|
|
||||||
let stored_path = ctx
|
let stored_path = ctx
|
||||||
.services
|
.services
|
||||||
.image_storage
|
.object_storage
|
||||||
.store(&movie_id.value().to_string(), &image_bytes)
|
.store(&movie_id.value().to_string(), &image_bytes)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use domain::testing::{
|
|||||||
};
|
};
|
||||||
use domain::{
|
use domain::{
|
||||||
ports::{
|
ports::{
|
||||||
AuthService, DiaryExporter, DiaryRepository, DocumentParser, EventPublisher, ImageStorage,
|
AuthService, DiaryExporter, DiaryRepository, DocumentParser, EventPublisher, ObjectStorage,
|
||||||
ImportProfileRepository, ImportSessionRepository, MetadataClient, MovieProfileRepository,
|
ImportProfileRepository, ImportSessionRepository, MetadataClient, MovieProfileRepository,
|
||||||
MovieRepository, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
MovieRepository, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
||||||
ReviewRepository, SearchCommand, SearchPort, StatsRepository, UserProfileFieldsRepository,
|
ReviewRepository, SearchCommand, SearchPort, StatsRepository, UserProfileFieldsRepository,
|
||||||
@@ -16,7 +16,7 @@ use domain::{
|
|||||||
testing::{
|
testing::{
|
||||||
FakeAuthService, FakeMetadataClient, FakePasswordHasher, InMemoryMovieRepository,
|
FakeAuthService, FakeMetadataClient, FakePasswordHasher, InMemoryMovieRepository,
|
||||||
InMemoryReviewRepository, InMemoryUserRepository, InMemoryWatchlistRepository,
|
InMemoryReviewRepository, InMemoryUserRepository, InMemoryWatchlistRepository,
|
||||||
NoopEventPublisher, NoopImageStorage, PanicDiaryExporter, PanicDiaryRepository,
|
NoopEventPublisher, NoopObjectStorage, PanicDiaryExporter, PanicDiaryRepository,
|
||||||
PanicDocumentParser, PanicImportProfileRepository, PanicImportSessionRepository,
|
PanicDocumentParser, PanicImportProfileRepository, PanicImportSessionRepository,
|
||||||
PanicMovieProfileRepository, PanicPersonCommand, PanicPersonQuery, PanicPosterFetcher,
|
PanicMovieProfileRepository, PanicPersonCommand, PanicPersonQuery, PanicPosterFetcher,
|
||||||
PanicProfileFieldsRepo, PanicSearchCommand, PanicSearchPort, PanicStatsRepository,
|
PanicProfileFieldsRepo, PanicSearchCommand, PanicSearchPort, PanicStatsRepository,
|
||||||
@@ -38,7 +38,7 @@ pub struct TestContextBuilder {
|
|||||||
pub stats_repo: Arc<dyn StatsRepository>,
|
pub stats_repo: Arc<dyn StatsRepository>,
|
||||||
pub metadata_client: Arc<dyn MetadataClient>,
|
pub metadata_client: Arc<dyn MetadataClient>,
|
||||||
pub poster_fetcher: Arc<dyn PosterFetcherClient>,
|
pub poster_fetcher: Arc<dyn PosterFetcherClient>,
|
||||||
pub image_storage: Arc<dyn ImageStorage>,
|
pub object_storage: Arc<dyn ObjectStorage>,
|
||||||
pub event_publisher: Arc<dyn EventPublisher>,
|
pub event_publisher: Arc<dyn EventPublisher>,
|
||||||
pub auth_service: Arc<dyn AuthService>,
|
pub auth_service: Arc<dyn AuthService>,
|
||||||
pub password_hasher: Arc<dyn PasswordHasher>,
|
pub password_hasher: Arc<dyn PasswordHasher>,
|
||||||
@@ -70,7 +70,7 @@ impl TestContextBuilder {
|
|||||||
stats_repo: Arc::new(PanicStatsRepository),
|
stats_repo: Arc::new(PanicStatsRepository),
|
||||||
metadata_client: Arc::new(FakeMetadataClient),
|
metadata_client: Arc::new(FakeMetadataClient),
|
||||||
poster_fetcher: Arc::new(PanicPosterFetcher),
|
poster_fetcher: Arc::new(PanicPosterFetcher),
|
||||||
image_storage: Arc::new(NoopImageStorage),
|
object_storage: Arc::new(NoopObjectStorage),
|
||||||
event_publisher: NoopEventPublisher::new(),
|
event_publisher: NoopEventPublisher::new(),
|
||||||
auth_service: Arc::new(FakeAuthService),
|
auth_service: Arc::new(FakeAuthService),
|
||||||
password_hasher: Arc::new(FakePasswordHasher),
|
password_hasher: Arc::new(FakePasswordHasher),
|
||||||
@@ -172,7 +172,7 @@ impl TestContextBuilder {
|
|||||||
password_hasher: self.password_hasher,
|
password_hasher: self.password_hasher,
|
||||||
metadata: self.metadata_client,
|
metadata: self.metadata_client,
|
||||||
poster_fetcher: self.poster_fetcher,
|
poster_fetcher: self.poster_fetcher,
|
||||||
image_storage: self.image_storage,
|
object_storage: self.object_storage,
|
||||||
event_publisher: self.event_publisher,
|
event_publisher: self.event_publisher,
|
||||||
diary_exporter: self.diary_exporter,
|
diary_exporter: self.diary_exporter,
|
||||||
document_parser: self.document_parser,
|
document_parser: self.document_parser,
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ pub async fn execute(ctx: &AppContext, cmd: UpdateProfileCommand) -> Result<(),
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
if let Some(old_path) = user.avatar_path() {
|
if let Some(old_path) = user.avatar_path() {
|
||||||
let _ = ctx.services.image_storage.delete(old_path).await;
|
let _ = ctx.services.object_storage.delete(old_path).await;
|
||||||
}
|
}
|
||||||
let key = format!("avatars/{}", user_id.value());
|
let key = format!("avatars/{}", user_id.value());
|
||||||
let stored = ctx.services.image_storage.store(&key, &bytes).await?;
|
let stored = ctx.services.object_storage.store(&key, &bytes).await?;
|
||||||
if let Err(e) = ctx
|
if let Err(e) = ctx
|
||||||
.services
|
.services
|
||||||
.event_publisher
|
.event_publisher
|
||||||
@@ -49,10 +49,10 @@ pub async fn execute(ctx: &AppContext, cmd: UpdateProfileCommand) -> Result<(),
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
if let Some(old_path) = user.banner_path() {
|
if let Some(old_path) = user.banner_path() {
|
||||||
let _ = ctx.services.image_storage.delete(old_path).await;
|
let _ = ctx.services.object_storage.delete(old_path).await;
|
||||||
}
|
}
|
||||||
let key = format!("banners/{}", user_id.value());
|
let key = format!("banners/{}", user_id.value());
|
||||||
let stored = ctx.services.image_storage.store(&key, &bytes).await?;
|
let stored = ctx.services.object_storage.store(&key, &bytes).await?;
|
||||||
if let Err(e) = ctx
|
if let Err(e) = ctx
|
||||||
.services
|
.services
|
||||||
.event_publisher
|
.event_publisher
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ pub async fn execute(ctx: &AppContext, id: WrapUpId) -> Result<(), DomainError>
|
|||||||
.await?
|
.await?
|
||||||
.ok_or_else(|| DomainError::NotFound("wrap-up not found".into()))?;
|
.ok_or_else(|| DomainError::NotFound("wrap-up not found".into()))?;
|
||||||
|
|
||||||
let storage = WrapUpStorage::new(ctx.services.image_storage.clone());
|
let storage = WrapUpStorage::new(ctx.services.object_storage.clone());
|
||||||
let _ = storage.delete_video(&id).await;
|
let _ = storage.delete_video(&id).await;
|
||||||
|
|
||||||
ctx.repos.wrapup_repo.delete(&id).await
|
ctx.repos.wrapup_repo.delete(&id).await
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ pub async fn execute(
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
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.image_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)
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
use domain::errors::DomainError;
|
use domain::errors::DomainError;
|
||||||
use domain::ports::ImageStorage;
|
use domain::ports::ObjectStorage;
|
||||||
use domain::value_objects::WrapUpId;
|
use domain::value_objects::WrapUpId;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct WrapUpStorage {
|
pub struct WrapUpStorage {
|
||||||
inner: Arc<dyn ImageStorage>,
|
inner: Arc<dyn ObjectStorage>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WrapUpStorage {
|
impl WrapUpStorage {
|
||||||
pub fn new(storage: Arc<dyn ImageStorage>) -> Self {
|
pub fn new(storage: Arc<dyn ObjectStorage>) -> Self {
|
||||||
Self { inner: storage }
|
Self { inner: storage }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ pub trait PosterFetcherClient: Send + Sync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait ImageStorage: Send + Sync {
|
pub trait ObjectStorage: Send + Sync {
|
||||||
/// Stores `image_bytes` at `key` and returns the stored key.
|
/// Stores `image_bytes` at `key` and returns the stored key.
|
||||||
async fn store(&self, key: &str, image_bytes: &[u8]) -> Result<String, DomainError>;
|
async fn store(&self, key: &str, image_bytes: &[u8]) -> Result<String, DomainError>;
|
||||||
async fn get(&self, key: &str) -> Result<Vec<u8>, DomainError>;
|
async fn get(&self, key: &str) -> Result<Vec<u8>, DomainError>;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
ports::{
|
ports::{
|
||||||
AuthService, DiaryExporter, DiaryRepository, DocumentParser, EventPublisher, FeedSortBy,
|
AuthService, DiaryExporter, DiaryRepository, DocumentParser, EventPublisher, FeedSortBy,
|
||||||
FollowingFilter, GeneratedToken, ImageStorage, ImportProfileRepository,
|
FollowingFilter, GeneratedToken, ObjectStorage, ImportProfileRepository,
|
||||||
ImportSessionRepository, MetadataClient, MetadataSearchCriteria, MovieProfileRepository,
|
ImportSessionRepository, MetadataClient, MetadataSearchCriteria, MovieProfileRepository,
|
||||||
MovieRepository, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
MovieRepository, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
||||||
ReviewRepository, SearchCommand, SearchPort, StatsRepository, UserProfileFieldsRepository,
|
ReviewRepository, SearchCommand, SearchPort, StatsRepository, UserProfileFieldsRepository,
|
||||||
@@ -351,12 +351,12 @@ impl EventPublisher for NoopEventPublisher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── NoopImageStorage ──────────────────────────────────────────────────────────
|
// ── NoopObjectStorage ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
pub struct NoopImageStorage;
|
pub struct NoopObjectStorage;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl ImageStorage for NoopImageStorage {
|
impl ObjectStorage for NoopObjectStorage {
|
||||||
async fn store(&self, key: &str, _image_bytes: &[u8]) -> Result<String, DomainError> {
|
async fn store(&self, key: &str, _image_bytes: &[u8]) -> Result<String, DomainError> {
|
||||||
Ok(format!("noop://{key}"))
|
Ok(format!("noop://{key}"))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use domain::ports::{
|
use domain::ports::{
|
||||||
AuthService, ImageStorage, LocalApContentQuery, MetadataClient, PasswordHasher,
|
AuthService, ObjectStorage, LocalApContentQuery, MetadataClient, PasswordHasher,
|
||||||
PosterFetcherClient, UserProfileFieldsRepository, WatchEventRepository, WebhookTokenRepository,
|
PosterFetcherClient, UserProfileFieldsRepository, WatchEventRepository, WebhookTokenRepository,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ pub fn build_poster_fetcher() -> anyhow::Result<Arc<dyn PosterFetcherClient>> {
|
|||||||
poster_fetcher::create()
|
poster_fetcher::create()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_image_storage() -> anyhow::Result<Arc<dyn ImageStorage>> {
|
pub fn build_object_storage() -> anyhow::Result<Arc<dyn ObjectStorage>> {
|
||||||
image_storage::create()
|
image_storage::create()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ pub async fn get_image(
|
|||||||
if key.starts_with("http://") || key.starts_with("https://") {
|
if key.starts_with("http://") || key.starts_with("https://") {
|
||||||
return axum::response::Redirect::temporary(&key).into_response();
|
return axum::response::Redirect::temporary(&key).into_response();
|
||||||
}
|
}
|
||||||
match state.app_ctx.services.image_storage.get(&key).await {
|
match state.app_ctx.services.object_storage.get(&key).await {
|
||||||
Ok(bytes) => {
|
Ok(bytes) => {
|
||||||
let mime = infer::get(&bytes)
|
let mime = infer::get(&bytes)
|
||||||
.map(|t| t.mime_type())
|
.map(|t| t.mime_type())
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ pub async fn get_video(State(state): State<AppState>, Path(id): Path<Uuid>) -> i
|
|||||||
match state
|
match state
|
||||||
.app_ctx
|
.app_ctx
|
||||||
.services
|
.services
|
||||||
.image_storage
|
.object_storage
|
||||||
.get_stream(&video_key)
|
.get_stream(&video_key)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ async fn wire_dependencies() -> anyhow::Result<(AppState, axum::Router)> {
|
|||||||
let (auth_service, password_hasher) = factory::build_auth_adapters()?;
|
let (auth_service, password_hasher) = factory::build_auth_adapters()?;
|
||||||
let metadata_client = factory::build_metadata_client()?;
|
let metadata_client = factory::build_metadata_client()?;
|
||||||
let poster_fetcher = factory::build_poster_fetcher()?;
|
let poster_fetcher = factory::build_poster_fetcher()?;
|
||||||
let image_storage = factory::build_image_storage()?;
|
let object_storage = factory::build_object_storage()?;
|
||||||
|
|
||||||
let db = factory::build_database_adapters(&backend, &database_url).await?;
|
let db = factory::build_database_adapters(&backend, &database_url).await?;
|
||||||
let ap_content_repo = db.ap_content;
|
let ap_content_repo = db.ap_content;
|
||||||
@@ -201,7 +201,7 @@ async fn wire_dependencies() -> anyhow::Result<(AppState, axum::Router)> {
|
|||||||
password_hasher,
|
password_hasher,
|
||||||
metadata: metadata_client,
|
metadata: metadata_client,
|
||||||
poster_fetcher,
|
poster_fetcher,
|
||||||
image_storage,
|
object_storage,
|
||||||
event_publisher: event_publisher_arc,
|
event_publisher: event_publisher_arc,
|
||||||
diary_exporter: Arc::new(ExportAdapter) as Arc<dyn DiaryExporter>,
|
diary_exporter: Arc::new(ExportAdapter) as Arc<dyn DiaryExporter>,
|
||||||
document_parser: Arc::new(ImporterDocumentParser) as Arc<dyn DocumentParser>,
|
document_parser: Arc::new(ImporterDocumentParser) as Arc<dyn DocumentParser>,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use domain::{
|
|||||||
collections::{PageParams, Paginated},
|
collections::{PageParams, Paginated},
|
||||||
},
|
},
|
||||||
ports::{
|
ports::{
|
||||||
AuthService, DiaryRepository, EventPublisher, GeneratedToken, ImageStorage, MetadataClient,
|
AuthService, DiaryRepository, EventPublisher, GeneratedToken, ObjectStorage, MetadataClient,
|
||||||
MovieRepository, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
MovieRepository, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
||||||
ReviewRepository, SearchCommand, SearchPort, StatsRepository, UserRepository,
|
ReviewRepository, SearchCommand, SearchPort, StatsRepository, UserRepository,
|
||||||
WatchlistRepository,
|
WatchlistRepository,
|
||||||
@@ -194,7 +194,7 @@ impl PosterFetcherClient for Panic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl ImageStorage for Panic {
|
impl ObjectStorage for Panic {
|
||||||
async fn store(&self, _: &str, _: &[u8]) -> Result<String, DomainError> {
|
async fn store(&self, _: &str, _: &[u8]) -> Result<String, DomainError> {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
@@ -670,7 +670,7 @@ pub fn make_test_state(auth_service: Arc<dyn AuthService>) -> crate::state::AppS
|
|||||||
password_hasher: Arc::clone(&repo) as _,
|
password_hasher: Arc::clone(&repo) as _,
|
||||||
metadata: Arc::clone(&repo) as _,
|
metadata: Arc::clone(&repo) as _,
|
||||||
poster_fetcher: Arc::clone(&repo) as _,
|
poster_fetcher: Arc::clone(&repo) as _,
|
||||||
image_storage: Arc::clone(&repo) as _,
|
object_storage: Arc::clone(&repo) as _,
|
||||||
event_publisher: Arc::clone(&repo) as _,
|
event_publisher: Arc::clone(&repo) as _,
|
||||||
diary_exporter: Arc::clone(&repo) as _,
|
diary_exporter: Arc::clone(&repo) as _,
|
||||||
document_parser: Arc::clone(&repo) as _,
|
document_parser: Arc::clone(&repo) as _,
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use domain::{
|
|||||||
SearchQuery, SearchResults, User,
|
SearchQuery, SearchResults, User,
|
||||||
},
|
},
|
||||||
ports::{
|
ports::{
|
||||||
AuthService, EventPublisher, GeneratedToken, ImageStorage, MetadataClient,
|
AuthService, EventPublisher, GeneratedToken, ObjectStorage, MetadataClient,
|
||||||
MetadataSearchCriteria, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
MetadataSearchCriteria, PasswordHasher, PersonCommand, PersonQuery, PosterFetcherClient,
|
||||||
SearchCommand, SearchPort, UserRepository,
|
SearchCommand, SearchPort, UserRepository,
|
||||||
},
|
},
|
||||||
@@ -61,9 +61,9 @@ impl PosterFetcherClient for PanicFetcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PanicImageStorage;
|
struct PanicObjectStorage;
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl ImageStorage for PanicImageStorage {
|
impl ObjectStorage for PanicObjectStorage {
|
||||||
async fn store(&self, _: &str, _: &[u8]) -> Result<String, DomainError> {
|
async fn store(&self, _: &str, _: &[u8]) -> Result<String, DomainError> {
|
||||||
panic!()
|
panic!()
|
||||||
}
|
}
|
||||||
@@ -430,7 +430,7 @@ async fn test_app() -> Router {
|
|||||||
password_hasher: Arc::new(PanicHasher),
|
password_hasher: Arc::new(PanicHasher),
|
||||||
metadata: Arc::new(PanicMeta),
|
metadata: Arc::new(PanicMeta),
|
||||||
poster_fetcher: Arc::new(PanicFetcher),
|
poster_fetcher: Arc::new(PanicFetcher),
|
||||||
image_storage: Arc::new(PanicImageStorage),
|
object_storage: Arc::new(PanicObjectStorage),
|
||||||
event_publisher: Arc::new(NoopEventPublisher),
|
event_publisher: Arc::new(NoopEventPublisher),
|
||||||
diary_exporter: Arc::new(PanicExporter),
|
diary_exporter: Arc::new(PanicExporter),
|
||||||
document_parser: Arc::new(PanicDocumentParser),
|
document_parser: Arc::new(PanicDocumentParser),
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
let (auth_service, password_hasher) = auth::create()?;
|
let (auth_service, password_hasher) = auth::create()?;
|
||||||
let metadata_client = metadata::create()?;
|
let metadata_client = metadata::create()?;
|
||||||
let poster_fetcher = poster_fetcher::create()?;
|
let poster_fetcher = poster_fetcher::create()?;
|
||||||
let image_storage = image_storage::create()?;
|
let object_storage = image_storage::create()?;
|
||||||
|
|
||||||
let db = db::connect(&database_url, &backend).await?;
|
let db = db::connect(&database_url, &backend).await?;
|
||||||
let (event_publisher_arc, consumer_arc) = event_bus::create(&db.db_pool).await?;
|
let (event_publisher_arc, consumer_arc) = event_bus::create(&db.db_pool).await?;
|
||||||
@@ -100,7 +100,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
password_hasher,
|
password_hasher,
|
||||||
metadata: metadata_client,
|
metadata: metadata_client,
|
||||||
poster_fetcher,
|
poster_fetcher,
|
||||||
image_storage,
|
object_storage,
|
||||||
event_publisher: event_publisher_arc,
|
event_publisher: event_publisher_arc,
|
||||||
diary_exporter: Arc::new(ExportAdapter) as Arc<dyn DiaryExporter>,
|
diary_exporter: Arc::new(ExportAdapter) as Arc<dyn DiaryExporter>,
|
||||||
document_parser: Arc::new(ImporterDocumentParser) as Arc<dyn DocumentParser>,
|
document_parser: Arc::new(ImporterDocumentParser) as Arc<dyn DocumentParser>,
|
||||||
@@ -155,7 +155,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
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.image_storage),
|
Arc::clone(&ctx.services.object_storage),
|
||||||
)) as Arc<dyn EventHandler>;
|
)) as Arc<dyn EventHandler>;
|
||||||
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>;
|
||||||
@@ -170,7 +170,7 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
// ── Image conversion ──────────────────────────────────────────────────────
|
// ── Image conversion ──────────────────────────────────────────────────────
|
||||||
|
|
||||||
let conversion = image_converter::build(
|
let conversion = image_converter::build(
|
||||||
Arc::clone(&ctx.services.image_storage),
|
Arc::clone(&ctx.services.object_storage),
|
||||||
image_ref_command,
|
image_ref_command,
|
||||||
image_ref_query,
|
image_ref_query,
|
||||||
Arc::clone(&ctx.services.event_publisher),
|
Arc::clone(&ctx.services.event_publisher),
|
||||||
@@ -210,13 +210,13 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
Arc::clone(&ctx.repos.movie),
|
Arc::clone(&ctx.repos.movie),
|
||||||
Arc::clone(&ctx.services.metadata),
|
Arc::clone(&ctx.services.metadata),
|
||||||
Arc::clone(&ctx.services.poster_fetcher),
|
Arc::clone(&ctx.services.poster_fetcher),
|
||||||
Arc::clone(&ctx.services.image_storage),
|
Arc::clone(&ctx.services.object_storage),
|
||||||
Arc::clone(&ctx.services.event_publisher),
|
Arc::clone(&ctx.services.event_publisher),
|
||||||
3,
|
3,
|
||||||
)) as Arc<dyn EventHandler>;
|
)) as Arc<dyn EventHandler>;
|
||||||
|
|
||||||
let cleanup = Arc::new(image_storage::ImageCleanupHandler::new(Arc::clone(
|
let cleanup = Arc::new(image_storage::ImageCleanupHandler::new(Arc::clone(
|
||||||
&ctx.services.image_storage,
|
&ctx.services.object_storage,
|
||||||
))) as Arc<dyn EventHandler>;
|
))) as Arc<dyn EventHandler>;
|
||||||
|
|
||||||
#[cfg(not(feature = "federation"))]
|
#[cfg(not(feature = "federation"))]
|
||||||
|
|||||||
Reference in New Issue
Block a user