mirror of
https://github.com/chmln/handlr.git
synced 2024-11-27 03:13:49 +01:00
more reliable matching using libmagic
This commit is contained in:
parent
5c49436b62
commit
4f2940135e
6 changed files with 56 additions and 153 deletions
154
Cargo.lock
generated
154
Cargo.lock
generated
|
@ -6,15 +6,6 @@ version = "0.3.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9"
|
||||
dependencies = [
|
||||
"nodrop",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.5.1"
|
||||
|
@ -56,6 +47,12 @@ version = "0.12.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d1ccbaf7d9ec9537465a97bf19edc1a4e158ecb49fc16178202238c569cc42"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
|
@ -69,7 +66,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec 0.5.1",
|
||||
"arrayvec",
|
||||
"constant_time_eq",
|
||||
]
|
||||
|
||||
|
@ -137,7 +134,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "860643c53f980f0d38a5e25dfab6c3c93b2cb3aa1fe192643d17a293c6c41936"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"bitflags 1.2.1",
|
||||
"clap_derive",
|
||||
"indexmap",
|
||||
"lazy_static",
|
||||
|
@ -225,16 +222,6 @@ dependencies = [
|
|||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13aea89a5c93364a98e9b37b2fa237effbb694d5cfe01c5b70941f7eb087d5e3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.3.5"
|
||||
|
@ -300,7 +287,7 @@ version = "0.3.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.2.1",
|
||||
"fuchsia-zircon-sys",
|
||||
]
|
||||
|
||||
|
@ -369,12 +356,6 @@ dependencies = [
|
|||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.2.5"
|
||||
|
@ -406,7 +387,7 @@ dependencies = [
|
|||
"json",
|
||||
"mime",
|
||||
"mime-db",
|
||||
"once_cell",
|
||||
"mime-detective",
|
||||
"pest",
|
||||
"pest_derive",
|
||||
"regex",
|
||||
|
@ -415,7 +396,6 @@ dependencies = [
|
|||
"thiserror",
|
||||
"url",
|
||||
"xdg",
|
||||
"xdg-mime",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -575,20 +555,6 @@ version = "1.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lexical-core"
|
||||
version = "0.6.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f86d66d380c9c5a685aaac7a11818bdfa1f733198dfd9ec09c70b762cd12ad6f"
|
||||
dependencies = [
|
||||
"arrayvec 0.4.12",
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"rustc_version",
|
||||
"ryu",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.71"
|
||||
|
@ -604,6 +570,26 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "magic"
|
||||
version = "0.12.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96f74caec41a12630bb8fd9546530a41addb720eb0c10593855f59ce96a779aa"
|
||||
dependencies = [
|
||||
"bitflags 0.7.0",
|
||||
"libc",
|
||||
"magic-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "magic-sys"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17442cc60e34d501588c95bc976da04b6a87c51ab02370e95e1c2893a52df16c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "maplit"
|
||||
version = "1.0.2"
|
||||
|
@ -640,6 +626,16 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mime-detective"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "691f45910296797c90bd9f536428635cf813a59073a3a5af93e208c428c9b4e9"
|
||||
dependencies = [
|
||||
"magic",
|
||||
"mime",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mime_guess"
|
||||
version = "2.0.3"
|
||||
|
@ -710,23 +706,6 @@ dependencies = [
|
|||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nodrop"
|
||||
version = "0.1.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "5.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b471253da97532da4b61552249c521e01e736071f71c1a4f7ebbfbf0a06aad6"
|
||||
dependencies = [
|
||||
"lexical-core",
|
||||
"memchr",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.0"
|
||||
|
@ -737,12 +716,6 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.2.3"
|
||||
|
@ -755,7 +728,7 @@ version = "0.10.29"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cee6d85f4cb4c4f59a6a85d5b68a233d280c82e29e822913b9c8b129fbf20bdd"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.2.1",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"lazy_static",
|
||||
|
@ -1054,15 +1027,6 @@ dependencies = [
|
|||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.5"
|
||||
|
@ -1085,7 +1049,7 @@ version = "0.4.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bitflags 1.2.1",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
|
@ -1102,21 +1066,6 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
dependencies = [
|
||||
"semver-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.111"
|
||||
|
@ -1202,12 +1151,6 @@ dependencies = [
|
|||
"winapi 0.3.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f3eb36b47e512f8f1c9e3d10c2c1965bc992bd9cdb024fa581e2194501c83d3"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
|
@ -1620,16 +1563,3 @@ name = "xdg"
|
|||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57"
|
||||
|
||||
[[package]]
|
||||
name = "xdg-mime"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "362780d5ed4fcb81db6460966be8cd691e48419caa84bb8a81063d2abdab7082"
|
||||
dependencies = [
|
||||
"dirs",
|
||||
"glob",
|
||||
"mime",
|
||||
"nom",
|
||||
"unicase",
|
||||
]
|
||||
|
|
|
@ -18,13 +18,12 @@ thiserror = "1.0.19"
|
|||
ascii_table = "3.0.1"
|
||||
xdg = "2.2.0"
|
||||
mime = "0.3.16"
|
||||
once_cell = "1.4.0"
|
||||
regex = { version = "1.3.9", default-features = false, features = ["std"] }
|
||||
mime-db = "0.1.5"
|
||||
atty = "0.2.14"
|
||||
confy = "0.4.0"
|
||||
serde = "1.0.111"
|
||||
xdg-mime = "0.3.0"
|
||||
mime-detective = "1.0.0"
|
||||
|
||||
[profile.release]
|
||||
opt-level=3
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
use crate::Result;
|
||||
use once_cell::sync::Lazy;
|
||||
use xdg_mime::SharedMimeInfo;
|
||||
|
||||
pub static SHARED_MIME_DB: Lazy<SharedMimeInfo> =
|
||||
Lazy::new(SharedMimeInfo::new);
|
||||
|
||||
static CUSTOM_MIMES: &[&'static str] = &[
|
||||
"inode/directory",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::{common::SHARED_MIME_DB, Error, Result};
|
||||
use crate::{Error, Result};
|
||||
use mime::Mime;
|
||||
use mime_detective::MimeDetective;
|
||||
use std::{
|
||||
convert::TryFrom,
|
||||
path::{Path, PathBuf},
|
||||
|
@ -26,38 +27,14 @@ impl TryFrom<&str> for MimeType {
|
|||
}
|
||||
}
|
||||
|
||||
fn read_mb(path: &Path) -> Result<(std::fs::Metadata, Vec<u8>)> {
|
||||
let metadata = std::fs::metadata(path)?;
|
||||
let data = if metadata.len() <= 1024 {
|
||||
std::fs::read(path)?
|
||||
} else {
|
||||
use std::io::prelude::*;
|
||||
let mut buffer = Vec::with_capacity(1024);
|
||||
let reader = std::io::BufReader::new(std::fs::File::open(path)?);
|
||||
reader.take(1024).read_exact(&mut buffer)?;
|
||||
buffer
|
||||
};
|
||||
Ok((metadata, data))
|
||||
}
|
||||
|
||||
impl TryFrom<&Path> for MimeType {
|
||||
type Error = Error;
|
||||
fn try_from(path: &Path) -> Result<Self> {
|
||||
let file_name = path.file_name().unwrap_or_default().to_string_lossy();
|
||||
|
||||
match &*SHARED_MIME_DB.get_mime_types_from_file_name(&file_name) {
|
||||
[t, ..] if t == &mime::APPLICATION_OCTET_STREAM => Ok(Self({
|
||||
let (meta, data) = read_mb(path)?;
|
||||
SHARED_MIME_DB
|
||||
.guess_mime_type()
|
||||
.metadata(meta)
|
||||
.data(&data)
|
||||
.guess()
|
||||
.mime_type()
|
||||
.clone()
|
||||
})),
|
||||
[other, ..] => Ok(Self(other.clone())),
|
||||
_ => Err(Error::Ambiguous(path.to_string_lossy().into())),
|
||||
match MimeDetective::new()?.detect_filepath(path)? {
|
||||
guess if guess == mime::APPLICATION_OCTET_STREAM => {
|
||||
Err(Error::Ambiguous(path.to_string_lossy().into()))
|
||||
}
|
||||
guess => Ok(Self(guess)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ mod desktop_entry;
|
|||
mod handler;
|
||||
mod mime_types;
|
||||
|
||||
pub use self::db::{autocomplete as db_autocomplete, SHARED_MIME_DB};
|
||||
pub use self::db::autocomplete as db_autocomplete;
|
||||
pub use desktop_entry::{DesktopEntry, Mode as ExecMode, Rule as EntryRule};
|
||||
pub use handler::Handler;
|
||||
pub use mime_types::{MimeOrExtension, MimeType};
|
||||
|
|
|
@ -10,14 +10,16 @@ pub enum Error {
|
|||
Xdg(#[from] xdg::BaseDirectoriesError),
|
||||
#[error(transparent)]
|
||||
Config(#[from] confy::ConfyError),
|
||||
#[error("no handler defined for .{0}")]
|
||||
#[error("no handler defined for {0}")]
|
||||
NotFound(String),
|
||||
#[error("could not figure out the mime type .{0}")]
|
||||
#[error("could not figure out the mime type {0}")]
|
||||
Ambiguous(String),
|
||||
#[error(transparent)]
|
||||
BadMimeType(#[from] mime::FromStrError),
|
||||
#[error("malformed desktop entry at .{0}")]
|
||||
#[error("malformed desktop entry at {0}")]
|
||||
BadEntry(std::path::PathBuf),
|
||||
#[error(transparent)]
|
||||
MimeDetect(#[from] mime_detective::DetectiveError),
|
||||
}
|
||||
|
||||
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
||||
|
|
Loading…
Reference in a new issue