use xdg-mime by default on linux, infer elsewhere

This commit is contained in:
Lynne Megido 2021-02-27 12:02:49 +10:00
parent db94465bb7
commit b141b85ea7
Signed by: lynnesbian
GPG key ID: F0A184B5213D9F90
5 changed files with 23 additions and 17 deletions

1
Cargo.lock generated
View file

@ -179,6 +179,7 @@ name = "fif"
version = "0.2.4"
dependencies = [
"cached",
"cfg-if",
"clap",
"env_logger",
"exitcode",

View file

@ -15,10 +15,10 @@ exclude = [".idea/", "Cross.toml", "*.sh"]
#license-file = "LICENSE"
[features]
default = ["multi-threaded", "infer-backend"]
default = ["multi-threaded"]
multi-threaded = ["rayon"]
infer-backend = ["infer"]
xdg-mime-backend = ["xdg-mime"]
infer-backend = []
xdg-mime-backend = []
[dependencies]
walkdir = "2.3.1"
@ -27,13 +27,14 @@ smartstring = "0.2.6"
mime_guess = "2.0.3"
snailquote = "0.3.0"
once_cell = "1.5.2"
infer = { version = "0.3.4" }
rayon = { version = "1.5.0", optional = true }
infer = { version = "0.3.4", optional = true }
exitcode = "1.1.2"
cfg-if = "1.0.0"
# use git version while waiting on a release incorporating https://github.com/ebassi/xdg-mime-rs/commit/de5a6dd
[target.'cfg(not(target_os = "windows"))'.dependencies]
xdg-mime = {git = "https://github.com/ebassi/xdg-mime-rs", version = "0.3", rev = "de5a6dd", optional = true }
xdg-mime = {git = "https://github.com/ebassi/xdg-mime-rs", version = "0.3", rev = "de5a6dd" }
[dependencies.clap]
version = "3.0.0-beta.2"

View file

@ -10,8 +10,6 @@ use smartstring::alias::String;
use crate::mimedb::MimeDb;
// use log::{debug, warn};
// rather than reading once into a large buffer, it tends to be faster to first try identifying the file from a small
// chunk read from the top, and *then* proceeding with the large buffer. many file formats can be easily identified by
// the first 128 bytes. of course, not all formats can, and some (OOXML...) require reading a long ways in.
@ -87,6 +85,11 @@ cached! {
} else if mime == Mime::from_str("application/msword").unwrap() {
// classic office files considered harmful
vec![String::from("doc"), String::from("xls"), String::from("ppt")]
} else if mime == Mime::from_str("application/zip").unwrap() {
// neither xdg-mime nor infer seem to be able to detect office XML files properly...
[vec![String::from("zip"), String::from("docx"), String::from("xlsx"), String::from("pptx")], possible_exts].concat()
} else {
possible_exts
})

View file

@ -40,10 +40,10 @@ mod mimedb;
mod parameters;
mod scanerror;
#[cfg(feature = "infer-backend")]
#[cfg(any(all(not(target_os = "linux"), not(feature = "xdg-mime-backend")), all(target_os = "linux", feature = "infer-backend")))]
static MIMEDB: OnceCell<mimedb::InferDb> = OnceCell::new();
#[cfg(feature = "xdg-mime-backend")]
#[cfg(any(all(target_os = "linux", not(feature = "infer-backend")), all(not(target_os = "linux"), not(feature = "xdg-mime-backend"))))]
static MIMEDB: OnceCell<mimedb::XdgDb> = OnceCell::new();
// TODO: test if this actually works on a windows machine
@ -162,13 +162,13 @@ fn main() {
// .target(env_logger::Target::Stdout) // log to stdout rather than stderr
.init();
#[cfg(feature = "infer-backend")]
MIMEDB
#[cfg(any(all(not(target_os = "linux"), not(feature = "xdg-mime-backend")), all(target_os = "linux", feature = "infer-backend")))]
MIMEDB
.set(mimedb::InferDb::init())
.or(Err("Failed to initialise Infer backend!"))
.unwrap();
#[cfg(feature = "xdg-mime-backend")]
#[cfg(any(all(target_os = "linux", not(feature = "infer-backend")), all(not(target_os = "linux"), not(feature = "xdg-mime-backend"))))]
MIMEDB
.set(mimedb::XdgDb::init())
.or(Err("Failed to initialise XDG Mime backend!"))

View file

@ -1,4 +1,4 @@
#[cfg(feature = "infer-backend")]
#[cfg(any(all(not(target_os = "linux"), not(feature = "xdg-mime-backend")), all(target_os = "linux", feature = "infer-backend")))]
use std::str::FromStr;
use mime_guess::Mime;
@ -8,11 +8,12 @@ pub trait MimeDb {
fn get_type(&self, data: &[u8]) -> Option<Mime>;
}
#[cfg(feature = "infer-backend")]
#[cfg(any(all(not(target_os = "linux"), not(feature = "xdg-mime-backend")), all(target_os = "linux", feature = "infer-backend")))]
pub struct InferDb {
db: infer::Infer,
}
#[cfg(any(all(not(target_os = "linux"), not(feature = "xdg-mime-backend")), all(target_os = "linux", feature = "infer-backend")))]
fn open_document_check(buf: &[u8], kind: &str) -> bool {
let mime = format!("application/vnd.oasis.opendocument.{}", kind);
let mime = mime.as_bytes();
@ -20,7 +21,7 @@ fn open_document_check(buf: &[u8], kind: &str) -> bool {
buf.len() > 38 + mime.len() && buf.starts_with(b"PK\x03\x04") && buf[38..mime.len() + 38] == mime[..]
}
#[cfg(feature = "infer-backend")]
#[cfg(any(all(not(target_os = "linux"), not(feature = "xdg-mime-backend")), all(target_os = "linux", feature = "infer-backend")))]
impl MimeDb for InferDb {
fn init() -> Self {
let mut info = infer::Infer::new();
@ -82,12 +83,12 @@ impl MimeDb for InferDb {
}
}
#[cfg(feature = "xdg-mime-backend")]
#[cfg(any(all(target_os = "linux", not(feature = "infer-backend")), all(not(target_os = "linux"), not(feature = "xdg-mime-backend"))))]
pub struct XdgDb {
db: xdg_mime::SharedMimeInfo,
}
#[cfg(feature = "xdg-mime-backend")]
#[cfg(any(all(target_os = "linux", not(feature = "infer-backend")), all(not(target_os = "linux"), not(feature = "xdg-mime-backend"))))]
impl MimeDb for XdgDb {
fn init() -> Self {
Self {