I’m apparently old-school enough to find gmail
and co painfully inefficient for
handling significant amounts of mail. I still find procmail
+mutt
hard to beat. One thing mutt
can’t do, however, is filter threads
automatically - there’s no “mute” facility like gmail
has; threads
have to processed manually.
Equally, procmail
itself has no threading facilities or understanding
of Message-Id
or References
.
Matching email threads
It can be done, though, with some cheesy awk:
#!/bin/bash
#
# If a mail message has a References: value found in the refs file, then
# add the requested header.
#
# Usage:
#
# cat mail_msgs | match-thread.sh ~/.mail.refs.muted "Muted: true"
#
ref_file="$1"
header="$2"
mail=/tmp/match-thread.mail.$$
cat - >$mail
newrefs="$(cat $mail | formail -x references -x message-id | tr -d '\n')"
touch $ref_file
cat $ref_file | awk -v newrefs="$newrefs" '
BEGIN {
found = 0;
split(newrefs, tmp);
for (i in tmp) {
refs[tmp[i]]++;
}
}
# Each thread will have one line in the ref file, with
# space-separated references. So we just need to look for any
# reference from the mail.
{
for (ref in refs) {
if (index($0, ref) != 0) {
found = 1;
exit(0);
}
}
}
END {
exit(found ? 0 : 1);
}
'
if [[ $? = 0 ]]; then
cat $mail | formail -i "$header"
else
cat $mail
fi
rm $mail
Essentially, we record all the References
in the thread we’re trying
to act on. Then we can trigger the above to see if the new mail is part
of the thread of interest.
(This seems like the sort of thing formail
could do, given its -D
option has a message ID cache, but I haven’t even bothered to take a
look at how hard that would be…)
procmail
usage
In .procmailrc
, we’d use this like so:
:0 Wfh: formail.lock
| $HOME/src/procmail-thread/match-thread.sh $HOME/.refs.muted "Procmail-Muted: true"
:0 Wfh: formail.lock
| $HOME/src/procmail-thread/match-thread.sh $HOME/.refs.watched "Procmail-Watched: true"
This will add the given header if we find any of the email’s
References
values in our “database”.
Then, we can do what we like with the mails, like deliver them as already-read, carbon copy them to the inbox, etc.:
:0
* Procmail-Muted: true
{
SWITCHRC=$HOME/.procmailrc.markread
}
:0
* Procmail-Watched: true
{
:0 c:
$DEFAULT
SWITCHRC=$HOME/.procmailrc.markread
}
:0
$DEST/
mutt
usage
To actually watch or mute a thread, we add a couple of mutt
macros:
macro index,pager "M" "|~/src/procmail-thread/add-thread.sh ~/.refs.muted<return>"
macro index,pager "W" "|~/src/procmail-thread/add-thread.sh ~/.refs.watched<return>"
The add-thread.sh
script is similar to the above, but populates the
refs file with all message IDs found in the given email.
I put all this in a git repo.