From df2f924b2fa04b4bc30607b23aa1ec1c9a7ce78e Mon Sep 17 00:00:00 2001 From: Lynnesbian Date: Thu, 18 Feb 2021 21:43:24 +1000 Subject: [PATCH] added some extension sets, replaced 'echo' with 'printf' in shell output --- .idea/csv-plugin.xml | 23 +++++++++++++++++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- src/extensionset.rs | 24 ++++++++++++++++++++++++ src/formats.rs | 9 +++++---- src/main.rs | 24 +++++++++++++++++------- src/parameters.rs | 9 +++++++-- 7 files changed, 78 insertions(+), 15 deletions(-) create mode 100644 .idea/csv-plugin.xml create mode 100644 src/extensionset.rs diff --git a/.idea/csv-plugin.xml b/.idea/csv-plugin.xml new file mode 100644 index 0000000..4423c5a --- /dev/null +++ b/.idea/csv-plugin.xml @@ -0,0 +1,23 @@ + + + + + + \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 9539096..9f6ef7a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -169,7 +169,7 @@ dependencies = [ [[package]] name = "fif" -version = "0.2.0" +version = "0.2.1" dependencies = [ "cached", "clap", diff --git a/Cargo.toml b/Cargo.toml index d5ca04b..4782794 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "fif" description = "A command-line tool for detecting and optionally correcting files with incorrect extensions." -version = "0.2.0" +version = "0.2.1" authors = ["Lynnesbian "] edition = "2018" license = "GPL-3.0-or-later" diff --git a/src/extensionset.rs b/src/extensionset.rs new file mode 100644 index 0000000..c8bf4ba --- /dev/null +++ b/src/extensionset.rs @@ -0,0 +1,24 @@ +use clap::Clap; + +#[derive(Clap, PartialEq, Debug)] +pub enum ExtensionSet { + Images, + Audio, + Videos, + Media, + Documents, + Archives +} + +impl ExtensionSet { + pub fn extensions(&self) -> Vec<&str> { + match self { + Self::Images => vec!["png", "jpg", "jpeg", "webp", "raw", "gif", "apng", "tga", "bmp", "tif", "tiff", "heif", + "avif", "jp2", "mng", "svg"], + Self::Videos => vec!["webm", "mp4", "mkv", "mov", "avi", "m4v", "wmv", "bik", "ogv", "qt", "3gp", "3g2", "divx"], + Self::Audio => vec!["ogg", "oga", "opus", "mp3", "m4a", "aac", "flac", "ape", "midi", "mid", "alac", "wav", + "aiff", "aa3", "at3"], + _ => todo!() + } + } +} \ No newline at end of file diff --git a/src/formats.rs b/src/formats.rs index bb612c9..a391537 100644 --- a/src/formats.rs +++ b/src/formats.rs @@ -72,6 +72,7 @@ pub trait Format { } } +// TODO: maybe make a batch script version for windows pub struct Script {} impl Format for Script { @@ -89,9 +90,9 @@ impl Format for Script { } fn no_known_extension(&self, f: &mut W, path: &PathBuf) -> io::Result<()> { - write!(f, "echo No known extension for ")?; + write!(f, "printf No known extension for ")?; write_pathbuf(f, path)?; - writeln!(f,) + writeln!(f,"\nprintf '\n'") } fn unreadable(&self, f: &mut W, path: &PathBuf) -> io::Result<()> { @@ -109,12 +110,12 @@ impl Format for Script { fn header(&self, _: &Entries, f: &mut W) -> io::Result<()> { write!( f, - "#!/usr/bin/env sh\n\nGenerated by fif {}.\n\n", + "#!/usr/bin/env sh\n# Generated by fif {}.\n\nset -e\n\n", VERSION.unwrap_or("???") ) } fn footer(&self, _: &Entries, f: &mut W) -> io::Result<()> { - writeln!(f, "\necho Done.") + writeln!(f, "\nprintf 'Done.\\n'") } } diff --git a/src/main.rs b/src/main.rs index a7eab3d..04d0a41 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,6 +37,7 @@ mod inspectors; mod mimedb; mod parameters; mod scanerror; +mod extensionset; #[cfg(feature = "infer-backend")] static MIMEDB: OnceCell = OnceCell::new(); @@ -63,7 +64,7 @@ fn is_hidden(entry: &DirEntry) -> bool { .map_or(false, |f| f.starts_with('.') && f != ".") } -fn wanted_file(args: ¶meters::Parameters, entry: &DirEntry) -> bool { +fn wanted_file(args: ¶meters::Parameters, exts: &Vec<&str>, entry: &DirEntry) -> bool { if !args.scan_hidden && is_hidden(entry) { // skip hidden files and directories. this check is performed first because it's very lightweight. return false; @@ -80,11 +81,7 @@ fn wanted_file(args: ¶meters::Parameters, entry: &DirEntry) -> bool { return false; } // don't scan files without extensions. TODO - this should be configurable - if let Some(extensions) = &args.extensions { - // if the user has specified a list of extensions to check against, make sure this file ends in one of them. - return extensions.contains(&ext.unwrap().to_lowercase().into()); - } - true + exts.contains(&ext.unwrap().to_lowercase().as_str()) } fn extension_from_path(path: &Path) -> Option { @@ -179,9 +176,22 @@ fn main() { debug!("Iterating directory: {:?}", args.dirs); + let extensions: Vec<&str> = if let Some(exts) = &args.exts { + exts + .iter() + .map(|s| s.as_str()) + .collect() + } else if let Some(exts) = &args.ext_set { + exts.extensions().to_vec() + } else { + unreachable!() + }; + + debug!("Checking files with extensions: {:?}", extensions); + let stepper = WalkDir::new(&args.dirs).into_iter(); let entries: Vec = stepper - .filter_entry(|e| wanted_file(&args, e)) // filter out unwanted files + .filter_entry(|e| wanted_file(&args, &extensions, e)) // filter out unwanted files .filter_map(|e| e.ok()) // ignore anything that fails, e.g. files we don't have read access on .filter(|e| !e.file_type().is_dir()) // remove directories from the final list .collect(); diff --git a/src/parameters.rs b/src/parameters.rs index bd398c5..5b9bc97 100644 --- a/src/parameters.rs +++ b/src/parameters.rs @@ -2,6 +2,7 @@ use std::path::PathBuf; use clap::Clap; use smartstring::{LazyCompact, SmartString}; +use crate::extensionset::ExtensionSet; #[derive(Clap, PartialEq, Debug)] pub enum OutputFormat { @@ -12,8 +13,12 @@ pub enum OutputFormat { #[derive(Clap, Debug)] pub struct Parameters { /// Only examine files with these extensions (Comma-separated list) - #[clap(short, long, use_delimiter = true, require_delimiter = true)] - pub extensions: Option>>, + #[clap(short, long, use_delimiter = true, require_delimiter = true, required_unless_present = "ext-set")] + pub exts: Option>>, + + /// write good docs 0uo + #[clap(short = 'E', long, arg_enum, required_unless_present = "exts")] + pub ext_set: Option, /// Don't skip hidden files and directories #[clap(short, long)]