feat: trace-level matching, health watcher/worker status, timezone config

This commit is contained in:
Accusys
2026-05-21 01:08:30 +08:00
parent 8ede4be159
commit bebaa743ed
60 changed files with 6110 additions and 1586 deletions

View File

@@ -17,42 +17,84 @@ mod tests {
#[test]
fn test_detect_category_image() {
assert_eq!(detect_category(Path::new("photo.jpg")), FileCategory::Image);
assert_eq!(detect_category(Path::new("photo.jpeg")), FileCategory::Image);
assert_eq!(
detect_category(Path::new("photo.jpeg")),
FileCategory::Image
);
assert_eq!(detect_category(Path::new("photo.png")), FileCategory::Image);
assert_eq!(detect_category(Path::new("photo.svg")), FileCategory::Image);
assert_eq!(detect_category(Path::new("photo.webp")), FileCategory::Image);
assert_eq!(
detect_category(Path::new("photo.webp")),
FileCategory::Image
);
}
#[test]
fn test_detect_category_document() {
assert_eq!(detect_category(Path::new("doc.pdf")), FileCategory::Document);
assert_eq!(detect_category(Path::new("doc.docx")), FileCategory::Document);
assert_eq!(detect_category(Path::new("doc.pages")), FileCategory::Document);
assert_eq!(detect_category(Path::new("doc.txt")), FileCategory::Document);
assert_eq!(
detect_category(Path::new("doc.pdf")),
FileCategory::Document
);
assert_eq!(
detect_category(Path::new("doc.docx")),
FileCategory::Document
);
assert_eq!(
detect_category(Path::new("doc.pages")),
FileCategory::Document
);
assert_eq!(
detect_category(Path::new("doc.txt")),
FileCategory::Document
);
}
#[test]
fn test_detect_category_spreadsheet() {
assert_eq!(detect_category(Path::new("data.xlsx")), FileCategory::Spreadsheet);
assert_eq!(detect_category(Path::new("data.csv")), FileCategory::Spreadsheet);
assert_eq!(detect_category(Path::new("data.numbers")), FileCategory::Spreadsheet);
assert_eq!(
detect_category(Path::new("data.xlsx")),
FileCategory::Spreadsheet
);
assert_eq!(
detect_category(Path::new("data.csv")),
FileCategory::Spreadsheet
);
assert_eq!(
detect_category(Path::new("data.numbers")),
FileCategory::Spreadsheet
);
}
#[test]
fn test_detect_category_presentation() {
assert_eq!(detect_category(Path::new("deck.pptx")), FileCategory::Presentation);
assert_eq!(detect_category(Path::new("deck.key")), FileCategory::Presentation);
assert_eq!(
detect_category(Path::new("deck.pptx")),
FileCategory::Presentation
);
assert_eq!(
detect_category(Path::new("deck.key")),
FileCategory::Presentation
);
}
#[test]
fn test_detect_category_archive() {
assert_eq!(detect_category(Path::new("files.zip")), FileCategory::Archive);
assert_eq!(detect_category(Path::new("files.tar.gz")), FileCategory::Archive);
assert_eq!(
detect_category(Path::new("files.zip")),
FileCategory::Archive
);
assert_eq!(
detect_category(Path::new("files.tar.gz")),
FileCategory::Archive
);
}
#[test]
fn test_detect_category_unknown() {
assert_eq!(detect_category(Path::new("file.xyz")), FileCategory::Unknown);
assert_eq!(
detect_category(Path::new("file.xyz")),
FileCategory::Unknown
);
assert_eq!(detect_category(Path::new("file")), FileCategory::Unknown);
}
@@ -84,13 +126,18 @@ pub enum FileCategory {
/// Detect file category from path extension
pub fn detect_category(path: &Path) -> FileCategory {
let ext = path.extension()
let ext = path
.extension()
.and_then(|e| e.to_str())
.map(|e| e.to_lowercase());
match ext.as_deref() {
Some("mp4" | "mov" | "mkv" | "avi" | "webm" | "m4v" | "mpeg") => FileCategory::Video,
Some("jpg" | "jpeg" | "png" | "gif" | "bmp" | "webp" | "svg" | "heic" | "tiff") => FileCategory::Image,
Some("pdf" | "doc" | "docx" | "odt" | "pages" | "rtf" | "txt" | "md" | "rst") => FileCategory::Document,
Some("jpg" | "jpeg" | "png" | "gif" | "bmp" | "webp" | "svg" | "heic" | "tiff") => {
FileCategory::Image
}
Some("pdf" | "doc" | "docx" | "odt" | "pages" | "rtf" | "txt" | "md" | "rst") => {
FileCategory::Document
}
Some("xls" | "xlsx" | "csv" | "ods" | "numbers") => FileCategory::Spreadsheet,
Some("ppt" | "pptx" | "odp" | "key") => FileCategory::Presentation,
Some("zip" | "tar" | "gz" | "tgz" | "7z" | "rar") => FileCategory::Archive,
@@ -102,16 +149,20 @@ pub fn detect_category(path: &Path) -> FileCategory {
pub fn base_format_info(path: &Path) -> serde_json::Value {
let meta = std::fs::metadata(path).ok();
let size = meta.as_ref().map(|m| m.len()).unwrap_or(0);
let mtime = meta.as_ref()
let mtime = meta
.as_ref()
.and_then(|m| m.modified().ok())
.and_then(|t| {
let secs = t.duration_since(SystemTime::UNIX_EPOCH).ok()?.as_secs() as i64;
chrono::DateTime::from_timestamp(secs, 0)
.map(|dt| dt.to_rfc3339())
chrono::DateTime::from_timestamp(secs, 0).map(|dt| dt.to_rfc3339())
})
.unwrap_or_default();
let fname = path.to_string_lossy().to_string();
let ext = path.extension().and_then(|e| e.to_str()).unwrap_or("").to_lowercase();
let ext = path
.extension()
.and_then(|e| e.to_str())
.unwrap_or("")
.to_lowercase();
let cat = detect_category(path);
let file_type = match cat {
FileCategory::Video => "video",
@@ -150,7 +201,13 @@ fn ffprobe_probe(path: &Path, format_base: serde_json::Value) -> serde_json::Val
}
/// Run Python probe for document/spreadsheet/presentation files
fn python_probe(path: &Path, category: &FileCategory, scripts_dir: &str, python_path: &str, format_base: serde_json::Value) -> serde_json::Value {
fn python_probe(
path: &Path,
category: &FileCategory,
scripts_dir: &str,
python_path: &str,
format_base: serde_json::Value,
) -> serde_json::Value {
let script = format!("{}/probe_file.py", scripts_dir);
if !std::path::Path::new(&script).exists() {
return minimal_probe(format_base);
@@ -184,18 +241,12 @@ fn minimal_probe(format_base: serde_json::Value) -> serde_json::Value {
/// Unified probe: dispatches to the right probe based on file type
/// Returns a probe_json-compatible Value
pub async fn unified_probe(
path: &Path,
scripts_dir: &str,
python_path: &str,
) -> serde_json::Value {
pub async fn unified_probe(path: &Path, scripts_dir: &str, python_path: &str) -> serde_json::Value {
let cat = detect_category(path);
let format_base = base_format_info(path);
match cat {
FileCategory::Video | FileCategory::Image => {
ffprobe_probe(path, format_base)
}
FileCategory::Video | FileCategory::Image => ffprobe_probe(path, format_base),
FileCategory::Document | FileCategory::Spreadsheet | FileCategory::Presentation => {
python_probe(path, &cat, scripts_dir, python_path, format_base)
}