]> git.madduck.net Git - etc/mutt.git/blob - .mutt/bgrun

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

All patches and comments are welcome. Please squash your changes to logical commits before using git-format-patch and git-send-email to patches@git.madduck.net. If you'd read over the Git project's submission guidelines and adhered to them, I'd be especially grateful.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

bgrun: use a subdir as sentinel and for our own workspace
[etc/mutt.git] / .mutt / bgrun
1 #!/bin/sh
2
3 #exec 2>> /tmp/bgrun.stderr
4 #set -x
5
6 SELF="${0##*/}"
7
8 TEMPDIR=
9 TEMPRUNDIR=.tempdir-run.d
10 cleanup() {
11   if [ -d $TEMPRUNDIR ]; then
12     local TEMPDIR; TEMPDIR="$PWD"
13     echo Cleaning up tempdir $TEMPDIR… >> output.stderr
14     notify_output
15     cd /
16     rm -rf "$TEMPDIR"
17   else
18     notify_output
19   fi
20   trap - 1 2 3 4 5 6 7 8 10 11 12 13 14 15
21 }
22 trap cleanup 1 2 3 4 5 6 7 8 10 11 12 13 14 15
23
24 enter_tempdir() {
25   if [ -d $TEMPRUNDIR ]; then
26     return
27
28   else
29     if [ -z "${TMPDIR:-}" ]; then
30       TMPDIR=/tmp
31     fi
32     for i in $LOGNAME volatile; do
33       if [ -d "${TMPDIR}/$i" ]; then
34         TMPDIR="${TMPDIR}/$i"
35         break
36       fi
37     done
38     cd $(mktemp -dp "$TMPDIR" mutt.XXXXXXXXXX)
39     mkdir $TEMPRUNDIR
40   fi
41 }
42
43 notify() {
44   if [ -x "$(command -v awesome-client)" ]; then
45     local stdout stderr escaped output
46     stdout="${2:-}"
47     stderr="${3:-}"
48     for i in stdout stderr; do
49       if eval test -s $TEMPRUNDIR/output.$i; then
50         escaped=$(eval sed -e 's,\",\\\",g' $TEMPRUNDIR/output.$i)
51         output="${output:+$output
52 }${i}:
53 $escaped"
54       fi
55     done
56     [ -n "${escaped:-}" ] || return
57     awesome-client <<-_eof
58         local naughty = require("naughty")
59         naughty.notify({ preset = naughty.config.presets.low,
60                 title  = "${1:-Output from mutt/$SELF}",
61                 text   = [[$output]]
62                 })
63         _eof
64   fi
65 }
66
67 notify_output() {
68   [ -d $TEMPRUNDIR ] || return
69   local stdout stderr anything
70
71   for i in stdout stderr; do
72     if [ -s "$TEMPRUNDIR/output.$i" ]; then
73       eval $i="'$TEMPRUNDIR/output.$i'"
74     else
75       eval $i=/dev/null
76     fi
77   done
78
79   notify "Output from mutt/$SELF" $stdout $stderr
80 }
81
82 guess_extension() {
83   python -c "import mimetypes; print(mimetypes.guess_extension('$1'))"
84 }
85
86 get_file() {
87   local t
88   if [ -z "$1" ]; then
89     t=$(TMPDIR="$PWD" tempfile -s $(guess_extension "$MIMETYPE"))
90     cat > "$t"
91     echo "$t"
92   else
93     t="$(echo ${1##*/} | sed -re 's![^[:alnum:],.@%^+=_-]!_!gi')"
94     ln "$1" "$t" 2>/dev/null || cp "$1" "$t"
95     echo "$t"
96   fi
97 }
98
99 MIMETYPE= FILENAME= VIEWER= DELAY=1
100 state=
101 for arg in "$@"; do
102   case "$state/$arg" in
103
104     (/-t) state=t;;
105     (t/*) MIMETYPE="$arg"; state=;;
106
107     (/-f) state=f;;
108     (f/*) FILENAME="$arg"; state=;;
109
110     (/-d) state=d;;
111     (d/*) DELAY="$arg"; state=;;
112
113     (/-v) state=v;;
114     (v/*) VIEWER="$arg"; state=;;
115
116     (*)
117       echo >&2 "E: Invalid argument: $i"
118       exit 1
119       ;;
120
121   esac
122 done
123
124 launch_viewer() {
125   local filename; filename="$1"
126   if [ -z "$VIEWER" ]; then
127     [ -n "${2:-}" ] && filename="${2}:${1}"
128     run-mailcap "$filename" > $TEMPRUNDIR/output.stdout 2> $TEMPRUNDIR/output.stderr
129   else
130     $VIEWER "$filename" > $TEMPRUNDIR/output.stdout 2> $TEMPRUNDIR/output.stderr
131   fi
132 }
133
134 case "$SELF" in
135   (bgview)
136     # make a copy of the file, then launch a shell process in the background
137     # to divert to run-mailcap, after which the temporary directory gets
138     # cleaned up.
139     enter_tempdir
140     FILE="$(get_file "$FILENAME")"
141     (
142       ts=$(($(date +%s) + $DELAY))
143       launch_viewer "$FILE" "$MIMETYPE"
144       while [ $(date +%s) -lt $ts ]; do sleep $DELAY; done
145       cleanup
146     ) &
147     trap - 1 2 3 4 5 6 7 8 10 11 12 13 14 15
148     ;;
149   (bgview-fifo)
150     # hack to stay around until the viewer has read the file: make a fifo and
151     # wait for the cat process to finish writing to it, which means that it
152     # must have been consumed on the other end.
153     enter_tempdir
154     FILE="$(get_file "$FILENAME")"
155     FIFO="fifo-${FILE##*/}"
156     mkfifo "$FIFO"
157     cat "$FILE" > "$FIFO" &
158     # For some reason, we do have to write a tempfile and cannot seem to
159     # redirect stdin directly to the fifo, i.e. this does not work instead of
160     # the previous three lines:
161     ## cat > "$FIFO" &
162     launch_viewer "$FIFO" "$MIMETYPE"
163     wait
164     cleanup
165     ;;
166   (bgview-delay)
167     # hack to stay around until the file hasn't been accessed for a few
168     # seconds, so that we can clean up. This is for cases when the FIFO method
169     # doesn't work, because e.g. Firefox randomly chooses it needs to read
170     # HTML files twice.
171     enter_tempdir
172     FILE="$(get_file "$FILENAME")"
173     touch "$FILE"
174     (launch_viewer "$FILE" "$MIMETYPE") &
175     (
176       while [ $(($(stat -c%X "$FILE") + $DELAY)) -gt $(date +%s) ]; do
177         sleep $DELAY
178       done
179       echo Cleaning up $TMPDIR… > $TMPDIR/output.stderr
180       cleanup
181     ) &
182     trap - 1 2 3 4 5 6 7 8 10 11 12 13 14 15
183     ;;
184 esac