E-mail migreren van mbox naar maildir

Armijn Hemel, 30 augustus 2010, 8749 views.

Twee populaire formaten om e-mail op Unix-machines op te slaan zijn mbox en maildir. Elk formaat heeft voor- en nadelen. Migreren van mbox naar maildir is met een klein beetje Python simpel te doen.

Tags: , ,

In het verleden hadden we een systeem waarop we zowel mbox als maildir gebruikten om e-mail op te slaan. De reden hiervoor was een typisch geval van voortschrijdende inzichten. Toen we het systeem opzetten hadden we alleen POP3 en de POP3-software maakte gebruik van mbox. Toen gebruikers waaronder wijzelf liever IMAP wilden, lag de keuze voor maildir voor de hand. Vanaf dat moment hadden we een hybride systeem: mbox voor POP3 en maildir voor IMAP.

Toen we naar een nieuwe machine migreerden besloten we om te standaardizeren op maildir (de POP3-software die we vanaf dat moment gebruiken kan ook makkelijk maildir aan). We hadden nog wel wat accounts die geconverteerd moesten worden van mbox naar maildir. Met een simpel script in Python was dit een fluitje van een cent.

Het script importeert eerst de nodige modules en leest daarna het mbox-bestand in het geheugen:

#!/usr/bin/python
import email
import email.Errors
import mailbox
import os
import sys
import time
def msgfactory(fp):
    try:
        return email.message_from_file(fp)
    except email.Errors.MessageParseError:
        # Don't return None since that will
        # stop the mailbox iterator
        return ''
domain = sys.argv[1]
inbox = sys.argv[2]
fp = open(inbox, 'rb')
mbox = mailbox.UnixMailbox(fp, msgfactory)

In het script is een parameter domain omdat het systeem gebruik maakt van virtuele domeins. Per domein hebben we een map per gebruiker. In ons geval hadden de mbox-bestanden de naam van de gebruiker, zonder de domeinnaam, dus het is makkelijk om per gebruiker een map te maken om de mails in op te slaan.

dirname = domain + "/" + inbox 
# create top level directory, pass if it already exists
try:
        storedir = os.mkdir(domain, 0750)
except:
        pass
# create user directory, pass if it already exists
try:
        storedir = os.mkdir(dirname, 0750)
except:
        pass

Als je een map in een maildir bekijkt dan zal je een aantal standaardmappen zien, waaronder new en cur, waarin respectievelijk nieuwe mails en mails die gezien zijn door een mailprogramma (maar niet noodzakelijkerwijs gelezen) in staan. Deze mappen zijn ook makkelijk op te zetten. In ons geval wisten we dat deze mappen niet bestonden, dus hebben we ze eenvoudig aangemaakt, zonder te controleren of ze al bestonden. Mocht je de inhoud van mbox-bestanden willen integreren in een bestaande IMAP-account, dan zal je wat extra werk moeten doen.

os.mkdir(dirname + "/new", 0750)
os.mkdir(dirname + "/cur", 0750)

Nadat alles opgezet is, is het een kwestie van berichten uit mbox lezen en als een bericht wegschrijven in maildir.

mailmsg = mbox.next()
count = 0
hostname = "imap.example.org"
while (mailmsg) != None:
        count+=1
        hammertime = time.time()
        filename = dirname + "/cur/%s%d.%s:2,S" % (hammertime, count, hostname)
        mail = open(filename, 'w+')
        mail.write(mailmsg.as_string())
        mailmsg = mbox.next()
print "mails converted:", count

Wat opvalt is dat we alle berichten markeren als 'gezien' (door de S aan het eind van de bestandsnaam te plakken). Hoewel dit niet noodzakelijkerwijs correct is (er zou ongelezen mail in de mbox kunnen staan) hebben we deze keuze opzettelijk gemaakt: de gebruikers die veel mail in hun mbox hadden, hadden in hun mailprogramma bijna altijd de optie 'mail op server laten staan' aanstaan. Deze berichten als 'nieuw' aanmerken zou verwarrend zijn geweest, aangezien ze deze berichten al hadden gelezen. Degenen bij wie nieuwe mail als gelezen zou worden gemarkeerd hebben we van tevoren gewaarschuwd en het bleek achteraf geen problemen opgeleverd te hebben.

Creative Commons License Op dit werk is een Creative Commons Licentie van toepassing.
Social networking: Tweet dit artikel op Twitter Geef dit artikel door op LinkedIn Bookmark dit artikel op Google Bookmark dit artikel op Yahoo! Bookmark dit artikel op Technorati Bookmark dit artikel op Delicious Deel dit artikel op Facebook Digg dit artikel op Digg Zend dit artikel naar to Reddit Geef dit artikel een duim omhoog op StumbleUpon Zend dit artikel naar Furl

Talkback

reageer op dit artikel