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
|
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>>()
|
.collect::<Vec<FileWithTagCount>>()
|
||||||
})
|
})
|
||||||
.map(|files| sort(files, req.sort.unwrap_or(NameAsc)))
|
.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());
|
.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) => {
|
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
|
let photos = files
|
||||||
.iter()
|
.iter()
|
||||||
@@ -356,11 +389,13 @@ pub async fn list_photos<TagD: TagDao, FS: FileSystemAccess>(
|
|||||||
})
|
})
|
||||||
.collect::<Vec<FileWithTagCount>>();
|
.collect::<Vec<FileWithTagCount>>();
|
||||||
|
|
||||||
|
info!("After all filters, {} files remain", photos.len());
|
||||||
|
|
||||||
// Handle sorting - use FileWithMetadata for date sorting to support EXIF dates
|
// Handle sorting - use FileWithMetadata for date sorting to support EXIF dates
|
||||||
let response_files = if let Some(sort_type) = req.sort {
|
let response_files = if let Some(sort_type) = req.sort {
|
||||||
match sort_type {
|
match sort_type {
|
||||||
SortType::DateTakenAsc | SortType::DateTakenDesc => {
|
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
|
// Collect file paths for batch EXIF query
|
||||||
let file_paths: Vec<String> =
|
let file_paths: Vec<String> =
|
||||||
@@ -533,6 +568,43 @@ pub fn list_files(dir: &Path) -> io::Result<Vec<PathBuf>> {
|
|||||||
Ok(files)
|
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 {
|
pub fn is_image_or_video(path: &Path) -> bool {
|
||||||
let extension = path
|
let extension = path
|
||||||
.extension()
|
.extension()
|
||||||
@@ -560,7 +632,7 @@ fn matches_media_type(path: &Path, media_type: &MediaType) -> bool {
|
|||||||
.and_then(|p| p.to_str())
|
.and_then(|p| p.to_str())
|
||||||
.map_or(String::from(""), |p| p.to_lowercase());
|
.map_or(String::from(""), |p| p.to_lowercase());
|
||||||
|
|
||||||
match media_type {
|
let result = match media_type {
|
||||||
MediaType::All => true,
|
MediaType::All => true,
|
||||||
MediaType::Photo => {
|
MediaType::Photo => {
|
||||||
extension == "png"
|
extension == "png"
|
||||||
@@ -575,7 +647,14 @@ fn matches_media_type(path: &Path, media_type: &MediaType) -> bool {
|
|||||||
|| extension == "avif"
|
|| extension == "avif"
|
||||||
}
|
}
|
||||||
MediaType::Video => extension == "mp4" || extension == "mov",
|
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>>(
|
pub fn is_valid_full_path<P: AsRef<Path> + Debug + AsRef<std::ffi::OsStr>>(
|
||||||
|
|||||||
Reference in New Issue
Block a user