fif/src/main.rs

105 lines
3.0 KiB
Rust

mod parameters;
use std::path::{Path};
use walkdir::{WalkDir, DirEntry};
use smartstring::alias::String;
use structopt::StructOpt;
use std::fs::File;
use std::io;
use std::io::Read;
use mime_guess;
use xdg_mime::SharedMimeInfo;
use mime_guess::Mime;
// TODO: test if this actually works on a windows machine
#[cfg(windows)]
fn is_hidden(entry: &DirEntry) -> bool {
use std::os::windows::prelude::*;
use std::fs;
fs::metadata(entry) // try to get metadata for file
.map_or(
false, // if getting metadata/attributes fails, assume it's not hidden
|f| f.file_attributes() & 0x2 // flag for hidden - https://docs.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
)
}
#[cfg(not(windows))]
fn is_hidden(entry: &DirEntry) -> bool {
entry.file_name().to_str().map_or(false, |f| f.starts_with("."))
}
fn ext_match(args: &parameters::Parameters, entry: &DirEntry) -> bool {
if entry.file_type().is_dir() {
return true;
}
if !args.scan_hidden && is_hidden(entry) {
return false;
}
let path = Path::new(entry.file_name());
if let Some(extensions) = &args.extensions {
return match path.extension() {
None => true,
Some(ext) => {
extensions.contains(&ext.to_string_lossy().into())
}
}
}
false
}
fn mime_type(db: &SharedMimeInfo, filepath: &Path) -> io::Result<Option<Mime>, > {
let mut buffer = [0; 1024];
// attempt to read up to the first kilobyte of the file
let mut file = File::open(filepath)?;
file.read(&mut buffer)?;
Ok(db.get_mime_type_for_data(&buffer).map(|m| m.0))
}
fn get_ext_from_mime(mime: &Mime) -> Option<String> {
match mime_guess::get_mime_extensions(mime) // get a list of possible extensions for this mime type
.map(|g| g[0]) { // take the first option in the list and return it as a string
// jpeg files are given the primary extension "jpe", due to the extension list being stored in alphabetical order.
// to handle this particular case, swap "jpe" out for "jpg", and leave everything else the same, making sure we
// convert the &strs to Strings.
Some("jpe") => Some(String::from("jpg")),
Some(ext) => Some(String::from(ext)),
None => None
}
}
fn main() {
let args = parameters::Parameters::from_args();
let db = xdg_mime::SharedMimeInfo::new();
println!("{:#?}", args);
// println!("{:#?}", args.dirs);
println!("=====\nIterating directory: {:?}\n=====", args.dirs);
let stepper = WalkDir::new(&args.dirs).into_iter();
for entry in stepper.filter_entry(|e| ext_match(&args, e)) {
let entry = entry.unwrap();
if !entry.file_type().is_file() {
println!("{} is not a file", entry.path().display());
continue
}
// let result = tree_magic_mini::from_filepath(entry.path()).unwrap_or("???");
let result = mime_type(&db, entry.path()).unwrap().unwrap();
println!(
"{} has type {}, extension should be {:?}",
entry.path().display(),
result,
get_ext_from_mime(&result)
);
}
// println!("WEBP CHECK: {:#?}", tree_magic_mini::match_filepath(
// "image/webp",
// Path::new("imgs/true_webp_lossless.webp"))
// );
}