Mailfilter
Ever tried to do something advanced with procmail?
man procmailrc
Extended regular expressions [...] \/ Splits the expression in two parts. Everything matching the right part will be assigned to the MATCH environment variable
This is unusable!
So we are introducing mailfilter. This is a python program with an seperate filter file.
The filter file is "$HOME/.mailfilter". This file is executed as python script from within the context of the mailfilter program, so we have the full python power available (this is important to note ;-)). It contains filter rules which map mail properties to Maildir folders. If no filter matches the mail goes into the INBOX.
Filtering is currently only supported for mail headers. Therefore the name and the value of a mail header is provided as regular expression for filtering. The name must match exactly while the value can occur anywhere. The rules are case insensitive.
The simplest filter takes the name of the Maildir folder where the mail should go to.
filter("To", "work@example\.com", "work")
The more advanced filter takes a callable object as its third parameter. This object is called with the match object which resulted from the regular expression matching of the value of the corresponding header. The return value must be the name of the Maildir folder.
# mail to alias+bank@... must go to alias/bank
filter("To", "alias\+(.*)@example\.com", lambda mo : "alias." + mo.group(1))
If the filter function is more complex lambdas are not enough. Therefore filter can be used as a decorator for the filter function
@filter("To", "alias\+(.*)@example\.com")
def aliases(mo):
return "alias." + mo.group(1)
If the filter function returns "None" the mail is discarded.
# kick mails from the moron
filter("From", "moron@other\.example\.com", lambda mo : None)
As this is a quite often use case there is a convienience function
# kick mails from the moron
discard("From", "moron@other\.example\.com")
Sometimes multiple filter rules correspond to the same filter function. This can be expressed with multiple filter decorators. Here is an example to filter mails from mailing lists automatically into the right Maildir folder.
# mails to news@ulm.ccc.de must go to ml/news-ulm-ccc-de
# triggers on 'List-Id: CCC Ulm - News Liste <news.ulm.ccc.de>'
@filter("List-Id", "(.*)$")
@filter("List-Id", "[^<]*<([^>]+)>")
@filter("List-Post", "<mailto:(.+)>")
def mailinglists(mo):
return "ml." + esc(mo.group(1))
Note that the filters are applied in reverse order.
ezml driver mailing lists are different. So we add
@filter("Mailing-List", "contact (.*)-help@(.*); run by ezmlm")
def ezmlm(mo):
return "ml.%s-%s" %(esc(mo.group(1)), esc(mo.group(2)))
Mailfilter is a kind of a procmail extention. This means all the dirty work is done by procmail. To make this happen we need the following procmailrc and put mailfilter.py into the PATH.
DEFAULT=$HOME/Maildir/ :0fw | mailfilter.py :0 H * X-Mailfilter-Discard: /dev/null :0 H * X-Mailfilter-Mailbox: \/.* .$MATCH/
This shows that mailfilter uses custom mail headers for its comunication with procmail. If such headers are already part the email they are ignored. This enables refiltering of all mails of the Maildir when altering the filter rules.
Integration for mbox is no problem. Use this procmail instead
:0fw | mailfilter.py :0 H * X-Mailfilter-Discard: /dev/null :0 H * X-Mailfilter-Mailbox: \/.* $MATCH
Download
Choose one of the following:
- Get the current version as bz2 file
- Browse the git repository to get other revisions
- clone the repository with git clone git://git.projects.spamt.net/mailfilter
mailing lists
Copying
mailfilter is published by Rico Schiekel and Alexander Bernauer under the GPL 2.0 (and not later).