diff options
author | rabite <rabite@posteo.de> | 2019-07-01 17:24:30 +0200 |
---|---|---|
committer | rabite <rabite@posteo.de> | 2019-07-01 17:24:30 +0200 |
commit | 366b9c6f3dfd5ce0b7e596f3ad82b3005e8d9759 (patch) | |
tree | bb6cb8d8c5f11a71bee7c04697e26f956ff61aa0 | |
parent | 17abbbd59f17ff43e1c67b94d0175b94ef609436 (diff) |
added custom quick action creator based on quick actions
-rwxr-xr-x | extra/actions/Add\ Action?type?name!.sh | 84 | ||||
-rw-r--r-- | src/fail.rs | 23 | ||||
-rw-r--r-- | src/main.rs | 43 | ||||
-rw-r--r-- | src/quick_actions.rs | 16 | ||||
-rw-r--r-- | src/trait_ext.rs | 36 |
5 files changed, 189 insertions, 13 deletions
diff --git a/extra/actions/Add\ Action?type?name!.sh b/extra/actions/Add\ Action?type?name!.sh new file mode 100755 index 0000000..6a322bc --- /dev/null +++ b/extra/actions/Add\ Action?type?name!.sh @@ -0,0 +1,84 @@ +#!/bin/sh + + +errecho() { + echo ${@} >&2 +} + +check_dir() { + DIR=${1} + + [ -d ${DIR} ] || + mkdir -p ${DIR} || + (echo "Can't create directory: ${DIR}" && exit 1) +} + +populate_file() { + FILE=${1} + + # Don't try to overwrite existing file + test -e ${FILE} && return + + + + cat > ${FILE} << EOF +#!/bin/sh + +# Selected files are stored here +FILES=\${@} + +# You can interate over them one by one +for FILE in \${FILES}; do + echo \$FILE +done + +# Or process them all at once +echo "\${FILES}" +EOF +} + + +## Starting point + +FILE=${1} +MIME=`hunter -m $FILE` +STATUS=$? + + +# MIME detection failed, bail out unless type is base +[ $STATUS != 0 ] && [ $type != "uni" ] && + echo $MIME && + exit 1 + +# Laziy not using XGD here because of OSX +ACTDIR="$HOME/.config/hunter/actions/" + +MIME_BASE=`echo $MIME | cut -d "/" -f 1` +MIME_SUB=`echo $MIME | cut -d "/" -f 2` + + +case $type in + uni) + AFILE="${ACTDIR}/${name}.sh" + check_dir "${ACTDIR}" + populate_file "${AFILE}" + $EDITOR "${AFILE}" + test -e "${AFILE}" && chmod +x "${AFILE}" + ;; + base) + BASEDIR="${ACTDIR}/$MIME_BASE" + AFILE="${BASEDIR}/${name}.sh" + check_dir "${BASEDIR}" + populate_file "${AFILE}" + $EDITOR "${AFILE}" + test -e ${AFILE} && chmod +x "${ACTDIR}/$name" + ;; + sub) + SUBDIR="${ACTDIR}/${MIME_BASE}/${MIME_SUB}" + AFILE="${SUBDIR}/${name}.sh" + check_dir ${SUBDIR} + populate_file "${AFILE}" + $EDITOR "${AFILE}" + test -e ${AFILE} && chmod+ +x ${AFILE} + ;; +esac diff --git a/src/fail.rs b/src/fail.rs index b3351ba..1e6baf0 100644 --- a/src/fail.rs +++ b/src/fail.rs @@ -103,7 +103,9 @@ pub enum HError { #[fail(display = "Failed to parse integer!")] ParseIntError(std::num::ParseIntError), #[fail(display = "{}", _0)] - Media(MediaError) + Media(MediaError), + #[fail(display = "{}", _0)] + Mime(MimeError), } impl HError { @@ -331,3 +333,22 @@ impl From<std::num::ParseIntError> for HError { err } } + + +// MIME Errors + +#[derive(Fail, Debug, Clone)] +pub enum MimeError { + #[fail(display = "Need a file to determine MIME type")] + NoFileProvided, + #[fail(display = "File access failed! Error: {}", _0)] + AccessFailed(Box<HError>), + #[fail(display = "No MIME type found for this file",)] + NoMimeFound +} + +impl From<MimeError> for HError { + fn from(e: MimeError) -> Self { + HError::Mime(e) + } +} diff --git a/src/main.rs b/src/main.rs index 57d2dbd..7efbad7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -69,9 +69,10 @@ mod mediaview; use widget::{Widget, WidgetCore}; use term::ScreenExt; -use fail::{HResult, HError}; +use fail::{HResult, HError, MimeError}; use file_browser::FileBrowser; use tabview::TabView; +use trait_ext::PathBufMime; fn reset_screen(core: &mut WidgetCore) -> HResult<()> { @@ -136,8 +137,7 @@ fn parse_args() -> HResult<()> { .short("a") .long("animation-off") .help("Turn off animations") - .takes_value(false), - ) + .takes_value(false)) .arg( Arg::with_name("show-hidden") .short("h") @@ -150,18 +150,32 @@ fn parse_args() -> HResult<()> { .short("i") .long("icons") .help("Show icons for different file types") - .takes_value(false), - ) + .takes_value(false)) + // For "Add Action" action + .arg( + Arg::with_name("mime") + .short("m") + .long("mime") + .help("Print MIME type of file") + .takes_value(false)) .arg( Arg::with_name("path") .index(1) - .help("Start in <path>") - ) + .help("Start in <path>")) .get_matches(); let path = args.value_of("path"); + // Just print MIME and quit + if args.is_present("mime") { + get_mime(path) + .map_err(|e| eprintln!("{}", e)). + ok(); + // If we get heres something went wrong. + std::process::exit(1) + } + if let Some(path) = path { std::env::set_current_dir(&path).ok(); } @@ -169,3 +183,18 @@ fn parse_args() -> HResult<()> { crate::config::set_argv_config(args).ok(); Ok(()) } + + + + + + +fn get_mime(path: Option<&str>) -> HResult<()> { + let path = path.ok_or(MimeError::NoFileProvided)?; + let path = std::path::PathBuf::from(path); + path.get_mime() + .map(|mime| println!("{}", mime)) + .map(|_| std::process::exit(0)) + .map_err(|e| eprintln!("{}", e)) + .map_err(|_| std::process::exit(1)) +} diff --git a/src/quick_actions.rs b/src/quick_actions.rs index 69bfb78..14c33bc 100644 --- a/src/quick_actions.rs +++ b/src/quick_actions.rs @@ -349,17 +349,22 @@ impl QuickAction { .iter() .fold(Ok(vec![]), |mut acc, query| { // If error occured/input was cancelled just skip querying + // Turn into try_fold? if acc.is_err() { return acc; } match core.minibuffer(query) { Err(HError::MiniBufferEmptyInput) => { - acc.as_mut().map(|acc| acc.push((OsString::from(query), - OsString::from("")))).ok(); + acc.as_mut() + .map(|acc| acc.push((OsString::from(query), + OsString::from("")))) + .ok(); acc } Ok(input) => { - acc.as_mut().map(|acc| acc.push((OsString::from(query), - OsString::from(input)))).ok(); + acc.as_mut() + .map(|acc| acc.push((OsString::from(query), + OsString::from(input)))) + .ok(); acc } Err(err) => Err(err) @@ -505,7 +510,8 @@ impl QuickPath for PathBuf { .collect::<Vec<&str>>() .iter() .skip(1) - .map(|q| q.to_string()) + // Remove ! in queries from sync actions + .map(|q| q.trim_end_matches("!").to_string()) .collect()) .unwrap_or_else(|| vec![]) } diff --git a/src/trait_ext.rs b/src/trait_ext.rs index 350138b..51e352e 100644 --- a/src/trait_ext.rs +++ b/src/trait_ext.rs @@ -1,3 +1,17 @@ +use std::path::PathBuf; + +use crate::fail::{HResult, MimeError}; +use crate::files::File; + + + + + + + + + +// This makes using short-circuiting iterators more convenient pub trait ExtractResult<T> { fn extract(self) -> T; } @@ -10,3 +24,25 @@ impl<T> ExtractResult<T> for Result<T,T> { } } } + + +// To get MIME from Path without hassle +pub trait PathBufMime { + fn get_mime(&self) -> HResult<String>; +} + +impl PathBufMime for PathBuf { + fn get_mime(&self) -> HResult<String> { + let mut file = File::new_from_path(&self, None) + .map_err(|e| MimeError::AccessFailed(Box::new(e)))?; + file.meta_sync() + .map_err(|e| MimeError::AccessFailed(Box::new(e)))?;; + + + file.get_mime() + .map(|mime| { + Ok(format!("{}", mime)) + }) + .ok_or(MimeError::NoMimeFound)? + } +} |