replace occurrences of "mimetype" w/ "MIME type"
This commit is contained in:
parent
ec10b58482
commit
33f4eb4135
8 changed files with 33 additions and 33 deletions
|
@ -132,7 +132,7 @@ this version of `clap`, which caused the build to fail. Also, `clap` 3 beta 4 de
|
||||||
- System extension set (`.dll`, `.so`, `.exe`...)
|
- System extension set (`.dll`, `.so`, `.exe`...)
|
||||||
- [`infer`] backend now supports Ren'Py archive (`.rpa`) files
|
- [`infer`] backend now supports Ren'Py archive (`.rpa`) files
|
||||||
### Changed
|
### Changed
|
||||||
- Output is now sorted: Files that couldn't be read, then files with no known mimetype, then files with no known
|
- Output is now sorted: Files that couldn't be read, then files with no known MIME type, then files with no known
|
||||||
extensions, then files with the wrong extension
|
extensions, then files with the wrong extension
|
||||||
- Added Apple iWork document formats to Documents extension set (`.pages`, `.key`, `.numbers`)
|
- Added Apple iWork document formats to Documents extension set (`.pages`, `.key`, `.numbers`)
|
||||||
### Fixed
|
### Fixed
|
||||||
|
@ -164,7 +164,7 @@ this version of `clap`, which caused the build to fail. Also, `clap` 3 beta 4 de
|
||||||
### Added
|
### Added
|
||||||
- fif can now traverse symlinks with the `-f`/`--follow-symlinks` flag
|
- fif can now traverse symlinks with the `-f`/`--follow-symlinks` flag
|
||||||
### Changed
|
### Changed
|
||||||
- Better mime type detection:
|
- Better MIME type detection:
|
||||||
- Consider "some/x-thing" and "some/thing" to be identical
|
- Consider "some/x-thing" and "some/thing" to be identical
|
||||||
- Use a patched version of mime_guess (which took a while to make 0u0;) with many more extension/type mappings
|
- Use a patched version of mime_guess (which took a while to make 0u0;) with many more extension/type mappings
|
||||||
- Extensions are no longer mandatory - running fif without `-e` or `-E` will scan all files, regardless of extension
|
- Extensions are no longer mandatory - running fif without `-e` or `-E` will scan all files, regardless of extension
|
||||||
|
|
|
@ -176,7 +176,7 @@ The five logging levels are used as follows:
|
||||||
| Level | Description | Example |
|
| Level | Description | Example |
|
||||||
|-|-|-|
|
|-|-|-|
|
||||||
| error | Errors that cause fif to stop running | fif was unable to open the provided directory |
|
| error | Errors that cause fif to stop running | fif was unable to open the provided directory |
|
||||||
| warn | Warnings that don't cause fif to stop running | fif was unable to determine the mime type of a given file |
|
| warn | Warnings that don't cause fif to stop running | fif was unable to determine the MIME type of a given file |
|
||||||
| info | Information pertaining to fif's status | The provided directory was scanned without issue, and no files are in need of renaming |
|
| info | Information pertaining to fif's status | The provided directory was scanned without issue, and no files are in need of renaming |
|
||||||
| debug | Debug information - usually not important to end users | The list of extensions fif will consider |
|
| debug | Debug information - usually not important to end users | The list of extensions fif will consider |
|
||||||
| trace | Trace info - usually not important to end users | "Found 15 items to check", "Scan successful", etc. |
|
| trace | Trace info - usually not important to end users | "Found 15 items to check", "Scan successful", etc. |
|
||||||
|
|
28
src/files.rs
28
src/files.rs
|
@ -22,10 +22,10 @@ use walkdir::{DirEntry, WalkDir};
|
||||||
use crate::findings::{Findings, ScanError};
|
use crate::findings::{Findings, ScanError};
|
||||||
use crate::mime_db::MimeDb;
|
use crate::mime_db::MimeDb;
|
||||||
use crate::parameters::ScanOpts;
|
use crate::parameters::ScanOpts;
|
||||||
use crate::{String, MIMEDB};
|
|
||||||
use crate::utils::APPLICATION_ZIP;
|
use crate::utils::APPLICATION_ZIP;
|
||||||
|
use crate::{String, MIMEDB};
|
||||||
|
|
||||||
/// Cache of mimetypes and their associated extensions, used by [`mime_extension_lookup()`]
|
/// Cache of MIME types and their associated extensions, used by [`mime_extension_lookup()`]
|
||||||
static MIMEXT: Lazy<RwLock<HashMap<String, Option<Vec<String>>>>> = Lazy::new(|| RwLock::new(HashMap::new()));
|
static MIMEXT: Lazy<RwLock<HashMap<String, Option<Vec<String>>>>> = Lazy::new(|| RwLock::new(HashMap::new()));
|
||||||
|
|
||||||
/// The number of bytes to read initially when identifying a file's MIME type. Used in the [`mime_type`] function.
|
/// The number of bytes to read initially when identifying a file's MIME type. Used in the [`mime_type`] function.
|
||||||
|
@ -39,7 +39,7 @@ pub const INITIAL_BUF_SIZE: usize = 128;
|
||||||
/// the [`mime_type`] function.
|
/// the [`mime_type`] function.
|
||||||
pub const BUF_SIZE: usize = 8192;
|
pub const BUF_SIZE: usize = 8192;
|
||||||
|
|
||||||
/// A [`Mime`] representing the "application/x-ole-storage" mimetype.
|
/// A [`Mime`] representing the "application/x-ole-storage" MIME type.
|
||||||
static APPLICATION_X_OLE_STORAGE: Lazy<Mime> = Lazy::new(|| Mime::from_str("application/x-ole-storage").unwrap());
|
static APPLICATION_X_OLE_STORAGE: Lazy<Mime> = Lazy::new(|| Mime::from_str("application/x-ole-storage").unwrap());
|
||||||
|
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
|
@ -114,29 +114,29 @@ pub fn wanted_file(
|
||||||
/// Inspects the given entry, returning a [`Findings`] on success and a [`ScanError`] on failure.
|
/// Inspects the given entry, returning a [`Findings`] on success and a [`ScanError`] on failure.
|
||||||
///
|
///
|
||||||
/// In the event of an IO error, the returned [`ScanError`] will be of type [`ScanError::File`]. Otherwise, a
|
/// In the event of an IO error, the returned [`ScanError`] will be of type [`ScanError::File`]. Otherwise, a
|
||||||
/// [`ScanError::Mime`] will be returned, meaning that the file was scanned successfully, but a mimetype could not be
|
/// [`ScanError::Mime`] will be returned, meaning that the file was scanned successfully, but a MIME type could not be
|
||||||
/// determined.
|
/// determined.
|
||||||
pub fn scan_file(entry: &DirEntry, canonical_paths: bool) -> Result<Findings, ScanError> {
|
pub fn scan_file(entry: &DirEntry, canonical_paths: bool) -> Result<Findings, ScanError> {
|
||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
// try to determine mimetype for this entry
|
// try to determine MIME type for this entry
|
||||||
let result = match mime_type(&*MIMEDB, path) {
|
let result = match mime_type(&*MIMEDB, path) {
|
||||||
// an error occurred while trying to read the file
|
// an error occurred while trying to read the file
|
||||||
Err(_) => return Err(ScanError::File(path)),
|
Err(_) => return Err(ScanError::File(path)),
|
||||||
// the file was read successfully, but we were unable to determine its mimetype
|
// the file was read successfully, but we were unable to determine its MIME type
|
||||||
Ok(None) => return Err(ScanError::Mime(path)),
|
Ok(None) => return Err(ScanError::Mime(path)),
|
||||||
// a mimetype was found!
|
// a MIME type was found!
|
||||||
Ok(Some(result)) => result,
|
Ok(Some(result)) => result,
|
||||||
};
|
};
|
||||||
|
|
||||||
// set of known extensions for the given mimetype
|
// set of known extensions for the given MIME type
|
||||||
let known_exts = mime_extension_lookup(result.essence_str().into());
|
let known_exts = mime_extension_lookup(result.essence_str().into());
|
||||||
// file extension for this particular file
|
// file extension for this particular file
|
||||||
let entry_ext = path.extension();
|
let entry_ext = path.extension();
|
||||||
|
|
||||||
let valid = match known_exts {
|
let valid = match known_exts {
|
||||||
// there is a known set of extensions for this mimetype, and the file has an extension
|
// there is a known set of extensions for this MIME type, and the file has an extension
|
||||||
Some(e) if entry_ext.is_some() => e.contains(&entry_ext.unwrap().to_string_lossy().to_lowercase().into()),
|
Some(e) if entry_ext.is_some() => e.contains(&entry_ext.unwrap().to_string_lossy().to_lowercase().into()),
|
||||||
// either this file has no extension, or there is no known set of extensions for this mimetype :(
|
// either this file has no extension, or there is no known set of extensions for this MIME type :(
|
||||||
Some(_) | None => false,
|
Some(_) | None => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -249,7 +249,7 @@ pub fn scan_directory(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tries to identify the mimetype of a file from a given path.
|
/// Tries to identify the MIME type of a file from a given path.
|
||||||
pub fn mime_type<T: MimeDb>(db: &T, path: &Path) -> io::Result<Option<Mime>> {
|
pub fn mime_type<T: MimeDb>(db: &T, path: &Path) -> io::Result<Option<Mime>> {
|
||||||
let mut buffer = [0; INITIAL_BUF_SIZE];
|
let mut buffer = [0; INITIAL_BUF_SIZE];
|
||||||
let mut file = File::open(path)?;
|
let mut file = File::open(path)?;
|
||||||
|
@ -278,7 +278,7 @@ pub fn mime_type<T: MimeDb>(db: &T, path: &Path) -> io::Result<Option<Mime>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let r = r.filter(|mime|
|
let r = r.filter(|mime|
|
||||||
// some mime types should be investigated further, reading up to BUF_SIZE even if they've been determined already
|
// some MIME types should be investigated further, reading up to BUF_SIZE even if they've been determined already
|
||||||
// one such type is XML - there's many more specific types that can be determined by reading further (such as SVG)
|
// one such type is XML - there's many more specific types that can be determined by reading further (such as SVG)
|
||||||
mime != &mime::TEXT_XML
|
mime != &mime::TEXT_XML
|
||||||
// another is ZIP - many file formats (DOCX, ODT, JAR...) are just ZIP files with particular data structures.
|
// another is ZIP - many file formats (DOCX, ODT, JAR...) are just ZIP files with particular data structures.
|
||||||
|
@ -301,7 +301,7 @@ pub fn mime_type<T: MimeDb>(db: &T, path: &Path) -> io::Result<Option<Mime>> {
|
||||||
Ok(db.get_type(&buffer))
|
Ok(db.get_type(&buffer))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of known extensions for this mime type, if any.
|
/// Returns a list of known extensions for this MIME type, if any.
|
||||||
/// This function uses the [`Mime`]'s "essence" rather than the [`Mime`] itself - [`mime_guess::get_mime_extensions`]
|
/// This function uses the [`Mime`]'s "essence" rather than the [`Mime`] itself - [`mime_guess::get_mime_extensions`]
|
||||||
/// ignores the type suffix, treating "image/svg+xml" as "image/svg", and thus fails to find any extensions. Passing the
|
/// ignores the type suffix, treating "image/svg+xml" as "image/svg", and thus fails to find any extensions. Passing the
|
||||||
/// `essence_str` (which includes the suffix) fixes this.
|
/// `essence_str` (which includes the suffix) fixes this.
|
||||||
|
@ -358,7 +358,7 @@ pub fn mime_extension_lookup(essence: String) -> Option<Vec<String>> {
|
||||||
]
|
]
|
||||||
.concat()
|
.concat()
|
||||||
} else if essence == "application/x-ms-dos-executable" {
|
} else if essence == "application/x-ms-dos-executable" {
|
||||||
// .dll, .exe, and .scr files are given the same mime type... but you definitely don't want to rename one to the
|
// .dll, .exe, and .scr files are given the same MIME type... but you definitely don't want to rename one to the
|
||||||
// other!
|
// other!
|
||||||
[vec![String::from("dll"), String::from("exe"), String::from("scr")], possible_exts].concat()
|
[vec![String::from("dll"), String::from("exe"), String::from("scr")], possible_exts].concat()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -20,9 +20,9 @@ use crate::String;
|
||||||
pub struct Findings {
|
pub struct Findings {
|
||||||
/// The location of the scanned file.
|
/// The location of the scanned file.
|
||||||
pub file: PathBuf,
|
pub file: PathBuf,
|
||||||
/// Whether or not the file's extension is valid for its mimetype.
|
/// Whether or not the file's extension is valid for its MIME type.
|
||||||
pub valid: bool,
|
pub valid: bool,
|
||||||
/// The file's mimetype.
|
/// The file's MIME type.
|
||||||
pub mime: Mime,
|
pub mime: Mime,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ impl serde::Serialize for Findings {
|
||||||
pub enum ScanError<'a> {
|
pub enum ScanError<'a> {
|
||||||
/// Something went wrong while trying to read the given file.
|
/// Something went wrong while trying to read the given file.
|
||||||
File(&'a Path),
|
File(&'a Path),
|
||||||
/// Failed to determine the mimetype of the given file.
|
/// Failed to determine the MIME type of the given file.
|
||||||
Mime(&'a Path),
|
Mime(&'a Path),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ impl<'a> Display for ScanError<'a> {
|
||||||
"Couldn't {} file: {}",
|
"Couldn't {} file: {}",
|
||||||
match self {
|
match self {
|
||||||
Self::File(_) => "read",
|
Self::File(_) => "read",
|
||||||
Self::Mime(_) => "determine mime type of",
|
Self::Mime(_) => "determine MIME type of",
|
||||||
},
|
},
|
||||||
match self {
|
match self {
|
||||||
Self::File(f) | Self::Mime(f) => f.to_string_lossy(),
|
Self::File(f) | Self::Mime(f) => f.to_string_lossy(),
|
||||||
|
|
|
@ -136,7 +136,7 @@ pub trait FormatSteps {
|
||||||
match error {
|
match error {
|
||||||
// failed to read the file
|
// failed to read the file
|
||||||
ScanError::File(path) => self.unreadable(f, path)?,
|
ScanError::File(path) => self.unreadable(f, path)?,
|
||||||
// file was read successfully, but we couldn't determine a mimetype
|
// file was read successfully, but we couldn't determine a MIME type
|
||||||
ScanError::Mime(path) => self.unknown_type(f, path)?,
|
ScanError::Mime(path) => self.unknown_type(f, path)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ impl FormatSteps for Shell {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unknown_type<W: Write>(&self, f: &mut W, path: &Path) -> io::Result<()> {
|
fn unknown_type<W: Write>(&self, f: &mut W, path: &Path) -> io::Result<()> {
|
||||||
smart_write(f, writablesln!["# Failed to detect mime type for ", path])
|
smart_write(f, writablesln!["# Failed to detect MIME type for ", path])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn header<W: Write>(&self, f: &mut W) -> io::Result<()> {
|
fn header<W: Write>(&self, f: &mut W) -> io::Result<()> {
|
||||||
|
@ -241,7 +241,7 @@ impl FormatSteps for PowerShell {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unknown_type<W: Write>(&self, f: &mut W, path: &Path) -> io::Result<()> {
|
fn unknown_type<W: Write>(&self, f: &mut W, path: &Path) -> io::Result<()> {
|
||||||
smart_write(f, writablesln!["<# Failed to detect mime type for ", path, " #>"])
|
smart_write(f, writablesln!["<# Failed to detect MIME type for ", path, " #>"])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn header<W: Write>(&self, f: &mut W) -> io::Result<()> {
|
fn header<W: Write>(&self, f: &mut W) -> io::Result<()> {
|
||||||
|
|
|
@ -18,7 +18,7 @@ use mime::Mime;
|
||||||
pub trait MimeDb {
|
pub trait MimeDb {
|
||||||
/// Initialise the database.
|
/// Initialise the database.
|
||||||
fn init() -> Self;
|
fn init() -> Self;
|
||||||
/// Given a slice of bytes, returns the inferred mimetype, if any.
|
/// Given a slice of bytes, returns the inferred MIME type, if any.
|
||||||
fn get_type(&self, data: &[u8]) -> Option<Mime>;
|
fn get_type(&self, data: &[u8]) -> Option<Mime>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ fn get_ext() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
/// Ensure that the mime types for JPEG, PNG, PDF, and ZIP are detected from their magic numbers.
|
/// Ensure that the MIME types for JPEG, PNG, PDF, and ZIP are detected from their magic numbers.
|
||||||
fn detect_type() {
|
fn detect_type() {
|
||||||
assert_eq!(MIMEDB.get_type(JPEG_BYTES), Some(IMAGE_JPEG));
|
assert_eq!(MIMEDB.get_type(JPEG_BYTES), Some(IMAGE_JPEG));
|
||||||
assert_eq!(MIMEDB.get_type(PNG_BYTES), Some(IMAGE_PNG));
|
assert_eq!(MIMEDB.get_type(PNG_BYTES), Some(IMAGE_PNG));
|
||||||
|
@ -71,7 +71,7 @@ fn recommend_ext() {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
/// Create a simple directory with some files, run `scan_directory` on it, and ensure that the files have their
|
/// Create a simple directory with some files, run `scan_directory` on it, and ensure that the files have their
|
||||||
/// associated mime types correctly deduced.
|
/// associated MIME types correctly deduced.
|
||||||
fn simple_directory() {
|
fn simple_directory() {
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::env::set_current_dir;
|
use std::env::set_current_dir;
|
||||||
|
@ -136,7 +136,7 @@ fn simple_directory() {
|
||||||
// the only invalid file detected should be "wrong.jpg", which is a misnamed png file
|
// the only invalid file detected should be "wrong.jpg", which is a misnamed png file
|
||||||
// 1. ensure detected extension is "jpg"
|
// 1. ensure detected extension is "jpg"
|
||||||
assert_eq!(result.file.as_path().extension().unwrap(), OsStr::new("jpg"));
|
assert_eq!(result.file.as_path().extension().unwrap(), OsStr::new("jpg"));
|
||||||
// 2. ensure detected mime type is IMAGE_PNG
|
// 2. ensure detected MIME type is IMAGE_PNG
|
||||||
assert_eq!(result.mime, IMAGE_PNG);
|
assert_eq!(result.mime, IMAGE_PNG);
|
||||||
// 3. ensure the recommended extension for "wrong.jpg" is "png"
|
// 3. ensure the recommended extension for "wrong.jpg" is "png"
|
||||||
assert_eq!(&result.recommended_extension().unwrap(), &String::from("png"));
|
assert_eq!(&result.recommended_extension().unwrap(), &String::from("png"));
|
||||||
|
@ -145,7 +145,7 @@ fn simple_directory() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the recommended extension for this file is in the list of known extensions for its mimetype - for
|
// check if the recommended extension for this file is in the list of known extensions for its MIME type - for
|
||||||
// example, if the file is determined to be an IMAGE_PNG, its recommended extension should be one of the extensions
|
// example, if the file is determined to be an IMAGE_PNG, its recommended extension should be one of the extensions
|
||||||
// returned by `mime_extension_lookup(IMAGE_PNG)`.
|
// returned by `mime_extension_lookup(IMAGE_PNG)`.
|
||||||
assert!(mime_extension_lookup(result.mime.essence_str().into())
|
assert!(mime_extension_lookup(result.mime.essence_str().into())
|
||||||
|
@ -161,8 +161,8 @@ fn simple_directory() {
|
||||||
.to_string_lossy()
|
.to_string_lossy()
|
||||||
.starts_with("test"));
|
.starts_with("test"));
|
||||||
|
|
||||||
// make sure the guessed mimetype is correct based on the extension of the scanned file
|
// make sure the guessed MIME type is correct based on the extension of the scanned file
|
||||||
// because we already know that the extensions match the mimetype (as we created these files ourselves earlier in
|
// because we already know that the extensions match the MIME type (as we created these files ourselves earlier in
|
||||||
// the test), all files with the "jpg" extension should be IMAGE_JPEGs, etc.
|
// the test), all files with the "jpg" extension should be IMAGE_JPEGs, etc.
|
||||||
let ext = result.file.as_path().extension().unwrap();
|
let ext = result.file.as_path().extension().unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -400,7 +400,7 @@ fn test_json() {
|
||||||
.read_to_string(&mut contents)
|
.read_to_string(&mut contents)
|
||||||
.expect("Failed to read from cursor to string");
|
.expect("Failed to read from cursor to string");
|
||||||
|
|
||||||
// the output should contain the file's mime type
|
// the output should contain the file's MIME type
|
||||||
assert!(
|
assert!(
|
||||||
contents.contains(IMAGE_JPEG.essence_str()),
|
contents.contains(IMAGE_JPEG.essence_str()),
|
||||||
"JSON output doesn't contain move command!\n===\n{}",
|
"JSON output doesn't contain move command!\n===\n{}",
|
||||||
|
|
|
@ -39,7 +39,7 @@ pub static CLAP_LONG_VERSION: Lazy<String> = Lazy::new(|| {
|
||||||
.into()
|
.into()
|
||||||
});
|
});
|
||||||
|
|
||||||
/// A [`Mime`] representing the "application/zip" mimetype.
|
/// A [`Mime`] representing the "application/zip" MIME type.
|
||||||
pub static APPLICATION_ZIP: Lazy<Mime> = Lazy::new(|| Mime::from_str("application/zip").unwrap());
|
pub static APPLICATION_ZIP: Lazy<Mime> = Lazy::new(|| Mime::from_str("application/zip").unwrap());
|
||||||
|
|
||||||
/// Returns the name of the target operating system with proper casing, like "Windows" or "macOS".
|
/// Returns the name of the target operating system with proper casing, like "Windows" or "macOS".
|
||||||
|
|
Loading…
Reference in a new issue