X-Git-Url: https://git.madduck.net/etc/mutt.git/blobdiff_plain/a83d50d5a64488deb3796bbd0ca0a03b0516cc77..7013dfe93a05082153f79eca6c9e5c05b54d9d50:/.config/mutt/bgrun diff --git a/.config/mutt/bgrun b/.config/mutt/bgrun new file mode 100755 index 0000000..ad432df --- /dev/null +++ b/.config/mutt/bgrun @@ -0,0 +1,180 @@ +#!/bin/sh + +#exec 2>> /tmp/bgrun.stderr +#set -x + +SELF="${0##*/}" + +TEMPDIR= +TEMPRUNDIR=.tempdir-run.d +cleanup() { + if [ -d $TEMPRUNDIR ]; then + local TEMPDIR; TEMPDIR="$PWD" + notify_output + cd / + rm -rf "$TEMPDIR" + fi + trap - 1 2 3 4 5 6 7 8 10 11 12 13 14 15 +} +trap cleanup 1 2 3 4 5 6 7 8 10 11 12 13 14 15 + +enter_tempdir() { + if [ -d $TEMPRUNDIR ]; then + return + + else + if [ -z "${TMPDIR:-}" ]; then + TMPDIR=/tmp + fi + for i in $LOGNAME volatile; do + if [ -d "${TMPDIR}/$i" ]; then + TMPDIR="${TMPDIR}/$i" + break + fi + done + cd $(mktemp -dp "$TMPDIR" mutt.XXXXXXXXXX) + mkdir $TEMPRUNDIR + fi +} + +notify() { + if [ -x "$(command -v awesome-client)" ]; then + local stdout stderr escaped output + stdout="${2:-}" + stderr="${3:-}" + for i in stdout stderr; do + if eval test -s $TEMPRUNDIR/output.$i; then + escaped=$(eval sed -e 's,\",\\\",g' $TEMPRUNDIR/output.$i) + output="${output:+$output +}${i}: +$escaped" + fi + done + [ -n "${escaped:-}" ] || return + awesome-client <<-_eof + local naughty = require("naughty") + naughty.notify({ preset = naughty.config.presets.low, + title = "${1:-Output from mutt/$SELF}", + text = [[$output]] + }) + _eof + fi +} + +notify_output() { + [ -d $TEMPRUNDIR ] || return + local stdout stderr anything + + for i in stdout stderr; do + if [ -s "$TEMPRUNDIR/output.$i" ]; then + eval $i="'$TEMPRUNDIR/output.$i'" + else + eval $i=/dev/null + fi + done + + notify "Output from mutt/$SELF" $stdout $stderr +} + +guess_extension() { + python3 -c "import mimetypes; print(mimetypes.guess_extension('$1'))" +} + +get_file() { + local t + if [ -z "$1" ]; then + t=$(mktemp -p "$PWD" tmp.XXXXXXXXXX.$(guess_extension "$MIMETYPE")) + cat > "$t" + echo "$t" + else + t="$(echo ${1##*/} | sed -re 's![^[:alnum:],.@%^+=_-]!_!gi')" + ln "$1" "$t" 2>/dev/null || cp "$1" "$t" + echo "$t" + fi +} + +MIMETYPE= FILENAME= VIEWER= DELAY=1 +state= +for arg in "$@"; do + case "$state/$arg" in + + (/-t) state=t;; + (t/*) MIMETYPE="$arg"; state=;; + + (/-f) state=f;; + (f/*) FILENAME="$arg"; state=;; + + (/-d) state=d;; + (d/*) DELAY="$arg"; state=;; + + (/-v) state=v;; + (v/*) VIEWER="$arg"; state=;; + + (*) + echo >&2 "E: Invalid argument: $i" + exit 1 + ;; + + esac +done + +launch_viewer() { + local filename; filename="$1" + if [ -z "$VIEWER" ]; then + [ -n "${2:-}" ] && filename="${2}:${1}" + run-mailcap "$filename" > $TEMPRUNDIR/output.stdout 2> $TEMPRUNDIR/output.stderr + else + $VIEWER "$filename" > $TEMPRUNDIR/output.stdout 2> $TEMPRUNDIR/output.stderr + fi +} + +case "$SELF" in + (bgview) + # make a copy of the file, then launch a shell process in the background + # to divert to run-mailcap, after which the temporary directory gets + # cleaned up. + enter_tempdir + FILE="$(get_file "$FILENAME")" + ( + ts=$(($(date +%s) + $DELAY)) + launch_viewer "$FILE" "$MIMETYPE" + while [ $(date +%s) -lt $ts ]; do sleep 1; done + cleanup + ) & + trap - 1 2 3 4 5 6 7 8 10 11 12 13 14 15 + ;; + (bgview-fifo) + # hack to stay around until the viewer has read the file: make a fifo and + # wait for the cat process to finish writing to it, which means that it + # must have been consumed on the other end. + enter_tempdir + FILE="$(get_file "$FILENAME")" + FIFO="fifo-${FILE##*/}" + mkfifo "$FIFO" + cat "$FILE" > "$FIFO" & + # For some reason, we do have to write a tempfile and cannot seem to + # redirect stdin directly to the fifo, i.e. this does not work instead of + # the previous three lines: + ## cat > "$FIFO" & + launch_viewer "$FIFO" "$MIMETYPE" + wait + cleanup + ;; + (bgview-delay) + # hack to stay around until the file hasn't been accessed for a few + # seconds, so that we can clean up. This is for cases when the FIFO method + # doesn't work, because e.g. Firefox randomly chooses it needs to read + # HTML files twice. + enter_tempdir + FILE="$(get_file "$FILENAME")" + touch "$FILE" + (launch_viewer "$FILE" "$MIMETYPE") & + ( + while [ $(($(stat -c%X "$FILE") + $DELAY)) -gt $(date +%s) ]; do + sleep 1 + done + cleanup + ) & + trap - 1 2 3 4 5 6 7 8 10 11 12 13 14 15 + ;; +esac