Add support for files in subdirectories

This commit is contained in:
2026-06-22 19:44:15 +02:00
parent 286284300a
commit afeccc4738
3 changed files with 54 additions and 21 deletions
Generated
+29
View File
@@ -910,6 +910,7 @@ dependencies = [
"tower-http",
"tracing",
"tracing-subscriber",
"walkdir",
]
[[package]]
@@ -1366,6 +1367,15 @@ version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
@@ -1817,6 +1827,16 @@ version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
]
[[package]]
name = "want"
version = "0.3.1"
@@ -1924,6 +1944,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
+1
View File
@@ -21,3 +21,4 @@ tokio = { version = "1.25.0", features = ["full"] }
tower-http = { version = "0.3.5", features = ["fs", "trace", "compression-br"] }
tracing = "0.1.37"
tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
walkdir = "2.5.0"
+20 -17
View File
@@ -14,6 +14,7 @@ use tokio::{task, sync::Semaphore};
use tower_http::{trace::{self, TraceLayer}, compression::CompressionLayer};
use tracing::Level;
use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt};
use walkdir::WalkDir;
mod config;
mod error;
@@ -185,23 +186,24 @@ async fn update_config_and_image_list_cache_job(
};
// Read all image files from the image_dir
let images: HashSet<_> = match image_dir.read_dir() {
Ok(images) => {
// flatten ignores io error while traversing the iterator
images.flatten().filter_map(|entry| {
let images: HashSet<_> = WalkDir::new(&image_dir)
.into_iter()
.filter_map(|entry| {
match entry {
Ok(entry) => {
let path = entry.path();
if path.extension().unwrap_or_default().to_ascii_lowercase() == "jpg" {
Some(path)
if path.extension().unwrap_or_default().eq_ignore_ascii_case("jpg") {
Some(path.to_path_buf())
} else {
None
}
}).collect()
},
Err(error) => {
tracing::error!("Could not read images: {:#}", error);
continue
},
};
tracing::error!("Could not read image dir: {:#}", error);
None
}
}
}).collect();
let update_image_metadata = if image_dir_change != last_image_dir_change {
tracing::debug!("Update image list because image dir was modified");
@@ -221,8 +223,9 @@ async fn update_config_and_image_list_cache_job(
// Update image list
if update_image_metadata {
let images = images.clone();
let image_dir = image_dir.clone();
let image_metadata = task::spawn_blocking(move || {
read_image_metadata(&images)
read_image_metadata(&image_dir, &images)
}).await.unwrap_or_else(|error| {
tracing::error!("Could not read images due to panic: {:#}", error);
Vec::new()
@@ -349,7 +352,7 @@ async fn converted_image(
image_path.exists()
.then_some(())
.ok_or(anyhow!("Requested image not found!"))
.ok_or(anyhow!("Requested image {} not found!", image_path.display()))
.context(StatusCode::NOT_FOUND)?;
// Check if we have the file already in cache
@@ -465,11 +468,11 @@ fn fix_image_orientation(image: DynamicImage, exif: &Exif) -> DynamicImage {
}
}
fn read_image_metadata(images: &HashSet<PathBuf>) -> Vec<ImageInfo> {
fn read_image_metadata(image_dir: &Path, images: &HashSet<PathBuf>) -> Vec<ImageInfo> {
let mut files = vec![];
for path in images {
let image_info = match read_image_info(path) {
let image_info = match read_image_info(image_dir, path) {
Ok(image_info) => image_info,
Err(error) => {
tracing::warn!("Skipping {:?} due to error: {:#}", path, error);
@@ -491,7 +494,7 @@ fn extract_exif_string(field: &exif::Field) -> Option<String> {
}
}
fn read_image_info(path: &Path) -> Result<ImageInfo> {
fn read_image_info(image_dir: &Path, path: &Path) -> Result<ImageInfo> {
let file = File::open(path)?;
let mut file = BufReader::new(file);
@@ -534,7 +537,7 @@ fn read_image_info(path: &Path) -> Result<ImageInfo> {
width,
height,
created: datetime.unwrap_or_default(),
name: path.file_name().expect("invalid file path").to_owned(),
name: path.strip_prefix(image_dir).expect("invalid path prefix").into(),
..Default::default()
})
}