feat: Add thumbnail management for albums and people, implement face embedding functionality
This commit is contained in:
@@ -15,3 +15,10 @@ pub struct BoundingBox {
|
||||
pub trait FaceDetector: Send + Sync {
|
||||
async fn detect_faces(&self, image_bytes: &[u8]) -> CoreResult<Vec<BoundingBox>>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait FaceEmbedder: Send + Sync {
|
||||
/// Generates a feature vector for a cropped face image.
|
||||
/// The image bytes should be a pre-cropped face.
|
||||
async fn generate_embedding(&self, image_bytes: &[u8]) -> CoreResult<Vec<f32>>;
|
||||
}
|
||||
|
||||
@@ -39,10 +39,20 @@ pub enum FaceDetectorRuntime {
|
||||
RemoteNats { subject: String },
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum FaceEmbedderRuntime {
|
||||
Tract,
|
||||
Onnx,
|
||||
RemoteNats { subject: String },
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
pub struct AiConfig {
|
||||
pub face_detector_runtime: FaceDetectorRuntime,
|
||||
pub face_detector_model_path: Option<String>,
|
||||
pub face_embedder_runtime: FaceEmbedderRuntime,
|
||||
pub face_embedder_model_path: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
|
||||
@@ -194,3 +194,11 @@ pub struct PersonShare {
|
||||
pub user_id: uuid::Uuid,
|
||||
pub permission: PersonPermission,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FaceEmbedding {
|
||||
pub id: uuid::Uuid,
|
||||
pub face_region_id: uuid::Uuid,
|
||||
pub model_id: i16,
|
||||
pub embedding: Vec<u8>,
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ use crate::{
|
||||
error::CoreResult,
|
||||
models::Media,
|
||||
repositories::{
|
||||
AlbumRepository, FaceRegionRepository, MediaMetadataRepository, MediaRepository,
|
||||
PersonRepository, TagRepository, UserRepository,
|
||||
AlbumRepository, FaceEmbeddingRepository, FaceRegionRepository, MediaMetadataRepository,
|
||||
MediaRepository, PersonRepository, TagRepository, UserRepository,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@ pub struct PluginContext {
|
||||
pub tag_repo: Arc<dyn TagRepository>,
|
||||
pub person_repo: Arc<dyn PersonRepository>,
|
||||
pub face_region_repo: Arc<dyn FaceRegionRepository>,
|
||||
pub face_embedding_repo: Arc<dyn FaceEmbeddingRepository>,
|
||||
pub media_library_path: String,
|
||||
pub config: Arc<AppConfig>,
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ use uuid::Uuid;
|
||||
use crate::{
|
||||
error::CoreResult,
|
||||
models::{
|
||||
Album, AlbumPermission, FaceRegion, Media, MediaMetadata, Person, PersonPermission, Tag,
|
||||
User,
|
||||
Album, AlbumPermission, FaceEmbedding, FaceRegion, Media, MediaMetadata, Person,
|
||||
PersonPermission, Tag, User,
|
||||
},
|
||||
schema::{ListMediaOptions, MediaImportBundle},
|
||||
};
|
||||
@@ -43,6 +43,7 @@ pub trait AlbumRepository: Send + Sync {
|
||||
async fn delete(&self, id: Uuid) -> CoreResult<()>;
|
||||
async fn list_media_by_album_id(&self, album_id: Uuid) -> CoreResult<Vec<Media>>;
|
||||
async fn is_media_in_public_album(&self, media_id: Uuid) -> CoreResult<bool>;
|
||||
async fn set_thumbnail_media_id(&self, album_id: Uuid, media_id: Uuid) -> CoreResult<()>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -90,6 +91,7 @@ pub trait PersonRepository: Send + Sync {
|
||||
async fn list_by_user(&self, user_id: Uuid) -> CoreResult<Vec<Person>>;
|
||||
async fn update(&self, person: Person) -> CoreResult<()>;
|
||||
async fn delete(&self, id: Uuid) -> CoreResult<()>;
|
||||
async fn set_thumbnail_media_id(&self, person_id: Uuid, media_id: Uuid) -> CoreResult<()>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -129,3 +131,12 @@ pub trait PersonShareRepository: Send + Sync {
|
||||
pub trait MediaImportRepository: Send + Sync {
|
||||
async fn create_media_bundle(&self, bundle: MediaImportBundle) -> CoreResult<()>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait FaceEmbeddingRepository: Send + Sync {
|
||||
async fn create(&self, embedding: &FaceEmbedding) -> CoreResult<()>;
|
||||
async fn find_by_face_region_id(
|
||||
&self,
|
||||
face_region_id: Uuid,
|
||||
) -> CoreResult<Option<FaceEmbedding>>;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,12 @@ pub trait AlbumService: Send + Sync {
|
||||
) -> CoreResult<Album>;
|
||||
async fn delete_album(&self, album_id: Uuid, user_id: Uuid) -> CoreResult<()>;
|
||||
async fn get_public_album_bundle(&self, album_id: Uuid) -> CoreResult<PublicAlbumBundle>;
|
||||
async fn set_album_thumbnail(
|
||||
&self,
|
||||
album_id: Uuid,
|
||||
media_id: Uuid,
|
||||
user_id: Uuid,
|
||||
) -> CoreResult<()>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -114,6 +120,13 @@ pub trait PersonService: Send + Sync {
|
||||
source_person_id: Uuid,
|
||||
user_id: Uuid,
|
||||
) -> CoreResult<()>;
|
||||
|
||||
async fn set_person_thumbnail(
|
||||
&self,
|
||||
person_id: Uuid,
|
||||
face_region_id: Uuid,
|
||||
user_id: Uuid,
|
||||
) -> CoreResult<()>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
|
||||
Reference in New Issue
Block a user