From f846e3bce8bbfeb4ad30967e1e51fdd4bdde3230 Mon Sep 17 00:00:00 2001 From: Calle Helmertz Date: Tue, 20 Aug 2024 00:14:22 +0200 Subject: [PATCH] fix(filetype): infer after checking file ext We error out if trying to sort a directory with the image "a.jpg" which is constructed with "echo a>a.jpg". With this patch, "a.jpg" would be ignored and not cause an error, allowing image-sorter to continue with proper image files. --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/app.rs | 23 +++++++++++++++++++++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eee0f55..d99a3a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -158,6 +158,7 @@ dependencies = [ "anyhow", "crossbeam-channel", "expanduser", + "infer", "ratatui", "structopt", "subprocess", @@ -170,6 +171,12 @@ version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" +[[package]] +name = "infer" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "865e8a58ae8e24d2c4412c31344afa1d302a3740ad67528c10f50d6876cdcf55" + [[package]] name = "itertools" version = "0.11.0" diff --git a/Cargo.toml b/Cargo.toml index 94c029e..d390bb9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ subprocess = "0.2.6" ratatui = { version = "0.23", default-features = false, features = ["termion"] } termion = "2.0.1" crossbeam-channel = "0.5.0" +infer = "0.3" expanduser = "1.2.2" [[bin]] diff --git a/src/app.rs b/src/app.rs index ae017db..daade4a 100644 --- a/src/app.rs +++ b/src/app.rs @@ -258,9 +258,28 @@ impl App { } fn is_image(file: &Path) -> bool { + // first, a quick check for the file extension let image_exts = ["jpeg", "jpg", "png"]; - file.extension().map_or(false, |f| { + let looks_like_image = file.extension().map_or(false, |f| { image_exts.iter().any(|ext| f.to_str() == Some(ext)) - }) + }); + if !looks_like_image { + return false; + } + + // second, check the file's mime type by reading the first few bytes + let kind = infer::get_from_path(file); + if kind.is_err() { + // could not read file + return false; + } + let kind = kind.unwrap(); + if kind.is_none() { + // unknown file type + return false; + } + + let kind = kind.unwrap(); + matches!(kind.mime_type(), "image/jpeg" | "image/png") } }