[notmuch] [PATCH] Add post-add and post-tag hooks

Tomas Carnecky tom at dbservice.com
Mon Dec 21 19:18:21 PST 2009


On 12/22/09 3:56 AM, Tomas Carnecky wrote:
 > The post-add hook is run by 'notmuch new' after each new message is 
added,
 > post-tag is run after a tag has been added or removed. The hooks are 
stored
 > in the users home directory (~/.notmuch/hooks/).
 >
 > Since post-tag is run unconditionally every time a new tag is added 
or removed,
 > that means it is also invoked when 'notmuch new' adds the two implicit
 > tags (inbox, unread). So make sure your scripts don't choke on that 
and can
 > be both executed in parallel.

What are these good for? I (try to) use these two hooks to automatically 
tag messages. But not in the usual way, I don't use static scripts, I 
use a spam filter. I hope to be able to teach it to classify the 
messages, not only spam/ham but also add tags such as patch (does that 
message contain a patch?), tag messages based on which mailing lists the 
messages belong etc.

I use dspam as the spam filter. Each tag is actually a virtual user that 
exists in dspam. When adding new messages dspam classifies the mails and 
I assign the tags based on the result. If dspam deemed the message Spam 
then I set the tag. To train dspam I use the post-tag hook: whenever I 
change a tag (for example add 'spam' to a falsely unrecognized spam), 
the post-tag hook retrains dspam.

Since the post-add hook is running synchronously with 'notmuch new', 
this adds quite a bit overhead. Depending on how fast the spam filter 
is, it adds more or less time to do the import of new messages. It also 
depends on how many tags you want to assign - dspam has to run once for 
each tag to see if the tag should be assigned or not.

tom

--- >8 --- post-add
#!/bin/bash

# This is so that the post-tag doesn't trigger retraining!
export NOTMUCH_POST_ADD=1

MESSAGEID=$1
FILENAME=$2

# Array of tags.
tags=( spam )
for tag in "${tags[@]}"; do
         RESULT="$(/opt/dspam/bin/dspam --user $tag --deliver=summary < 
$FILENAME)"

         if echo $RESULT | grep -q 'result="Spam";'; then
                 echo $tag
         fi
done

# I remove the inbox flag from all new messages and keep only 'unread'
echo "-inbox"
--- >8 ---

--- >8 --- post-tag
#!/bin/sh

if [ "$NOTMUCH_POST_ADD" ]; then
         echo "Exiting due to running in post-add"
         exit
fi

MESSAGEID=$1
FILENAME=$2
TAG=$3
ADDREMOVE=$4

if [ "x$ADDREMOVE" = "xadded" ]; then
         CLASS="spam"
else
         CLASS="innocent"
fi

/opt/dspam/bin/dspam --user $TAG --source=error --class=$CLASS < $FILENAME
--- >8 ---



More information about the notmuch mailing list