feat: media API (video/bbox/thumbnail), UUID unification, dot matrix text, portal fixes, API dictionary V1.3
This commit is contained in:
@@ -13,13 +13,25 @@ use crate::core::db::ResourceRecord;
|
||||
pub fn identity_routes() -> Router<crate::api::server::AppState> {
|
||||
Router::new()
|
||||
.route("/api/v1/files", get(list_files))
|
||||
.route("/api/v1/files/:uuid", get(get_file_detail))
|
||||
.route("/api/v1/files/:uuid/identities", get(get_file_identities))
|
||||
.route("/api/v1/identities/:uuid", get(get_identity_detail))
|
||||
.route("/api/v1/identities/:uuid/files", get(get_identity_files))
|
||||
.route("/api/v1/identities/:uuid/chunks", get(get_identity_chunks))
|
||||
.route("/api/v1/resources/register", post(register_resource))
|
||||
.route("/api/v1/resources/heartbeat", post(heartbeat_resource))
|
||||
.route("/api/v1/file/:file_uuid", get(get_file_detail))
|
||||
.route(
|
||||
"/api/v1/file/:file_uuid/identities",
|
||||
get(get_file_identities),
|
||||
)
|
||||
.route(
|
||||
"/api/v1/identity/:identity_uuid",
|
||||
get(get_identity_detail).delete(delete_identity),
|
||||
)
|
||||
.route(
|
||||
"/api/v1/identity/:identity_uuid/files",
|
||||
get(get_identity_files),
|
||||
)
|
||||
.route(
|
||||
"/api/v1/identity/:identity_uuid/chunks",
|
||||
get(get_identity_chunks),
|
||||
)
|
||||
.route("/api/v1/resource/register", post(register_resource))
|
||||
.route("/api/v1/resource/heartbeat", post(heartbeat_resource))
|
||||
.route("/api/v1/resources", get(list_resources))
|
||||
}
|
||||
|
||||
@@ -124,11 +136,11 @@ pub struct FileDetailResponse {
|
||||
|
||||
async fn get_file_detail(
|
||||
State(state): State<crate::api::server::AppState>,
|
||||
Path(uuid): Path<String>,
|
||||
Path(file_uuid): Path<String>,
|
||||
) -> Result<Json<FileDetailResponse>, (StatusCode, String)> {
|
||||
let file = state
|
||||
.db
|
||||
.get_file_by_uuid(&uuid)
|
||||
.get_file_by_uuid(&file_uuid)
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
||||
|
||||
@@ -141,7 +153,10 @@ async fn get_file_detail(
|
||||
metadata: f.probe_json,
|
||||
created_at: f.created_at,
|
||||
})),
|
||||
None => Err((StatusCode::NOT_FOUND, format!("File not found: {}", uuid))),
|
||||
None => Err((
|
||||
StatusCode::NOT_FOUND,
|
||||
format!("File not found: {}", file_uuid),
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +184,7 @@ pub struct FileIdentityItem {
|
||||
|
||||
async fn get_file_identities(
|
||||
State(state): State<crate::api::server::AppState>,
|
||||
Path(uuid): Path<String>,
|
||||
Path(file_uuid): Path<String>,
|
||||
Query(params): Query<FilesQuery>,
|
||||
) -> Result<Json<FileIdentitiesResponse>, (StatusCode, String)> {
|
||||
let page = params.page.unwrap_or(1);
|
||||
@@ -178,7 +193,7 @@ async fn get_file_identities(
|
||||
|
||||
let records = state
|
||||
.db
|
||||
.get_file_identities(&uuid, page_size as i32, offset)
|
||||
.get_file_identities(&file_uuid, page_size as i32, offset)
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?;
|
||||
|
||||
@@ -198,7 +213,7 @@ async fn get_file_identities(
|
||||
|
||||
Ok(Json(FileIdentitiesResponse {
|
||||
success: true,
|
||||
file_uuid: uuid,
|
||||
file_uuid: file_uuid,
|
||||
total: data.len() as i64,
|
||||
page,
|
||||
page_size,
|
||||
@@ -222,10 +237,15 @@ pub struct IdentityDetailResponse {
|
||||
pub updated_at: Option<chrono::DateTime<chrono::Utc>>,
|
||||
}
|
||||
|
||||
fn strip_uuid(u: &uuid::Uuid) -> String {
|
||||
u.to_string().replace('-', "")
|
||||
}
|
||||
|
||||
async fn get_identity_detail(
|
||||
State(state): State<crate::api::server::AppState>,
|
||||
Path(uuid_str): Path<String>,
|
||||
Path(identity_uuid): Path<String>,
|
||||
) -> Result<Json<IdentityDetailResponse>, (StatusCode, String)> {
|
||||
let uuid_str = identity_uuid;
|
||||
let uuid = Uuid::parse_str(&uuid_str)
|
||||
.map_err(|e| (StatusCode::BAD_REQUEST, format!("Invalid UUID: {}", e)))?;
|
||||
|
||||
@@ -267,6 +287,45 @@ pub struct IdentityFilesResponse {
|
||||
pub data: Vec<IdentityFileItem>,
|
||||
}
|
||||
|
||||
async fn delete_identity(
|
||||
State(state): State<crate::api::server::AppState>,
|
||||
Path(identity_uuid): Path<String>,
|
||||
) -> Result<StatusCode, StatusCode> {
|
||||
let table = crate::core::db::schema::table_name("face_detections");
|
||||
let id_table = crate::core::db::schema::table_name("identities");
|
||||
|
||||
// Get identity_id from identity_uuid
|
||||
let row: Option<(i32,)> = sqlx::query_as(&format!(
|
||||
"SELECT id FROM {} WHERE replace(uuid::text, '-', '') = $1",
|
||||
id_table
|
||||
))
|
||||
.bind(&identity_uuid)
|
||||
.fetch_optional(state.db.pool())
|
||||
.await
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
|
||||
let (identity_id,) = row.ok_or(StatusCode::NOT_FOUND)?;
|
||||
|
||||
// Unbind all faces
|
||||
sqlx::query(&format!(
|
||||
"UPDATE {} SET identity_id = NULL, identity_confidence = NULL WHERE identity_id = $1",
|
||||
table
|
||||
))
|
||||
.bind(identity_id)
|
||||
.execute(state.db.pool())
|
||||
.await
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
|
||||
// Delete identity
|
||||
sqlx::query(&format!("DELETE FROM {} WHERE id = $1", id_table))
|
||||
.bind(identity_id)
|
||||
.execute(state.db.pool())
|
||||
.await
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
|
||||
Ok(StatusCode::NO_CONTENT)
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct IdentityFileItem {
|
||||
pub file_uuid: String,
|
||||
@@ -282,9 +341,10 @@ pub struct IdentityFileItem {
|
||||
|
||||
async fn get_identity_files(
|
||||
State(state): State<crate::api::server::AppState>,
|
||||
Path(uuid_str): Path<String>,
|
||||
Path(identity_uuid): Path<String>,
|
||||
Query(params): Query<FilesQuery>,
|
||||
) -> Result<Json<IdentityFilesResponse>, (StatusCode, String)> {
|
||||
let uuid_str = identity_uuid;
|
||||
let uuid = Uuid::parse_str(&uuid_str)
|
||||
.map_err(|e| (StatusCode::BAD_REQUEST, format!("Invalid UUID: {}", e)))?;
|
||||
|
||||
@@ -421,9 +481,10 @@ pub struct IdentityChunkItem {
|
||||
|
||||
async fn get_identity_chunks(
|
||||
State(state): State<crate::api::server::AppState>,
|
||||
Path(uuid_str): Path<String>,
|
||||
Path(identity_uuid): Path<String>,
|
||||
Query(params): Query<FilesQuery>,
|
||||
) -> Result<Json<IdentityChunksResponse>, (StatusCode, String)> {
|
||||
let uuid_str = identity_uuid;
|
||||
let uuid = Uuid::parse_str(&uuid_str)
|
||||
.map_err(|e| (StatusCode::BAD_REQUEST, format!("Invalid UUID: {}", e)))?;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user