#!/usr/bin/python # -*- coding: utf-8 -*- # # This script permit to transform Thunderbird mail directory in # Maildir format. This script take Thunderbird mail directory path # (-m parameter) and inspect content to find mbox file and convert # relative path in maildir hierarchic path. You could use -r # parameter to replace accents in maildir path to avoid encoding # problems. It use perfect_maildir.pl [1] script (path could be # specify by using -P parameter) to convert mbox file to Maildir. # # Author : Benjamin Renard # Date : Wed, 25 Dec 2013 20:41:39 +0100 # Source : http://git.zionetrix.net/thunderbird2sogo from optparse import OptionParser import os import re import logging import sys import subprocess from replace_accents import replace_accents parser = OptionParser() parser.add_option('-m', action="store", type="string", dest="mbdir", help="The Mbox Thunderbird mail directory", default=None) parser.add_option('-M', action="store", type="string", dest="mddir", help="The maildir directory", default=None) parser.add_option('-P', action="store", type="string", dest="perfectmaildir", help="The perfect_maildir.pl script path", default='perfect_maildir.pl') parser.add_option('-t', '--just-try', action="store_true", dest="justtry") parser.add_option('-r', '--replace-accents', help='Remove accent in folder names', action="store_true", dest="replaceaccents") parser.add_option('-v', '--verbose', action="store_true", dest="verbose") parser.add_option('-d', '--debug', action="store_true", dest="debug") (options, args) = parser.parse_args() if options.debug: loglevel=logging.DEBUG elif options.verbose: loglevel=logging.INFO else: loglevel=logging.WARNING logging.basicConfig(level=loglevel,format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p') if not options.mbdir or not options.mddir: logging.fatal('You must provide Mbox directory and Maildir directory') sys.exit(1) if not os.path.isdir(options.mbdir): logging.fatal('The directory %s does not exists' % options.mbdir) sys.exit(1) options.mbdir=os.path.abspath(options.mbdir) if os.path.exists(options.mddir): logging.fatal('The destination Maildir directory already exists') sys.exit(1) def maildir_make(dir): if options.justtry: logging.info('Maildir make %s' % dir) return os.mkdir(dir) for s in ['cur','new','tmp']: os.mkdir('%s/%s' % (dir,s)) def isMboxFile(file): return open(file,'r').readline().startswith('From ') maildir_make(options.mddir) options.mddir=os.path.abspath(options.mddir) def listMbox(dir,mboxlist): for fname in os.listdir(dir): path="%s%s" % (dir,fname) if os.path.isfile(path): if not re.search('\.(msf|dat|html|wdseml)$',fname) and isMboxFile(path): md=re.sub('\.sbd/','/',path) md=re.sub('^\.\/','.',md) md=re.sub('\/+','.',md) md=re.sub('^\.Inbox(\.|$)','INBOX.',md) if options.replaceaccents: md=replace_accents(md) md=md.decode('utf-8').encode('utf-7') md=re.sub('\+','&',md) mboxlist[path]=md elif options.debug: logging.debug('File %s is not mbox' % path) elif os.path.isdir(path): path="%s/" % path listMbox(path,mboxlist) else: print "unknown path '%s'" % path mboxlist={} os.chdir(options.mbdir) listMbox('./',mboxlist) def runPerfectMaildir(maildir,mbox): if options.justtry: logging.info("Run perfect_maildir.pl on maildir '%s' with mbox file '%s'" % (maildir, mbox)) return logging.info("Read mbox file %s" % mbox) f=open(mbox,'r') data=f.read() f.close() logging.info("Running perfect_maildir.pl on maildir '%s' with mbox file '%s'" % (maildir,mbox)) p = subprocess.Popen(['perfect_maildir.pl',maildir],stdout=subprocess.PIPE,stderr=subprocess.PIPE,stdin=subprocess.PIPE) output, err = p.communicate(data) logging.info("End of perfect_maildir.pl : %s" % (output)) if './Inbox' in mboxlist: runPerfectMaildir(options.mddir,'%s/Inbox' %options.mbdir) del mboxlist['./Inbox'] subs=[] for mbox in sorted(mboxlist.keys()): maildir_make("%s/%s" % (options.mddir,mboxlist[mbox])) runPerfectMaildir('%s/%s' % (options.mddir,mboxlist[mbox]),'%s/%s' % (options.mbdir,mbox)) subs.append(re.sub('^\.','',mboxlist[mbox])) if not options.justtry: f=open('%s/subscriptions' % options.mddir,'w') logging.info('Write in subscriptions file :') for s in subs: logging.info(s) if not options.justtry: f.write("%s\n" % s) if not options.justtry: f.close()