feat: Add thumbnail generation feature and update media model

- Updated workspace members to include `libertas_importer`.
- Added a new migration to add `thumbnail_path` column to `media` table.
- Enhanced configuration structures to include `thumbnail_config`.
- Modified `Media` model to include `thumbnail_path`.
- Updated `MediaRepository` trait and its implementation to handle thumbnail path updates.
- Created `ThumbnailPlugin` for generating thumbnails based on media configurations.
- Integrated thumbnail generation into the media processing workflow.
- Updated dependencies in `libertas_worker` and `libertas_importer` for image processing.
This commit is contained in:
2025-11-12 00:28:12 +01:00
parent 4f7b93a8b0
commit 60860cf508
22 changed files with 1259 additions and 22 deletions

View File

@@ -48,6 +48,7 @@ pub struct PostgresMedia {
pub width: Option<i32>,
pub height: Option<i32>,
pub date_taken: Option<chrono::DateTime<chrono::Utc>>,
pub thumbnail_path: Option<String>,
}
#[derive(Debug, Clone, Copy, sqlx::Type, PartialEq, Eq, Deserialize)]

View File

@@ -64,6 +64,7 @@ impl From<PostgresMedia> for Media {
width: pg_media.width,
height: pg_media.height,
date_taken: pg_media.date_taken,
thumbnail_path: pg_media.thumbnail_path,
}
}
}

View File

@@ -31,8 +31,8 @@ impl MediaRepository for PostgresMediaRepository {
async fn create(&self, media: &Media) -> CoreResult<()> {
sqlx::query!(
r#"
INSERT INTO media (id, owner_id, storage_path, original_filename, mime_type, hash, created_at, width, height)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
INSERT INTO media (id, owner_id, storage_path, original_filename, mime_type, hash, created_at, width, height, thumbnail_path)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
"#,
media.id,
media.owner_id,
@@ -42,7 +42,8 @@ impl MediaRepository for PostgresMediaRepository {
media.hash,
media.created_at,
media.width,
media.height
media.height,
media.thumbnail_path
)
.execute(&self.pool)
.await
@@ -56,7 +57,7 @@ impl MediaRepository for PostgresMediaRepository {
PostgresMedia,
r#"
SELECT id, owner_id, storage_path, original_filename, mime_type, hash, created_at,
extracted_location, width, height, date_taken
extracted_location, width, height, date_taken, thumbnail_path
FROM media
WHERE hash = $1
"#,
@@ -74,7 +75,7 @@ impl MediaRepository for PostgresMediaRepository {
PostgresMedia,
r#"
SELECT id, owner_id, storage_path, original_filename, mime_type, hash, created_at,
extracted_location, width, height, date_taken
extracted_location, width, height, date_taken, thumbnail_path
FROM media
WHERE id = $1
"#,
@@ -91,7 +92,7 @@ impl MediaRepository for PostgresMediaRepository {
let mut query = sqlx::QueryBuilder::new(
r#"
SELECT id, owner_id, storage_path, original_filename, mime_type, hash, created_at,
extracted_location, width, height, date_taken
extracted_location, width, height, date_taken, thumbnail_path
FROM media
WHERE owner_id =
"#,
@@ -113,7 +114,7 @@ impl MediaRepository for PostgresMediaRepository {
Ok(media_list)
}
async fn update_metadata(
async fn update_exif_data(
&self,
id: Uuid,
width: Option<i32>,
@@ -125,7 +126,7 @@ impl MediaRepository for PostgresMediaRepository {
r#"
UPDATE media
SET width = $2, height = $3, extracted_location = $4, date_taken = $5
WHERE id = $1
WHERE id = $1 AND date_taken IS NULL
"#,
id,
width,
@@ -140,6 +141,23 @@ impl MediaRepository for PostgresMediaRepository {
Ok(())
}
async fn update_thumbnail_path(&self, id: Uuid, thumbnail_path: String) -> CoreResult<()> {
sqlx::query!(
r#"
UPDATE media
SET thumbnail_path = $2
WHERE id = $1
"#,
id,
thumbnail_path
)
.execute(&self.pool)
.await
.map_err(|e| CoreError::Database(e.to_string()))?;
Ok(())
}
async fn delete(&self, id: Uuid) -> CoreResult<()> {
sqlx::query!(
r#"