feat: update core API, database layer, and worker modules
- Remove unused imports (n8n_search, universal_search, Client, Arc, etc.) - Update API endpoints for identity, face recognition, search - Fix postgres_db.rs search_videos parent_uuid column - Add snapshot API and identity agent API - Clean up backup files (.bak, .bak2)
This commit is contained in:
@@ -842,8 +842,30 @@ async fn main() -> Result<()> {
|
||||
Commands::Register { path } => {
|
||||
println!("Registering: {}", path);
|
||||
|
||||
// Compute UUID
|
||||
let uuid = momentry_core::uuid::compute_uuid_from_path(&path);
|
||||
// Compute Birth UUID
|
||||
// Step 1: Connect to DB to check for existing Birthday
|
||||
let db = PostgresDb::init().await?;
|
||||
let path_buf = std::path::PathBuf::from(&path);
|
||||
let filename = path_buf
|
||||
.file_name()
|
||||
.map(|n| n.to_string_lossy().to_string())
|
||||
.unwrap_or_default();
|
||||
|
||||
let birthday = sqlx::query_scalar::<_, chrono::DateTime<chrono::Utc>>(
|
||||
"SELECT registration_time FROM dev.videos WHERE file_name = $1 AND registration_time IS NOT NULL LIMIT 1"
|
||||
)
|
||||
.bind(&filename)
|
||||
.fetch_optional(db.pool())
|
||||
.await?
|
||||
.map(|t| t.to_rfc3339())
|
||||
.unwrap_or_else(|| chrono::Utc::now().to_rfc3339());
|
||||
|
||||
let uuid = momentry_core::uuid::compute_birth_uuid(
|
||||
&momentry_core::uuid::get_mac_address(),
|
||||
&birthday,
|
||||
&path,
|
||||
&filename,
|
||||
);
|
||||
println!("UUID: {}", uuid);
|
||||
|
||||
// Run ffprobe
|
||||
@@ -909,11 +931,38 @@ async fn main() -> Result<()> {
|
||||
.map(|n| n.to_string_lossy().to_string())
|
||||
.unwrap_or_default();
|
||||
|
||||
// Calculate total_frames: prefer nb_frames (exact) over duration * fps (approximate)
|
||||
let total_frames = {
|
||||
let video_stream = probe_result
|
||||
.streams
|
||||
.iter()
|
||||
.find(|s| s.codec_type.as_deref() == Some("video"));
|
||||
|
||||
if let Some(stream) = video_stream {
|
||||
if let Some(nb_frames_str) = &stream.nb_frames {
|
||||
if let Ok(nb_frames) = nb_frames_str.parse::<u64>() {
|
||||
println!(" Using nb_frames from ffprobe: {} frames", nb_frames);
|
||||
Some(nb_frames)
|
||||
} else {
|
||||
println!(" Failed to parse nb_frames, using duration * fps fallback");
|
||||
Some((duration * fps).floor() as u64)
|
||||
}
|
||||
} else {
|
||||
println!(" nb_frames not available, using duration * fps fallback");
|
||||
Some((duration * fps).floor() as u64)
|
||||
}
|
||||
} else {
|
||||
println!(" No video stream found");
|
||||
Some(0)
|
||||
}
|
||||
};
|
||||
|
||||
let record = VideoRecord {
|
||||
id: 0,
|
||||
uuid: uuid.clone(),
|
||||
file_uuid: uuid.clone(),
|
||||
file_path,
|
||||
file_name,
|
||||
file_type: None,
|
||||
duration,
|
||||
width,
|
||||
height,
|
||||
@@ -921,10 +970,14 @@ async fn main() -> Result<()> {
|
||||
probe_json: Some(json_str),
|
||||
storage: Default::default(),
|
||||
status: VideoStatus::Pending,
|
||||
processing_status: Some(serde_json::json!({"phase": "REGISTERED"})),
|
||||
birth_registration: None,
|
||||
user_id: None,
|
||||
job_id: None,
|
||||
created_at: String::new(),
|
||||
registration_time: None,
|
||||
total_frames: total_frames.unwrap_or(0),
|
||||
parent_uuid: None,
|
||||
};
|
||||
|
||||
let video_id = db.register_video(&record).await?;
|
||||
@@ -1026,10 +1079,32 @@ async fn main() -> Result<()> {
|
||||
println!(" Mode: {}", processing_mode);
|
||||
|
||||
// Compute UUID if path is given
|
||||
let uuid = if target.len() == 16 && !target.contains('/') {
|
||||
let uuid = if target.len() == 32 && !target.contains('/') {
|
||||
target.clone()
|
||||
} else {
|
||||
momentry_core::uuid::compute_uuid_from_path(&target)
|
||||
// Connect to DB to find Birthday
|
||||
let db = PostgresDb::init().await?;
|
||||
let path_buf = std::path::PathBuf::from(&target);
|
||||
let filename = path_buf
|
||||
.file_name()
|
||||
.map(|n| n.to_string_lossy().to_string())
|
||||
.unwrap_or_default();
|
||||
|
||||
let birthday = sqlx::query_scalar::<_, chrono::DateTime<chrono::Utc>>(
|
||||
"SELECT registration_time FROM dev.videos WHERE file_name = $1 AND registration_time IS NOT NULL LIMIT 1"
|
||||
)
|
||||
.bind(&filename)
|
||||
.fetch_optional(db.pool())
|
||||
.await?
|
||||
.map(|t| t.to_rfc3339())
|
||||
.unwrap_or_else(|| chrono::Utc::now().to_rfc3339());
|
||||
|
||||
momentry_core::uuid::compute_birth_uuid(
|
||||
&momentry_core::uuid::get_mac_address(),
|
||||
&birthday,
|
||||
&target,
|
||||
&filename,
|
||||
)
|
||||
};
|
||||
|
||||
// Get video from database
|
||||
@@ -2377,17 +2452,34 @@ async fn main() -> Result<()> {
|
||||
println!("Starting to process {} chunks...", sentence_chunks.len());
|
||||
for (i, chunk) in sentence_chunks.iter().enumerate() {
|
||||
if i < 3 {
|
||||
println!("Processing chunk {}/{}: {}", i+1, sentence_chunks.len(), chunk.chunk_id);
|
||||
println!(
|
||||
"Processing chunk {}/{}: {}",
|
||||
i + 1,
|
||||
sentence_chunks.len(),
|
||||
chunk.chunk_id
|
||||
);
|
||||
}
|
||||
let text = chunk
|
||||
.content
|
||||
.get("text")
|
||||
.and_then(|v| v.as_str())
|
||||
.or_else(|| chunk.content.get("data").and_then(|data| data.get("text")).and_then(|v| v.as_str()))
|
||||
.or_else(|| {
|
||||
chunk
|
||||
.content
|
||||
.get("data")
|
||||
.and_then(|data| data.get("text"))
|
||||
.and_then(|v| v.as_str())
|
||||
})
|
||||
.or(chunk.text_content.as_deref())
|
||||
.unwrap_or("");
|
||||
|
||||
eprintln!("Embedding chunk {}/{}: {} (text len: {})...", i+1, sentence_chunks.len(), chunk.chunk_id, text.len());
|
||||
eprintln!(
|
||||
"Embedding chunk {}/{}: {} (text len: {})...",
|
||||
i + 1,
|
||||
sentence_chunks.len(),
|
||||
chunk.chunk_id,
|
||||
text.len()
|
||||
);
|
||||
|
||||
if text.is_empty() {
|
||||
continue;
|
||||
@@ -2583,7 +2675,19 @@ async fn main() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
Commands::Lookup { path } => {
|
||||
let uuid = momentry_core::uuid::compute_uuid_from_path(&path);
|
||||
let path_buf = std::path::PathBuf::from(&path);
|
||||
let filename = path_buf
|
||||
.file_name()
|
||||
.map(|n| n.to_string_lossy().to_string())
|
||||
.unwrap_or_default();
|
||||
// Lookup usually checks "what would be the UUID", so we use current time.
|
||||
// If it were registered, it would have used its registration time.
|
||||
let uuid = momentry_core::uuid::compute_birth_uuid(
|
||||
&momentry_core::uuid::get_mac_address(),
|
||||
&chrono::Utc::now().to_rfc3339(),
|
||||
&path,
|
||||
&filename,
|
||||
);
|
||||
println!("Path: {}", path);
|
||||
println!("UUID: {}", uuid);
|
||||
Ok(())
|
||||
@@ -2612,10 +2716,10 @@ async fn main() -> Result<()> {
|
||||
for video in videos {
|
||||
println!(
|
||||
"\nGenerating thumbnails for: {} ({})",
|
||||
video.file_name, video.uuid
|
||||
video.file_name, video.file_uuid
|
||||
);
|
||||
|
||||
match extractor.get_or_create(&video.file_path, &video.uuid) {
|
||||
match extractor.get_or_create(&video.file_path, &video.file_uuid) {
|
||||
Ok(result) => {
|
||||
println!(" Generated {} thumbnails", result.count);
|
||||
}
|
||||
@@ -2681,8 +2785,8 @@ async fn main() -> Result<()> {
|
||||
|
||||
for video in videos {
|
||||
let (sentence_count, time_count) =
|
||||
db.get_chunk_count(&video.uuid).await.unwrap_or((0, 0));
|
||||
let vector_count = db.get_vector_count(&video.uuid).await.unwrap_or(0);
|
||||
db.get_chunk_count(&video.file_uuid).await.unwrap_or((0, 0));
|
||||
let vector_count = db.get_vector_count(&video.file_uuid).await.unwrap_or(0);
|
||||
let total_chunks = sentence_count + time_count;
|
||||
|
||||
let psql_status = if total_chunks > 0 { "✓" } else { "-" };
|
||||
|
||||
Reference in New Issue
Block a user