From 28d85dc4a57db01ec3afa32527651b28bfdd7022 Mon Sep 17 00:00:00 2001 From: Cameron Date: Thu, 18 Dec 2025 11:25:50 -0500 Subject: [PATCH] Fix recursive search and media filtering --- src/files.rs | 89 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 84 insertions(+), 5 deletions(-) diff --git a/src/files.rs b/src/files.rs index beb7916..b566b76 100644 --- a/src/files.rs +++ b/src/files.rs @@ -250,6 +250,15 @@ pub async fn list_photos( true } }) + .filter(|f| { + // Apply media type filtering if specified + if let Some(ref media_type) = req.media_type { + let path = PathBuf::from(&f.file_name); + matches_media_type(&path, media_type) + } else { + true + } + }) .collect::>() }) .map(|files| sort(files, req.sort.unwrap_or(NameAsc))) @@ -274,9 +283,33 @@ pub async fn list_photos( .unwrap_or_else(|e| e.error_response()); } - match file_system.get_files_for_path(search_path) { + // Use recursive or non-recursive file listing based on flag + let files_result = if search_recursively { + // For recursive search without tags, manually list files recursively + is_valid_full_path( + &PathBuf::from(&app_state.base_path), + &PathBuf::from(search_path), + false, + ) + .map(|path| { + debug!("Valid path for recursive search: {:?}", path); + list_files_recursive(&path).unwrap_or_default() + }) + .context("Invalid path") + } else { + file_system.get_files_for_path(search_path) + }; + + match files_result { Ok(files) => { - info!("Found {:?} files in path: {:?}", files.len(), search_path); + info!( + "Found {:?} files in path: {:?} (recursive: {})", + files.len(), + search_path, + search_recursively + ); + + info!("Starting to filter {} files from filesystem", files.len()); let photos = files .iter() @@ -356,11 +389,13 @@ pub async fn list_photos( }) .collect::>(); + info!("After all filters, {} files remain", photos.len()); + // Handle sorting - use FileWithMetadata for date sorting to support EXIF dates let response_files = if let Some(sort_type) = req.sort { match sort_type { SortType::DateTakenAsc | SortType::DateTakenDesc => { - debug!("Date sorting requested, fetching EXIF data"); + info!("Date sorting requested, fetching EXIF data"); // Collect file paths for batch EXIF query let file_paths: Vec = @@ -533,6 +568,43 @@ pub fn list_files(dir: &Path) -> io::Result> { Ok(files) } +pub fn list_files_recursive(dir: &Path) -> io::Result> { + let tracer = global_tracer(); + let mut span = tracer.start("list_files_recursive"); + let dir_name_string = dir.to_str().unwrap_or_default().to_string(); + span.set_attribute(KeyValue::new("dir", dir_name_string)); + info!("Recursively listing files in: {:?}", dir); + + let mut result = Vec::new(); + + fn visit_dirs(dir: &Path, files: &mut Vec) -> io::Result<()> { + if dir.is_dir() { + for entry in read_dir(dir)? { + let entry = entry?; + let path = entry.path(); + + if path.is_dir() { + visit_dirs(&path, files)?; + } else if is_image_or_video(&path) { + files.push(path); + } + } + } + Ok(()) + } + + visit_dirs(dir, &mut result)?; + + span.set_attribute(KeyValue::new("file_count", result.len().to_string())); + span.set_status(Status::Ok); + info!( + "Found {:?} files recursively in directory: {:?}", + result.len(), + dir + ); + Ok(result) +} + pub fn is_image_or_video(path: &Path) -> bool { let extension = path .extension() @@ -560,7 +632,7 @@ fn matches_media_type(path: &Path, media_type: &MediaType) -> bool { .and_then(|p| p.to_str()) .map_or(String::from(""), |p| p.to_lowercase()); - match media_type { + let result = match media_type { MediaType::All => true, MediaType::Photo => { extension == "png" @@ -575,7 +647,14 @@ fn matches_media_type(path: &Path, media_type: &MediaType) -> bool { || extension == "avif" } MediaType::Video => extension == "mp4" || extension == "mov", - } + }; + + debug!( + "Media type check: path={:?}, extension='{}', type={:?}, match={}", + path, extension, media_type, result + ); + + result } pub fn is_valid_full_path + Debug + AsRef>(