chore: bump deps; fix clippy lints & cleanup

Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I4c4815ad145650a07f108614034d2e996a6a6964
This commit is contained in:
raf 2026-03-02 17:05:28 +03:00
commit cd1161ee5d
Signed by: NotAShelf
GPG key ID: 29D95B64378DB4BF
41 changed files with 1528 additions and 953 deletions

View file

@ -17,6 +17,7 @@ use crate::{
thumbnail,
};
/// Result of importing a single file.
pub struct ImportResult {
pub media_id: MediaId,
pub was_duplicate: bool,
@ -26,7 +27,7 @@ pub struct ImportResult {
}
/// Options for import operations
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Default)]
pub struct ImportOptions {
/// Skip files that haven't changed since last scan (based on mtime)
pub incremental: bool,
@ -36,16 +37,6 @@ pub struct ImportOptions {
pub photo_config: crate::config::PhotoConfig,
}
impl Default for ImportOptions {
fn default() -> Self {
Self {
incremental: false,
force: false,
photo_config: crate::config::PhotoConfig::default(),
}
}
}
/// Get the modification time of a file as a Unix timestamp
fn get_file_mtime(path: &Path) -> Option<i64> {
std::fs::metadata(path)
@ -55,9 +46,20 @@ fn get_file_mtime(path: &Path) -> Option<i64> {
.map(|d| d.as_secs() as i64)
}
/// Check that a canonicalized path falls under at least one configured root
/// directory. If no roots are configured, all paths are allowed (for ad-hoc
/// imports).
/// Validates that a path is within configured root directories.
///
/// # Arguments
///
/// * `storage` - Storage backend to query root directories
/// * `path` - Path to validate
///
/// # Returns
///
/// `Ok(())` if path is within roots or no roots configured
///
/// # Errors
///
/// Returns `InvalidOperation` if path is outside all root directories
pub async fn validate_path_in_roots(
storage: &DynStorageBackend,
path: &Path,
@ -79,6 +81,20 @@ pub async fn validate_path_in_roots(
)))
}
/// Imports a file using default options.
///
/// # Arguments
///
/// * `storage` - Storage backend
/// * `path` - Path to the file to import
///
/// # Returns
///
/// Import result with media ID and status
///
/// # Errors
///
/// Returns `FileNotFound` if path doesn't exist
pub async fn import_file(
storage: &DynStorageBackend,
path: &Path,
@ -236,15 +252,15 @@ pub async fn import_file_with_options(
storage.insert_media(&item).await?;
// Extract and store markdown links for markdown files
if is_markdown {
if let Err(e) = extract_and_store_links(storage, media_id, &path).await {
tracing::warn!(
media_id = %media_id,
path = %path.display(),
error = %e,
"failed to extract markdown links"
);
}
if is_markdown
&& let Err(e) = extract_and_store_links(storage, media_id, &path).await
{
tracing::warn!(
media_id = %media_id,
path = %path.display(),
error = %e,
"failed to extract markdown links"
);
}
// Store extracted extra metadata as custom fields
@ -419,12 +435,10 @@ async fn extract_and_store_links(
media_id: MediaId,
path: &Path,
) -> Result<()> {
// Read file content
let content = tokio::fs::read_to_string(path).await.map_err(|e| {
PinakesError::Io(std::io::Error::new(
std::io::ErrorKind::Other,
format!("failed to read markdown file for link extraction: {e}"),
))
PinakesError::Io(std::io::Error::other(format!(
"failed to read markdown file for link extraction: {e}"
)))
})?;
// Extract links