From 9d1366f2661210c9c7c3e170c224f3863723e399 Mon Sep 17 00:00:00 2001 From: Connor Johnstone Date: Mon, 23 Mar 2026 18:37:45 -0400 Subject: [PATCH] redux of the worker queue --- src/indexer.rs | 37 +++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 2 files changed, 38 insertions(+) diff --git a/src/indexer.rs b/src/indexer.rs index e1eac11..2210b08 100644 --- a/src/indexer.rs +++ b/src/indexer.rs @@ -118,6 +118,43 @@ async fn process_file( Ok(true) } +/// Index a single file by path. Returns `Ok(Some(track_id))` if indexed, +/// `Ok(None)` if skipped (unchanged mtime), or an error. +pub async fn index_file( + conn: &DatabaseConnection, + file_path: &std::path::Path, + dry_run: bool, +) -> IndexResult> { + let metadata = std::fs::metadata(file_path)?; + let mtime = metadata + .modified() + .ok() + .and_then(|t| { + let duration = t + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default(); + chrono::DateTime::from_timestamp(duration.as_secs() as i64, 0) + }) + .map(|dt| dt.naive_utc()) + .unwrap_or_else(|| chrono::Utc::now().naive_utc()); + + let scanned = ScannedFile { + path: file_path.to_owned(), + file_size: metadata.len() as i64, + mtime, + }; + + match process_file(conn, &scanned, dry_run).await? { + true => { + // Look up the track we just created to return its ID + let path_str = file_path.to_string_lossy().to_string(); + let track = shanty_db::queries::tracks::get_by_path(conn, &path_str).await?; + Ok(track.map(|t| t.id)) + } + false => Ok(None), + } +} + /// Run the full indexing pipeline: scan directory, extract metadata, upsert to DB. pub async fn index_directory( conn: &DatabaseConnection, diff --git a/src/lib.rs b/src/lib.rs index 23f4b2e..1dcbec5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,7 @@ pub mod metadata; pub mod scanner; pub use error::{IndexError, IndexResult}; +pub use indexer::index_file; use std::fmt; use std::path::PathBuf;