Annalate

A personal IMAP mail archiver and general purpose mailbox manipulation tool based on the c-client library.

It seems that there's no perfect MUA. For some reason, mail clients seem to be things that are either left to rot, or constantly bloated with trivial, pointless features. Apple's Mail is about as close as I've found, personally, but it's painfully slow at times, its filter functionality is broken and, of course, it's not particularly portable.

I can help Mail seem fast by keeping my mailboxes trim, archiving off old mail from INBOX and Sent, but Mail doesn't help me by giving me a nice functional filtering system. Hence annalate.

Annalate is a Perl script, utilising Mail::Client, which is in turn dependent on the c-client library, as distributed with uw-imapd. Annalate understands RFC1176 IMAP2 search criteria. Annalate can move, copy or delete mail via IMAP, or in local mailboxes, according to searches specified using IMAP2 criteria. Annalate can collate your messages into custom mailboxes by date, with names specified using a strftime format string. Annalate can work remotely via IMAP, can use TLS, or can work on local mailboxes in any of the formats understood by c-client.

Documentation

usage: annalate [ { -v | -vv } ] [ -X ] [ -s 'criteria' ] [ -a period ] \
                [ -b period ] [ { -d | { -c | -m } destination } ] source

       -v    give verbose output
       -vv   give very verbose output
       -X    do not expunge
       -s    supply alternative search criteria (default 'ALL')
       -a    magic after (SINCE) criterion
       -b    magic BEFORE criterion
       -d    delete messages matching criteria
       -c    copy messages matching criteria to destination
       -m    move messages matching criteria to destination

If copy, move or delete are not requested, the default action is to list.
Source mailboxes can be specified in any way the c-client understands,
including local mailbox names, {server/protocol}name remote mailboxes,
#driver.foo/bar/name mailboxes.  Destination mailboxes should be names only,
no server/protocol or driver, and must be the same type, location as the
source.  Destination mailbox names are in the form of a strftime (3C) format
-- date information to be extracted from each message as it is copied or
moved.  Destination mailboxes will be created as needed.  Magic before and
after criteria are calculated according to the current date and the
time period given as argument.  Time period may be qualified with a sign,
positive periods are added to "now".  Periods may bequlified with units: d -
days; h - hours; m - minutes; s - seconds. Examples of valid periods are:

  -7d    now minus seven days
  +1h    now plus one hour
  60m    now minus 60 minutes
+900s    now plus 900 seconds

Example: Delete all mail in remote IMAP folder "Garbage":

annalate -d {imap.jessies.org}Garbage

Example: Copy all mail from root in remote IMAP INBOX to remote IMAP folder
"Logs":

annalate -s 'FROM "root@"' -c Logs {imap.jessies.org}INBOX

Example: Move all read, unflagged, undeleted local mail older than 45 days
from INBOX into yearly archive folders:

annalate -s 'SEEN UNFLAGGED UNDELETED' -b 45d -m '%Y' INBOX

Downloads

Annalate is available under the terms of the GNU General Public License and can be downloaded here:

  • annalate - MD5 (annalate) = 67fa7cdee277b749fb4f9cad5f8968ec

Annalate is dependent on the following modules, available via CPAN:

Changes

Annalate is currently at revision 1.11, dated 2007/04/19 01:47:53. A changelog is available.

Disclaimer

This script is provided in good faith. The author accepts no responsibility for any mishaps, snafus, fubars or whatnots. Seriously.

Bugs

Although annalate does work over IMAP, my primary motivation was for a tool that I could run locally on my mail server. Consequently, minimal effort has been expended on making annalate play well when competing for mailbox locks with other IMAP clients. This hasn't proven problematic when operating on local mailboxes. Because I didn't have sufficient time or motivation to do a proper job of dealing with authentication, annalate doesn't currently offer any way to use stored authentication details for remote mailboxes -- either the user interacts, or the user takes the risk and writes an expect script. If either of these prove problematic for you, feel free to let me know.

While not a bug as such, it wasn't until after I'd completed annalate (at least to a degree that it was in some way useful) that I realised what a pain it can be to install Mail::Cclient, even from CPAN. I'm not going to start casting aspersions on whose fault that might be, but here are my notes on installing Mail::Cclient on Solaris, linked against Blastwave's imap-devel package, and associated Makefile.patch.

If you find a bug that you're confident isn't down to your mail server, please contact me. Please include as much detail as possible, including:

  • output from perl -V
  • output from uname -a
  • annalate's very verbose -vv output, including the error messages received, if any