Richard Jones' Log: OS X Mail.app rules to sieve filters
Tue, 01 Feb 2011
These days I have a snazzy phone with an awesome IMAP client. A problem I have though is the large volume of email my work address gets. I have had my laptop Mail.app rules sorting those messages to sensible folders, but that approach is flawed when my laptop isn't active. I've moved to using sieve on the IMAP server and to do that I wrote the following simple script to convert my Mail.app rules to sieve commands. I didn't even realise the standard library had a plist module until I googled it :-)
import plistlib p = plistlib.readPlist('/Users/sekrit/Library/Mail/MessageRules.plist') print ''' require ["fileinto", "reject"]; ''' stmt = 'if' def handle(header, expression, mbox): global stmt if header in ('To', 'Cc', 'From'): print stmt, 'address :contains ["%s"] "%s" { fileinto "INBOX.%s"; }' % (header, expression, mbox) elif header == 'Subject': print stmt, 'header :matches "Subject" ["*%s*"] { fileinto "INBOX.%s"; }' % (expression, mbox) else: raise ValueError(header) stmt = 'elsif' for rule in p['rules']: if 'Mailbox' not in rule: continue mbox = rule['Mailbox'].split('/')[-1].split('.')[0] print '#', rule['RuleName'], '->', mbox for criteria in rule['Criteria']: if criteria['Header'] == 'AnyRecipient': handle('To', criteria['Expression'], mbox) handle('Cc', criteria['Expression'], mbox) else: handle(criteria['Header'], criteria['Expression'], mbox) print ''' else { keep; } '''
ps. I realise my sieve-fu is probably really quite poor :-)