Fix recursive search and media filtering
This commit is contained in:
89
src/files.rs
89
src/files.rs
@@ -250,6 +250,15 @@ pub async fn list_photos<TagD: TagDao, FS: FileSystemAccess>(
|
||||
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::<Vec<FileWithTagCount>>()
|
||||
})
|
||||
.map(|files| sort(files, req.sort.unwrap_or(NameAsc)))
|
||||
@@ -274,9 +283,33 @@ pub async fn list_photos<TagD: TagDao, FS: FileSystemAccess>(
|
||||
.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<TagD: TagDao, FS: FileSystemAccess>(
|
||||
})
|
||||
.collect::<Vec<FileWithTagCount>>();
|
||||
|
||||
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<String> =
|
||||
@@ -533,6 +568,43 @@ pub fn list_files(dir: &Path) -> io::Result<Vec<PathBuf>> {
|
||||
Ok(files)
|
||||
}
|
||||
|
||||
pub fn list_files_recursive(dir: &Path) -> io::Result<Vec<PathBuf>> {
|
||||
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<PathBuf>) -> 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<P: AsRef<Path> + Debug + AsRef<std::ffi::OsStr>>(
|
||||
|
||||
Reference in New Issue
Block a user