How to convert mbox mail files, as found in Thunderbird dir, to Maildir?

Solution 1:

For Thunderbird users, version 60 brought experimental bidirectional mbox to Maildir conversion support. See meta ticket for open issues. Personally I can recommend the dovecot dsync method.

Having recently converted largish Thunderbird mbox folders to Maildir and evaluated your mentioned links, I cannot recommend any of the helper-scripts. There was a 'From:' split one script missed and the message count pre/post migration didn't match, other issues were text-encoding or timestamps with other conversion scripts found on github.

Instead, dsync gave fast (1-2 min on 25k messages) and consistent results, see your mentioned Migration/MailFormat Wiki page: dsync -Dv mirror mbox:~/.thunderbird/<profile/popMail/Account>:INBOX=Inbox. As noted, configure the mail_location=maildir:~/Maildir beforehand. Start with an empty folder and later make it the Account Folder for the Maildir-enabled Thunderbird with some manual cleanup. {cur,new,tmp} in the basedir have to move into "Inbox" and the folder .dot-prefix can be removed. Having a second Maildir-enabled profile will give directions what Thunderbird expects.

Solution 2:

The answer by wbob is useful and detailed. However, I had used a different solution before wbob suggested dovecot conversion. Besides, I ended up with notmuch storage. I have to accept my own answer because that's what got used after all.

I employed a simple Python script making use of mailbox library. (Thanks to notmuch IRC channel on freenode.)

#!/usr/bin/python3
import mailbox
import sys
import os
mbox_filename = sys.argv[1]
maildir_root_dir_name = sys.argv[2]
mbox = mailbox.mbox(mbox_filename, create=False)
mailbox_name = os.path.basename(mbox_filename)
maildir_dir_name = "/".join((maildir_root_dir_name, mailbox_name))
os.mkdir(maildir_dir_name, mode=0o750)
mdir = mailbox.Maildir(maildir_dir_name, create=True)
os.mkdir("/".join((maildir_dir_name, "cur")), mode=0o750)
os.mkdir("/".join((maildir_dir_name, "new")), mode=0o750)
os.mkdir("/".join((maildir_dir_name, "tmp")), mode=0o750)
count = 0
for x in mbox:
    print(x.get_from())
    count += 1
    if count % 1000 == 0:
        print(count)
    mdir.add(x)

Some messages were broken; the script stopped with error and a line number, so I had to use emacs (with vlf to open large files, I believe) to fix the problematic messages in mbox file.

The question deserves more elaborate answer, as it's quite troublesome to accomplish the task for most users. Hopefully, I'll expand this in future.