feat: trace-level matching, health watcher/worker status, timezone config
This commit is contained in:
@@ -37,7 +37,8 @@ pub async fn run_watcher() -> Result<()> {
|
||||
info!("Watch directories: {:?}", dirs);
|
||||
|
||||
tokio::spawn(async move {
|
||||
let mut interval = time::interval(std::time::Duration::from_millis(config.poll_interval_ms));
|
||||
let mut interval =
|
||||
time::interval(std::time::Duration::from_millis(config.poll_interval_ms));
|
||||
let mut known = std::collections::HashSet::new();
|
||||
loop {
|
||||
interval.tick().await;
|
||||
@@ -109,15 +110,43 @@ async fn auto_register_file(file_path: &str) {
|
||||
}
|
||||
};
|
||||
|
||||
let file_name = pre.get("file_name").and_then(|v| v.as_str()).unwrap_or("unknown").to_string();
|
||||
let file_name = pre
|
||||
.get("file_name")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("unknown")
|
||||
.to_string();
|
||||
let probe = pre.get("probe_json").cloned().unwrap_or_default();
|
||||
let file_type = pre.get("file_type").and_then(|v| v.as_str()).unwrap_or("unknown").to_string();
|
||||
let canonical_path = pre.get("file_path").and_then(|v| v.as_str()).unwrap_or(file_path).to_string();
|
||||
let file_type = pre
|
||||
.get("file_type")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("unknown")
|
||||
.to_string();
|
||||
let canonical_path = pre
|
||||
.get("file_path")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or(file_path)
|
||||
.to_string();
|
||||
|
||||
let duration = probe.get("format").and_then(|f| f.get("duration")).and_then(|v| v.as_f64()).unwrap_or(0.0);
|
||||
let width = probe.get("format").and_then(|f| f.get("width")).and_then(|v| v.as_u64()).unwrap_or(0) as u32;
|
||||
let height = probe.get("format").and_then(|f| f.get("height")).and_then(|v| v.as_u64()).unwrap_or(0) as u32;
|
||||
let fps_val = probe.get("format").and_then(|f| f.get("fps")).and_then(|v| v.as_f64()).unwrap_or(0.0);
|
||||
let duration = probe
|
||||
.get("format")
|
||||
.and_then(|f| f.get("duration"))
|
||||
.and_then(|v| v.as_f64())
|
||||
.unwrap_or(0.0);
|
||||
let width = probe
|
||||
.get("format")
|
||||
.and_then(|f| f.get("width"))
|
||||
.and_then(|v| v.as_u64())
|
||||
.unwrap_or(0) as u32;
|
||||
let height = probe
|
||||
.get("format")
|
||||
.and_then(|f| f.get("height"))
|
||||
.and_then(|v| v.as_u64())
|
||||
.unwrap_or(0) as u32;
|
||||
let fps_val = probe
|
||||
.get("format")
|
||||
.and_then(|f| f.get("fps"))
|
||||
.and_then(|v| v.as_f64())
|
||||
.unwrap_or(0.0);
|
||||
|
||||
let record = VideoRecord {
|
||||
id: 0,
|
||||
@@ -158,7 +187,10 @@ async fn auto_register_file(file_path: &str) {
|
||||
|
||||
match db.register_video(&record).await {
|
||||
Ok(id) => info!("[WATCHER] Auto-registered {} (id={})", record.file_uuid, id),
|
||||
Err(e) => warn!("[WATCHER] Auto-register failed for {}: {}", record.file_uuid, e),
|
||||
Err(e) => warn!(
|
||||
"[WATCHER] Auto-register failed for {}: {}",
|
||||
record.file_uuid, e
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,10 +207,14 @@ pub async fn pre_process_file(file_path: &str) -> Option<String> {
|
||||
let output_dir = std::env::var("MOMENTRY_OUTPUT_DIR")
|
||||
.unwrap_or_else(|_| "/Users/accusys/momentry/output_dev".to_string());
|
||||
|
||||
let birthday = std::fs::metadata(&path).ok()
|
||||
let birthday = std::fs::metadata(&path)
|
||||
.ok()
|
||||
.and_then(|m| m.modified().ok())
|
||||
.map(|t| {
|
||||
let secs = t.duration_since(std::time::UNIX_EPOCH).unwrap_or_default().as_secs();
|
||||
let secs = t
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_secs();
|
||||
chrono::DateTime::from_timestamp(secs as i64, 0)
|
||||
.map(|dt| dt.to_rfc3339())
|
||||
.unwrap_or_else(|| chrono::Utc::now().to_rfc3339())
|
||||
@@ -186,9 +222,8 @@ pub async fn pre_process_file(file_path: &str) -> Option<String> {
|
||||
.unwrap_or_else(|| chrono::Utc::now().to_rfc3339());
|
||||
|
||||
let mac = crate::core::storage::uuid::get_mac_address();
|
||||
let file_uuid = crate::core::storage::uuid::compute_birth_uuid(
|
||||
&mac, &birthday, &canonical_str, &filename,
|
||||
);
|
||||
let file_uuid =
|
||||
crate::core::storage::uuid::compute_birth_uuid(&mac, &birthday, &canonical_str, &filename);
|
||||
|
||||
let pre_path = std::path::PathBuf::from(&output_dir).join(format!("{}.pre.json", file_uuid));
|
||||
if pre_path.exists() {
|
||||
@@ -198,15 +233,22 @@ pub async fn pre_process_file(file_path: &str) -> Option<String> {
|
||||
|
||||
info!("[PRE-PROCESS] Pre-processing: {} → {}", filename, file_uuid);
|
||||
|
||||
let content_hash = crate::core::storage::content_hash::compute_sha256(&path).unwrap_or_default();
|
||||
let content_hash =
|
||||
crate::core::storage::content_hash::compute_sha256(&path).unwrap_or_default();
|
||||
|
||||
let scripts_dir = std::env::var("MOMENTRY_SCRIPTS_DIR")
|
||||
.unwrap_or_else(|_| "/Users/accusys/momentry_core_0.1/scripts".to_string());
|
||||
let python_path = std::env::var("MOMENTRY_PYTHON_PATH")
|
||||
.unwrap_or_else(|_| "/opt/homebrew/bin/python3.11".to_string());
|
||||
let probe_json = crate::core::probe::unified::unified_probe(&path, &scripts_dir, &python_path).await;
|
||||
let probe_json =
|
||||
crate::core::probe::unified::unified_probe(&path, &scripts_dir, &python_path).await;
|
||||
|
||||
let file_type = probe_json.get("format").and_then(|f| f.get("file_type")).and_then(|v| v.as_str()).unwrap_or("unknown").to_string();
|
||||
let file_type = probe_json
|
||||
.get("format")
|
||||
.and_then(|f| f.get("file_type"))
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("unknown")
|
||||
.to_string();
|
||||
|
||||
let pre_data = serde_json::json!({
|
||||
"file_name": filename,
|
||||
|
||||
Reference in New Issue
Block a user