fix: case insensitive Message-ID grepping, maildir check
[muttjump] / muttjump
1 #!/bin/bash
2 # written by Johannes Wei├čl
3
4 # muttjump
5 #
6 # This script makes mail indexers (like mairix, mu or nmzmail) together with
7 # mutt more useful.
8 #
9 # These search engines usually create a virtual maildir containing symbolic
10 # links to the original mails, which can be browsed using mutt.
11 # It would be optimal if mutt somehow knew that the two maildir entries
12 # identify the same mail, but this is not that easy (mail folder
13 # abstraction from different formats, no tight integration of mail indexers).
14 #
15 # So if one wants to rename (for setting/clearing flags), delete or edit the
16 # mails, it is only possible using the original mail. This (very simple)
17 # script helps to jump to this message, using e.g. this macro in .muttrc:
18 #
19 # macro generic ,j "<enter-command>push <pipe-message>muttjump<enter><enter>" "jump to original message"
20
21 # one of: mairix, mu, mu-old (mu < 0.7) and nmzmail
22 MUTTJUMP_INDEXER=${MUTTJUMP_INDEXER:-}
23
24 # program paths
25 MUTT=${MUTT:-mutt}
26 MAIRIX=${MAIRIX:-mairix}
27 MU=${MU:-mu}
28 NMZMAIL=${NMZMAIL:-nmzmail}
29
30 function die () {
31     echo -e >&2 "$0: $1"
32     exit 1
33 }
34
35 # Check command-line arguments and STDIN
36 if tty -s || [ $# -ne 0 ] ; then
37     cat >&2 <<END
38 Usage: $0 < msg
39
40 This script calls mutt, jumping to the message given in stdin.
41 Uses a mail search engine (currently mairix, mu and nmzmail are supported),
42 which has to be configured through MUTTJUMP_INDEXER variable.
43 END
44     exit 1
45 fi
46
47 # check if mutt is installed
48 if ! type -p $MUTT >/dev/null ; then
49     die "$MUTT is not in PATH, set MUTT variable"
50 fi
51
52 # search for Message-ID in STDIN
53 msgid=$(sed -n 's/^Message-ID: \(.*\)/\1/Ip' | head -n1)
54 if [ -z "$msgid" ] ; then
55     die "could not find Message-ID header in standard input"
56 fi
57 msgid_clean=$(echo "$msgid" | sed 's/^<\(.*\)>$/\1/')
58
59 # try to locate path of message using a mail search engine
60 case $MUTTJUMP_INDEXER in
61     mairix)
62         orig_msgfile=$($MAIRIX -r "m:$msgid_clean" | head -n1)
63         ;;
64     mu)
65         orig_msgfile=$($MU find -f l "i:$msgid_clean" |
66             grep -v "^\*\*" | head -n1)
67         ;;
68     mu-old)
69         orig_msgfile=$($MU find -f p "m:$msgid_clean" | head -n1)
70         ;;
71     nmzmail)
72         nmzmail_results=$(mktemp -d)
73         echo "+message-id:$msgid" | $NMZMAIL -n 1 -r "$nmzmail_results"
74         msgfile=$(find "$nmzmail_results" -type l | head -n1)
75         orig_msgfile=$(readlink "$msgfile")
76         rm -rf "$nmzmail_results"
77         ;;
78     "")
79         die "variable MUTTJUMP_INDEXER not set or empty"
80         ;;
81     *)
82         die "unknown mail index program \"$MUTTJUMP_INDEXER\""
83         ;;
84 esac
85
86 if [ -z "$orig_msgfile" -o ! -e "$orig_msgfile" ] ; then
87     die "no message with msgid $msgid found!"
88 fi
89
90 # get containing maildir of $orig_msgfile
91 orig_maildir=$(dirname $(dirname "$orig_msgfile"))
92 if [ ! -d "$orig_maildir/cur" ] ; then
93     die "directory \"$orig_maildir\" doesn't exist or is no Maildir"
94 fi
95
96 # Close message-stdin and open terminal-stdin instead.
97 # mutt behaves different if STDIN is no terminal
98 # TODO: Find cleaner solution (e.g. mutt command-line argument?)
99 exec 0<&-
100 term="/dev/$(ps -p$$ --no-heading | awk '{print $2}')"
101 exec < $term
102
103 # start mutt, open original folder and jump to the original message
104 $MUTT -e "push <change-folder>$orig_maildir<enter><search>\"~i $msgid\"<enter>"

Benjamin Mako Hill || Want to submit a patch?