#!/usr/bin/python
#
# vim: tabstop=4 expandtab shiftwidth=4 noautoindent
#
# archive.py -- Archive maildir folders
#
# Copyright (C) 2010 Steve Crook <steve@mixmin.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.

from email.utils import parsedate
from mailbox import Maildir
from os.path import isdir
import sys
import time

def convert_rfc2822_date_to_days_old(date_string):
    "Take an RFC2822 formatted date and return how many days old it is."
    date_tuple = parsedate(date_string)
    date_epoch = time.mktime(date_tuple)
    seconds_ago = time.time() - date_epoch
    return round(seconds_ago / (24 * 60 * 60), 2)

def args_to_folder_list(args):
    "Check if supplied arguements relate to valid maildir folders."
    if len(args) < 2:
        sys.stdout.write("No folders to archive\n")
        sys.exit(1)
    maybe_dirs = args[1:]
    mail_dirs = []
    for directory in maybe_dirs:
        if isdir(directory):
            if (isdir(directory + '/new')
                and isdir(directory + '/cur')
                and isdir(directory + '/tmp')):
                mail_dirs.append(directory)
            else:
                sys.stdout.write("Directory %s is an invalid Maildir\n" \
                                % directory)
        else:
            sys.stdout.write("Directory %s does not exist\n" % directory)
    return mail_dirs

#Process the arguements passed on the command line.  The function returns a
# list of (seemingly) valid maildirs.
mail_dirs = args_to_folder_list(sys.argv)

#Process each directory in mail_dirs sequentially.
for mail_dir in mail_dirs:
    # We assume the archive maildir will sit under the maildir it's archiving
    mail_archive = mail_dir + '/archive'
    mailbox = Maildir(mail_dir, factory = None)
    archive = Maildir(mail_archive, factory = None, create = True)

    archive_counter = 0
    for key in mailbox.iterkeys():
        message = mailbox.get(key)
        #TODO We might want to introduce a fallback method for messages with
        #     no Date header.  For now, we ignore such messages.
        if not 'Date' in message:
            continue
        # We default to archiving messages over 365 days old.
        if convert_rfc2822_date_to_days_old(message['Date']) > 365:
            archive_key = archive.add(message)
            # This check is pointless in theory as we just created the key but
            # I like to be sure before deleting the original.
            if archive.has_key(archive_key):
                archive_counter += 1
                mailbox.remove(key)
    sys.stdout.write("Archived %d messages from %s\n" \
                    % (archive_counter, mail_dir))

