feat: add job worker and duplicate registration check

Job Worker System:
- Add polling-based job worker (max 2 concurrent processors)
- Create monitor_jobs records when videos are registered
- Link videos.job_id to monitor_jobs
- Fix type mismatches (i32 vs i64) for database IDs

Duplicate Registration:
- Check if video already exists before registering
- Return existing video info with already_exists: true
- Use canonical path for UUID computation

USER_DATA_ROOT Configuration:
- Add MOMENTRY_USER_DATA_ROOT environment variable
- UUID computed from relative path (username/filename)
- Ensures consistent UUIDs when data root changes
This commit is contained in:
accusys
2026-03-25 02:50:31 +08:00
parent cd0f952aeb
commit 12a7b59232
9 changed files with 3669 additions and 229 deletions
+57
View File
@@ -25,6 +25,41 @@ pub fn compute_uuid_from_path(full_path: &str) -> String {
compute_uuid(&parent, &filename)
}
/// Extract relative path from full path given data root
/// Returns (relative_path, filename)
pub fn extract_relative_path(full_path: &str, data_root: &str) -> (String, String) {
let full_path = PathBuf::from(full_path);
let data_root = PathBuf::from(data_root);
// Canonicalize both paths
let full_canonical = full_path.canonicalize().unwrap_or(full_path.clone());
let root_canonical = data_root.canonicalize().unwrap_or(data_root.clone());
// Try to strip the data root prefix
let relative = full_canonical
.strip_prefix(&root_canonical)
.unwrap_or(&full_canonical);
// Separate into parent directory and filename
let filename = relative
.file_name()
.map(|n| n.to_string_lossy().to_string())
.unwrap_or_default();
let parent = relative
.parent()
.map(|p| p.to_string_lossy().to_string())
.unwrap_or_default();
(parent, filename)
}
/// Compute UUID from full path using data root for relative path extraction
pub fn compute_uuid_from_path_with_root(full_path: &str, data_root: &str) -> String {
let (parent, filename) = extract_relative_path(full_path, data_root);
compute_uuid(&parent, &filename)
}
#[cfg(test)]
mod tests {
use super::*;
@@ -41,4 +76,26 @@ mod tests {
let uuid = compute_uuid_from_path("/Users/test/Videos/video.mp4");
assert_eq!(uuid.len(), 16);
}
#[test]
fn test_relative_path_extraction() {
let (parent, filename) =
extract_relative_path("/data/sftpgo/data/demo/video.mp4", "/data/sftpgo/data");
assert_eq!(parent, "demo");
assert_eq!(filename, "video.mp4");
}
#[test]
fn test_uuid_with_data_root() {
let uuid1 = compute_uuid_from_path_with_root(
"/data/sftpgo/data/demo/video.mp4",
"/data/sftpgo/data",
);
let uuid2 = compute_uuid_from_path_with_root(
"/data/sftpgo/data/demo/video.mp4",
"/data/sftpgo/data",
);
assert_eq!(uuid1, uuid2);
assert_eq!(uuid1.len(), 16);
}
}