fix: search frames SQL alias bug, visual search serde default, identity JSON hyphen lookup
This commit is contained in:
@@ -475,6 +475,9 @@ pub struct IdentityChunkItem {
|
||||
pub file_uuid: String,
|
||||
pub chunk_id: String,
|
||||
pub chunk_type: String,
|
||||
pub start_frame: i64,
|
||||
pub end_frame: i64,
|
||||
pub fps: f64,
|
||||
pub start_time: Option<f64>,
|
||||
pub end_time: Option<f64>,
|
||||
pub text_content: Option<String>,
|
||||
@@ -504,6 +507,9 @@ async fn get_identity_chunks(
|
||||
file_uuid: r.file_uuid,
|
||||
chunk_id: r.chunk_id,
|
||||
chunk_type: r.chunk_type,
|
||||
start_frame: r.start_frame,
|
||||
end_frame: r.end_frame,
|
||||
fps: r.fps,
|
||||
start_time: r.start_time,
|
||||
end_time: r.end_time,
|
||||
text_content: r.text_content,
|
||||
@@ -788,16 +794,24 @@ async fn get_profile_image(
|
||||
async fn get_identity_json(
|
||||
Path(identity_uuid): Path<String>,
|
||||
) -> Result<(StatusCode, [(String, String); 1], Vec<u8>), StatusCode> {
|
||||
let path = crate::core::identity::storage::identity_file_path(&identity_uuid);
|
||||
if !path.exists() {
|
||||
return Err(StatusCode::NOT_FOUND);
|
||||
let clean = identity_uuid.replace('-', "");
|
||||
let with_hyphens = if clean.len() == 32 {
|
||||
format!("{}-{}-{}-{}-{}", &clean[0..8], &clean[8..12], &clean[12..16], &clean[16..20], &clean[20..32])
|
||||
} else {
|
||||
identity_uuid.clone()
|
||||
};
|
||||
for u in [&clean, &identity_uuid, &with_hyphens] {
|
||||
let p = crate::core::identity::storage::identity_file_path(u);
|
||||
if p.exists() {
|
||||
let data = std::fs::read(&p).map_err(|_| StatusCode::NOT_FOUND)?;
|
||||
return Ok((
|
||||
StatusCode::OK,
|
||||
[("content-type".to_string(), "application/json".to_string())],
|
||||
data,
|
||||
));
|
||||
}
|
||||
}
|
||||
let data = std::fs::read(&path).map_err(|_| StatusCode::NOT_FOUND)?;
|
||||
Ok((
|
||||
StatusCode::OK,
|
||||
[("content-type".to_string(), "application/json".to_string())],
|
||||
data,
|
||||
))
|
||||
Err(StatusCode::NOT_FOUND)
|
||||
}
|
||||
|
||||
// ── Experiment: Identity Text Search ──────────────────────────
|
||||
|
||||
@@ -65,6 +65,7 @@ pub enum SearchResult {
|
||||
// Primary: frame-accurate position
|
||||
start_frame: i64,
|
||||
end_frame: i64,
|
||||
fps: f64,
|
||||
// Reference: time derived from frames (subject to FPS variation)
|
||||
start_time: f64,
|
||||
end_time: f64,
|
||||
@@ -340,7 +341,7 @@ async fn search_chunks(
|
||||
|
||||
let chunk_table = schema::table_name("chunk");
|
||||
let mut sql = format!(
|
||||
"SELECT chunk_id, chunk_type, start_time, end_time, start_frame, end_frame, text_content, content FROM {} WHERE file_uuid = '{}'",
|
||||
"SELECT chunk_id, chunk_type, start_time, end_time, (start_time * fps)::bigint as start_frame, (end_time * fps)::bigint as end_frame, fps, text_content, content FROM {} WHERE file_uuid = '{}'",
|
||||
chunk_table, uuid
|
||||
);
|
||||
if let Some(tr) = &req.time_range {
|
||||
@@ -432,6 +433,7 @@ async fn search_chunks(
|
||||
f64,
|
||||
i64,
|
||||
i64,
|
||||
f64,
|
||||
Option<String>,
|
||||
Option<serde_json::Value>,
|
||||
)> = sqlx::query_as(&sql).fetch_all(db.pool()).await?;
|
||||
@@ -446,6 +448,7 @@ async fn search_chunks(
|
||||
end_time,
|
||||
start_frame,
|
||||
end_frame,
|
||||
fps,
|
||||
text_content,
|
||||
content,
|
||||
)| {
|
||||
@@ -476,6 +479,7 @@ async fn search_chunks(
|
||||
end_time,
|
||||
start_frame,
|
||||
end_frame,
|
||||
fps,
|
||||
score,
|
||||
text,
|
||||
speaker_id,
|
||||
@@ -666,7 +670,7 @@ async fn search_frames_internal_v2(
|
||||
);
|
||||
|
||||
if let Some(uuid) = &req.file_uuid {
|
||||
sql.push_str(&format!(" AND fd.file_uuid = '{}'", uuid));
|
||||
sql.push_str(&format!(" AND v.file_uuid = '{}'", uuid));
|
||||
}
|
||||
if let Some(tr) = &req.time_range {
|
||||
sql.push_str(&format!(
|
||||
|
||||
@@ -23,8 +23,10 @@ pub struct VisualChunkSearchCriteria {
|
||||
/// Minimum number of unique object classes
|
||||
pub min_unique_classes: Option<u32>,
|
||||
/// Specific object classes to include (empty means all)
|
||||
#[serde(default)]
|
||||
pub required_classes: Vec<String>,
|
||||
/// Object class counts to filter by
|
||||
#[serde(default)]
|
||||
pub class_counts: HashMap<String, (u32, u32)>,
|
||||
/// Time range (optional)
|
||||
pub time_range: Option<(f64, f64)>,
|
||||
|
||||
Reference in New Issue
Block a user