Fix Recursive searching with tags including Any and All filter modes
This commit is contained in:
55
src/files.rs
55
src/files.rs
@@ -14,16 +14,16 @@ use actix_web::{
|
||||
web::{self, Query},
|
||||
HttpResponse,
|
||||
};
|
||||
use log::{debug, error, info};
|
||||
use log::{debug, error, info, trace};
|
||||
|
||||
use crate::data::{Claims, FilesRequest, FilterMode, PhotosResponse};
|
||||
use crate::{AppState, create_thumbnails};
|
||||
use crate::{create_thumbnails, AppState};
|
||||
|
||||
use crate::error::IntoHttpError;
|
||||
use crate::tags::TagDao;
|
||||
use crate::video::StreamActor;
|
||||
use path_absolutize::*;
|
||||
use serde::Deserialize;
|
||||
use crate::video::StreamActor;
|
||||
|
||||
pub async fn list_photos<TagD: TagDao, FS: FileSystemAccess>(
|
||||
_: Claims,
|
||||
@@ -34,10 +34,15 @@ pub async fn list_photos<TagD: TagDao, FS: FileSystemAccess>(
|
||||
) -> HttpResponse {
|
||||
let path = &req.path;
|
||||
|
||||
// Do we need this?
|
||||
if let (Some(tag_ids), Some(filter_mode)) = (&req.tag_ids, &req.tag_filter_mode) {
|
||||
let search_recursively = &req.recursive.unwrap_or(false);
|
||||
let search_recursively = req.recursive.unwrap_or(false);
|
||||
if let Some(tag_ids) = &req.tag_ids {
|
||||
if search_recursively {
|
||||
let filter_mode = req.tag_filter_mode.unwrap_or(FilterMode::Any);
|
||||
debug!(
|
||||
"Searching for tags: {}. With path: '{}' and filter mode: {:?}",
|
||||
tag_ids, path, filter_mode
|
||||
);
|
||||
|
||||
let mut dao = tag_dao.lock().expect("Unable to get TagDao");
|
||||
let tag_ids = tag_ids
|
||||
.split(',')
|
||||
@@ -45,9 +50,24 @@ pub async fn list_photos<TagD: TagDao, FS: FileSystemAccess>(
|
||||
.collect::<Vec<i32>>();
|
||||
|
||||
return dao
|
||||
.get_files_with_tag_ids(tag_ids.clone())
|
||||
.get_files_with_any_tag_ids(tag_ids.clone())
|
||||
.context(format!("Failed to get files with tag_ids: {:?}", tag_ids))
|
||||
.map(|tagged_files| match filter_mode {
|
||||
FilterMode::Any => tagged_files,
|
||||
FilterMode::All => tagged_files
|
||||
.iter()
|
||||
.filter(|&file_path| {
|
||||
let file_tags = dao.get_tags_for_path(file_path).unwrap_or_default();
|
||||
tag_ids
|
||||
.iter()
|
||||
.all(|id| file_tags.iter().any(|tag| &tag.id == id))
|
||||
})
|
||||
.cloned()
|
||||
.collect::<Vec<String>>(),
|
||||
})
|
||||
.map(|tagged_files| {
|
||||
trace!("Found tagged files: {:?}", tagged_files);
|
||||
|
||||
HttpResponse::Ok().json(PhotosResponse {
|
||||
photos: tagged_files,
|
||||
dirs: vec![],
|
||||
@@ -59,7 +79,7 @@ pub async fn list_photos<TagD: TagDao, FS: FileSystemAccess>(
|
||||
}
|
||||
|
||||
if let Ok(files) = file_system.get_files_for_path(path) {
|
||||
debug!("Valid path: {:?}", path);
|
||||
debug!("Valid search path: {:?}", path);
|
||||
|
||||
let photos = files
|
||||
.iter()
|
||||
@@ -78,12 +98,6 @@ pub async fn list_photos<TagD: TagDao, FS: FileSystemAccess>(
|
||||
})
|
||||
.map(|f| f.to_str().unwrap().to_string())
|
||||
.filter(|file_path| {
|
||||
let recursive = req.recursive.unwrap_or(false);
|
||||
let file_slash_count = file_path.split("/").collect::<Vec<&str>>().len();
|
||||
let filter_path_slash_count = path.split("/").collect::<Vec<&str>>().len();
|
||||
// Skip if this path is below/deeper than the search path
|
||||
if !recursive && file_slash_count > filter_path_slash_count { return false; }
|
||||
|
||||
if let (Some(tag_ids), Ok(mut tag_dao)) = (&req.tag_ids, tag_dao.lock()) {
|
||||
let tag_ids = tag_ids
|
||||
.split(',')
|
||||
@@ -91,7 +105,6 @@ pub async fn list_photos<TagD: TagDao, FS: FileSystemAccess>(
|
||||
.collect::<Vec<i32>>();
|
||||
|
||||
let filter_mode = &req.tag_filter_mode.unwrap_or(FilterMode::Any);
|
||||
|
||||
let file_tags = tag_dao.get_tags_for_path(file_path).unwrap_or_default();
|
||||
|
||||
return match filter_mode {
|
||||
@@ -152,7 +165,7 @@ pub fn is_valid_full_path<P: AsRef<Path> + Debug + AsRef<std::ffi::OsStr>>(
|
||||
path: &P,
|
||||
new_file: bool,
|
||||
) -> Option<PathBuf> {
|
||||
debug!("Base: {:?}. Path: {:?}", base, path);
|
||||
trace!("is_valid_full_path => Base: {:?}. Path: {:?}", base, path);
|
||||
|
||||
let path = PathBuf::from(&path);
|
||||
let mut path = if path.is_relative() {
|
||||
@@ -398,7 +411,7 @@ mod tests {
|
||||
Data::new(RealFileSystem::new(String::from("/tmp"))),
|
||||
Data::new(Mutex::new(SqliteTagDao::default())),
|
||||
)
|
||||
.await;
|
||||
.await;
|
||||
let status = response.status();
|
||||
assert_eq!(status, 200);
|
||||
|
||||
@@ -438,7 +451,7 @@ mod tests {
|
||||
Data::new(RealFileSystem::new(String::from("./"))),
|
||||
Data::new(Mutex::new(SqliteTagDao::default())),
|
||||
)
|
||||
.await;
|
||||
.await;
|
||||
|
||||
assert_eq!(response.status(), 400);
|
||||
}
|
||||
@@ -484,7 +497,7 @@ mod tests {
|
||||
Data::new(FakeFileSystem::new(files)),
|
||||
Data::new(Mutex::new(tag_dao)),
|
||||
)
|
||||
.await;
|
||||
.await;
|
||||
|
||||
assert_eq!(200, response.status());
|
||||
|
||||
@@ -528,7 +541,7 @@ mod tests {
|
||||
"path=&tag_ids={},{}&tag_filter_mode=All",
|
||||
tag1.id, tag3.id
|
||||
))
|
||||
.unwrap();
|
||||
.unwrap();
|
||||
|
||||
let response: HttpResponse = list_photos(
|
||||
claims,
|
||||
@@ -541,7 +554,7 @@ mod tests {
|
||||
Data::new(FakeFileSystem::new(files)),
|
||||
Data::new(Mutex::new(tag_dao)),
|
||||
)
|
||||
.await;
|
||||
.await;
|
||||
|
||||
assert_eq!(200, response.status());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user