#!/bin/sh
+#exec 2>> /tmp/bgrun.stderr
+#set -x
+
SELF="${0##*/}"
-if [ -z "$TMPDIR" ]; then
- TMPDIR=/tmp
-elif [ -d "${TMPDIR}/volatile" ]; then
- TMPDIR="${TMPDIR}/volatile"
-fi
-export TMPDIR
-TMPDIR=$(mktemp -dp "$TMPDIR" mutt.XXXXXXXXXX)
-cleanup() { cd / && notify_output && rm -rf "$TMPDIR"; }
+TEMPDIR=
+TEMPDIR_SENTINEL=.tempdir
+cleanup() {
+ if [ -e $TEMPDIR_SENTINEL ]; then
+ local TEMPDIR; TEMPDIR="$PWD"
+ echo Cleaning up tempdir $TEMPDIR… >> output.stderr
+ notify_output
+ cd /
+ rm -rf "$TEMPDIR"
+ else
+ notify_output
+ 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
-cd "$TMPDIR"
+enter_tempdir() {
+ if [ -e $TEMPDIR_SENTINEL ]; 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)
+ touch $TEMPDIR_SENTINEL
+ 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 output.$i; then
+ anything=1
+ escaped=$(eval sed -e 's,\",\\\",g' 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 = "$3",
- text = [[stdout:
- $(sed -e 's,\",\\\",g' "$1")
- stderr:
- $(sed -e 's,\",\\\",g' "$2")]]
+ title = "${1:-Output from mutt/$SELF}",
+ text = [[$output]]
})
_eof
fi
}
notify_output() {
- if [ -s "$TMPDIR/output.stdout" ] || [ -s "$TMPDIR/output.stderr" ]; then
- notify $TMPDIR/output.stdout $TMPDIR/output.stderr \
- "Output from mutt/$SELF on $BASENAME"
- fi
+ [ -e $TEMPDIR_SENTINEL ] || return
+ local stdout stderr anything
+
+ for i in stdout stderr; do
+ if [ -s "output.$i" ]; then
+ eval $i="'output.$i'"
+ else
+ eval $i=/dev/null
+ fi
+ done
+
+ notify "Output from mutt/$SELF" $stdout $stderr
}
guess_extension() {
python -c "import mimetypes; print(mimetypes.guess_extension('$1'))"
}
-launch_viewer() {
- run-mailcap --action=view "$1":"$2" > output.stdout 2> output.stderr
-}
-
-MIMETYPE="$1"; shift
-
get_file() {
local t
if [ -z "$1" ]; then
- t=$(tempfile -d . -p mutt -s $(guess_extension "$MIMETYPE"))
+ t=$(TMPDIR="$PWD" tempfile -s $(guess_extension "$MIMETYPE"))
cat > "$t"
echo "$t"
else
t="$(echo ${1##*/} | sed -re 's![^[:alnum:],.@%^+=_-]!_!gi')"
- cp "$1" "$t"
+ 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" > output.stdout 2> output.stderr
+ else
+ $VIEWER "$filename" > output.stdout 2> output.stderr
+ fi
+}
+
case "$SELF" in
- (bgrun)
+ (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.
- FILE="$(get_file "${1:-}")"
+ enter_tempdir
+ FILE="$(get_file "$FILENAME")"
(
- launch_viewer "$MIMETYPE" "$FILE"
- sleep 1
+ ts=$(($(date +%s) + $DELAY))
+ launch_viewer "$FILE" "$MIMETYPE"
+ while [ $(date +%s) -lt $ts ]; do sleep $DELAY; done
cleanup
) &
trap - 1 2 3 4 5 6 7 8 10 11 12 13 14 15
;;
- (bgrun-fifo)
+ (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.
- FILE="$(get_file "${1:-}")"
- FIFO="${FILE%/*}/fifo-${FILE##*/}"
+ 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 "$MIMETYPE" "${FIFO}"
+ launch_viewer "$FIFO" "$MIMETYPE"
wait
cleanup
;;
- (bgrun-delay)
- # hack to stay around for a fixed period of time after the viewer process
- # returns control to the caller, 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.
- FILE="$(get_file "${1:-}")"
- (launch_viewer "$MIMETYPE" "${FILE}") &
+ (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") &
(
- sleep 1m
+ while [ $(($(stat -c%X "$FILE") + $DELAY)) -gt $(date +%s) ]; do
+ sleep $DELAY
+ done
echo Cleaning up $TMPDIR… > $TMPDIR/output.stderr
cleanup
) &
+ trap - 1 2 3 4 5 6 7 8 10 11 12 13 14 15
;;
esac