Add support for files in subdirectories
This commit is contained in:
Generated
+29
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
+24
-21
@@ -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 path = entry.path();
|
||||
if path.extension().unwrap_or_default().to_ascii_lowercase() == "jpg" {
|
||||
Some(path)
|
||||
} else {
|
||||
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().eq_ignore_ascii_case("jpg") {
|
||||
Some(path.to_path_buf())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
Err(error) => {
|
||||
tracing::error!("Could not read image dir: {:#}", error);
|
||||
None
|
||||
}
|
||||
}).collect()
|
||||
},
|
||||
Err(error) => {
|
||||
tracing::error!("Could not read images: {:#}", error);
|
||||
continue
|
||||
},
|
||||
};
|
||||
}
|
||||
}).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()
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user