################################################################################
# mail_archiver.py - Stephane PUYBAREAU (puyb <at> puyb <dot> net) - 2008      # 
# Organise an imap mail box by moving or deleting old messages.                # 
# Messages in INBOX are moved in an INBOX.archive folder organised by year and # 
# quarters. Messages in Sent are move in the archive folder in a sub inbox     # 
# sent. Messages in INBOX.Newsletters are deleted and messages in subdirectory # 
# INBOX.MailingLists ar deleted too.                                           # 
#                                                                              # 
# This software is provided under the terms of the GPL v3 licence.             # 
# See http://www.gnu.org/licenses/gpl.html for more information                # 
#                                                                              # 
# This script use the feedparser module available at http://www.feedparser.org # 
################################################################################



import imaplib
import feedparser
from datetime import date, timedelta
import sys

inbox_archive = 45          # in days
newsletter_delete = 10      # in days
mailing_list_delete = 45    # in days
server = 'localhost'
login  = 'your_login'
passwd = 'your_password'



c = imaplib.IMAP4(server)
c.login(login, passwd)

inboxes = [j.split('"')[-2] for j in c.list()[1]]

def make_inbox(c, inbox):
    global inboxes
    if inbox in inboxes:
        return
    inbox = inbox.split('.')
    for i in range(1, len(inbox)):
        if '.'.join(inbox[:i + 1]) not in inboxes:
            c.create('.'.join(inbox[:i + 1]))
    inboxes = [j.split('"')[-2] for j in c.list()[1]]


# Archive INBOX
c.select()
code, (list,) = c.search(None, 'ALL')
for i in list.split():
    try:
        code, (envelope,) = c.fetch(i, '(ENVELOPE)')
        date_str = envelope[len('%s (ENVELOPE ("' % i):].split('"', 1)[0]
        d = feedparser._parse_date(date_str)
        if not d:
            d = feedparser._parse_date(date_str.split(' ', 1)[1])
        try:
            d = date(*d[:3])
        except:
            d = date.today()
        if d < date.today() - timedelta(jours):
            inbox = 'INBOX.Archives.%s.Q%s' % (d.year, int((d.month - 1) / 3) + 1)
            print i, d, inbox
            make_inbox(c, inbox)
            c.copy(i, inbox)
            c.store(i, '+FLAGS.SILENT', '\\Deleted')
    except:
        print i, envelope, date_str, date
        import traceback
        traceback.print_exc()
        sys.exit()
c.expunge()
        
# Archive INBOX.Sent
c.select('INBOX.Sent')
code, (list,) = c.search(None, 'ALL')
for i in list.split():
    try:
        code, (envelope,) = c.fetch(i, '(ENVELOPE)')
        date_str = envelope[len('%s (ENVELOPE ("' % i):].split('"', 1)[0]
        d = feedparser._parse_date(date_str)
        if not d:
            d = feedparser._parse_date(date_str.split(' ', 1)[1])
        try:
            d = date(*d[:3])
        except:
            d = date.today()
        if d < date.today() - timedelta(jours):
            inbox = 'INBOX.Archives.%s.Q%s.Sent' % (d.year, int((d.month - 1) / 3) + 1)
            print i, d, inbox
            make_inbox(c, inbox)
            c.copy(i, inbox)
            c.store(i, '+FLAGS.SILENT', '\\Deleted')
    except:
        print i, envelope, date_str, date
        import traceback
        traceback.print_exc()
        sys.exit()
c.expunge()

# Delete INBOX.Mailing Lists.*
c.select('INBOX.NewsLetters')
code, (list,) = c.search(None, 'ALL')
for i in list.split():
    try:
        code, (envelope,) = c.fetch(i, '(ENVELOPE)')
        date_str = envelope[len('%s (ENVELOPE ("' % i):].split('"', 1)[0]
        d = feedparser._parse_date(date_str)
        if not d:
            d = feedparser._parse_date(date_str.split(' ', 1)[1])
        try:
            d = date(*d[:3])
        except:
            d = date.today()
        if d < date.today() - timedelta(jours2):
            print i, d, 'INBOX.NewsLetters'
            c.store(i, '+FLAGS.SILENT', '\\Deleted')
    except:
        print i, envelope, date_str, date
        import traceback
        traceback.print_exc()
        sys.exit()
c.expunge()

# Delete INBOX.Mailing Lists.*
for inbox in [i for i in inboxes if i.startswith('INBOX.Mailing Lists.')]:
    c.select(inbox)
    code, (list,) = c.search(None, 'ALL')
    for i in list.split():
        try:
            code, (envelope,) = c.fetch(i, '(ENVELOPE)')
            date_str = envelope[len('%s (ENVELOPE ("' % i):].split('"', 1)[0]
            d = feedparser._parse_date(date_str)
            if not d:
                d = feedparser._parse_date(date_str.split(' ', 1)[1])
            try:
                d = date(*d[:3])
            except:
                d = date.today()
            if d < date.today() - timedelta(jours):
                print i, d, inbox
                c.store(i, '+FLAGS.SILENT', '\\Deleted')
        except:
            print i, envelope, date_str, date
            import traceback
            traceback.print_exc()
            sys.exit()
    c.expunge()


c.close()
