diff --git a/src/ai/handlers.rs b/src/ai/handlers.rs index 41a90b6..2fcfa06 100644 --- a/src/ai/handlers.rs +++ b/src/ai/handlers.rs @@ -222,13 +222,14 @@ pub async fn get_available_models_handler( let ollama_client = &app_state.ollama; // Fetch models with capabilities from primary server - let primary_models = match OllamaClient::list_models_with_capabilities(&ollama_client.primary_url).await { - Ok(models) => models, - Err(e) => { - log::warn!("Failed to fetch models from primary server: {:?}", e); - vec![] - } - }; + let primary_models = + match OllamaClient::list_models_with_capabilities(&ollama_client.primary_url).await { + Ok(models) => models, + Err(e) => { + log::warn!("Failed to fetch models from primary server: {:?}", e); + vec![] + } + }; let primary = ServerModels { url: ollama_client.primary_url.clone(), diff --git a/src/ai/insight_generator.rs b/src/ai/insight_generator.rs index 5bf96c6..bad9507 100644 --- a/src/ai/insight_generator.rs +++ b/src/ai/insight_generator.rs @@ -995,7 +995,10 @@ impl InsightGenerator { let image_base64 = if has_vision { match self.load_image_as_base64(&file_path) { Ok(b64) => { - log::info!("Successfully loaded image for vision-capable model '{}'", model_to_check); + log::info!( + "Successfully loaded image for vision-capable model '{}'", + model_to_check + ); Some(b64) } Err(e) => { diff --git a/src/ai/ollama.rs b/src/ai/ollama.rs index 8be9463..a9c9d35 100644 --- a/src/ai/ollama.rs +++ b/src/ai/ollama.rs @@ -63,7 +63,10 @@ impl OllamaClient { } /// Check if a model has vision capabilities using the /api/show endpoint - pub async fn check_model_capabilities(url: &str, model_name: &str) -> Result { + pub async fn check_model_capabilities( + url: &str, + model_name: &str, + ) -> Result { let client = Client::builder() .connect_timeout(Duration::from_secs(5)) .timeout(Duration::from_secs(10)) diff --git a/src/files.rs b/src/files.rs index 600445f..ab6f63e 100644 --- a/src/files.rs +++ b/src/files.rs @@ -1,3 +1,6 @@ +use ::anyhow; +use actix::{Handler, Message}; +use anyhow::{Context, anyhow}; use std::collections::HashSet; use std::fmt::Debug; use std::fs::read_dir; @@ -5,10 +8,7 @@ use std::io; use std::io::ErrorKind; use std::path::{Path, PathBuf}; use std::sync::Mutex; - -use ::anyhow; -use actix::{Handler, Message}; -use anyhow::{Context, anyhow}; +use std::time::SystemTime; use crate::data::{Claims, FilesRequest, FilterMode, MediaType, PhotosResponse, SortType}; use crate::database::ExifDao; @@ -22,6 +22,7 @@ use actix_web::{ HttpRequest, HttpResponse, web::{self, Query}, }; +use chrono::{DateTime, Utc}; use log::{debug, error, info, trace, warn}; use opentelemetry::KeyValue; use opentelemetry::trace::{Span, Status, TraceContextExt, Tracer}; @@ -73,18 +74,24 @@ fn apply_sorting_with_exif( .into_iter() .map(|f| { // Try EXIF date first - let date_taken = exif_map.get(&f.file_name).copied().or_else(|| { - // Fallback to filename extraction - extract_date_from_filename(&f.file_name).map(|dt| dt.timestamp()) - }).or_else(|| { - // Fallback to filesystem metadata creation date - let full_path = base_path.join(&f.file_name); - std::fs::metadata(full_path) - .and_then(|md| md.created()) - .ok() - .and_then(|ct| ct.duration_since(std::time::UNIX_EPOCH).ok()) - .map(|d| d.as_secs() as i64) - }); + let date_taken = exif_map + .get(&f.file_name) + .copied() + .or_else(|| { + // Fallback to filename extraction + extract_date_from_filename(&f.file_name).map(|dt| dt.timestamp()) + }) + .or_else(|| { + // Fallback to filesystem metadata creation date + let full_path = base_path.join(&f.file_name); + std::fs::metadata(full_path) + .and_then(|md| md.created().or(md.modified())) + .ok() + .map(|system_time| { + >>::into(system_time) + .timestamp() + }) + }); FileWithMetadata { file_name: f.file_name, @@ -332,8 +339,13 @@ pub async fn list_photos( // Handle sorting - use helper function that supports EXIF date sorting let sort_type = req.sort.unwrap_or(NameAsc); let mut exif_dao_guard = exif_dao.lock().expect("Unable to get ExifDao"); - let result = - apply_sorting_with_exif(files, sort_type, &mut exif_dao_guard, &span_context, (&app_state.base_path).as_ref()); + let result = apply_sorting_with_exif( + files, + sort_type, + &mut exif_dao_guard, + &span_context, + (&app_state.base_path).as_ref(), + ); drop(exif_dao_guard); result }) @@ -476,8 +488,13 @@ pub async fn list_photos( // Handle sorting - use helper function that supports EXIF date sorting let response_files = if let Some(sort_type) = req.sort { let mut exif_dao_guard = exif_dao.lock().expect("Unable to get ExifDao"); - let result = - apply_sorting_with_exif(photos, sort_type, &mut exif_dao_guard, &span_context, (&app_state.base_path).as_ref()); + let result = apply_sorting_with_exif( + photos, + sort_type, + &mut exif_dao_guard, + &span_context, + (&app_state.base_path).as_ref(), + ); drop(exif_dao_guard); result } else { diff --git a/src/main.rs b/src/main.rs index ec0f634..b37f5fd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,9 +28,9 @@ use actix_web::{ web::{self, BufMut, BytesMut}, }; use chrono::Utc; -use urlencoding::decode; use diesel::sqlite::Sqlite; use rayon::prelude::*; +use urlencoding::decode; use crate::ai::InsightGenerator; use crate::auth::login;