fif/src/main.rs

86 lines
3.0 KiB
Rust
Raw Normal View History

// fif - File Info Fixer
// Copyright (C) 2021 Lynnesbian
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
2021-02-04 11:22:19 +00:00
mod parameters;
2021-02-05 09:15:12 +00:00
mod inspectors;
2021-02-04 11:22:19 +00:00
use std::path::{Path};
use walkdir::{WalkDir, DirEntry};
use smartstring::alias::String;
use structopt::StructOpt;
2021-02-05 09:15:12 +00:00
use log::{info};
2021-02-04 11:22:19 +00:00
// 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('.') && f != ".")
2021-02-04 11:22:19 +00:00
}
2021-02-05 09:15:12 +00:00
fn wanted_file(args: &parameters::Parameters, 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;
}
2021-02-04 11:22:19 +00:00
if entry.file_type().is_dir() {
// always allow directories - there's no point doing file extension matching on something that isn't a file.
2021-02-04 11:22:19 +00:00
return true;
}
let ext = Path::new(entry.file_name()) // create a Path from the entry...
.extension() // get its extension...
.map(|e| String::from(e.to_string_lossy())); // and convert it from an OsStr to a String.
2021-02-04 11:22:19 +00:00
if ext.is_none() { return false } // don't scan files without extensions. TODO - this should be configurable
2021-02-04 11:22:19 +00:00
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.
// TODO - maybe use ascii_lowercase instead?
return extensions.contains(&ext.unwrap().to_ascii_lowercase().into())
2021-02-04 11:22:19 +00:00
}
true
2021-02-04 11:22:19 +00:00
}
fn main() {
let args = parameters::Parameters::from_args();
2021-02-05 09:15:12 +00:00
// env_logger::init();
2021-02-04 11:22:19 +00:00
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();
2021-02-05 09:15:12 +00:00
let entries: Vec<DirEntry> = stepper
.filter_entry(|e| wanted_file(&args, e)) // filter out unwanted files
.filter_map(|e| e.ok()) // ignore anything that fails, e.g. files we don't have read access on
.collect();
2021-02-05 09:15:12 +00:00
info!("Found {} items to check", entries.len());
2021-02-05 09:15:12 +00:00
// println!("{:#?}", entries);
2021-02-04 11:22:19 +00:00
}