Dovecot to Zarafa Migration

From Zarafa wiki

Jump to: navigation, search


This article is a community contribution and may include unsupported configurations.

I had to import all mails from a remote mailserver running dovecot-imapd. Below you'll find a python-script doing the imports and recreating the folder structure. In order to access the files on the remote mailserver I used sshfs, which can come in quite handy in cases like these.

You're using this script on your own risk - I don't take any responsibility for damaged, lost, destroyed, blown-up data / hardware /cities or any other harmful things or financial loss or whatever someone might think of, which might be directly or indirectly caused by using this code.

Christof Klaus


   #!/usr/bin/python
   # -*- coding: utf-8 -*-
 
   #################################################
   # file: dovecot-to-zarafa.py
   # creationdate: 09/30/2010
   # author: Christof Klaus
   #
   # loops through the files / folders of a maildir and calls zarafa-dagent
   # with the appropriate params in order to recreate the maildir folder structure in
   # zarafa and to import the mails into these folders
   #
   # furthermore, a conversion of the umlaut-representations that seem to be used in dovecot
   # folder storage to latin-1 is being done..
   #
   # this file has only been tested on a maildir of a dovecot mailserver.
   # no guarantee that it works for any other type of imap-server like cyrus, courier or whatever
   #
   # creates as many threads as maildir/user-combinations are given.
   # call with: ./dovecot-to-zarafa.py <path-to-maildir> <zarafausername> [ <path-to-maildir2> <zarafausername2> ...]
   #
   #################################################
 
   import sys, os
   from threading import Thread
 
   class looper(Thread):
       def __init__(self, maildir, username):
           Thread.__init__(self)
           self.maildir = maildir
           self.username = username
      
       def dagent_cmd(self, folder, file, read=False):
           cmd = '/usr/bin/zarafa-dagent '
           if folder:
               # do special-char replacements
               charmap = {'&-':'&', '&AN8-':'ß', '&AMQ-':'Ä', '&AOQ-':'ä', '&ANY-':'Ö','&APY-':'ö', '&ANw-':'Ü', '&APw-':'ü'}
               for k,v in charmap.items(): folder = folder.replace(k,v)
               cmd += ' --create -p "." --folder "%s" ' % (folder)
           cmd += '-s '
           if read: cmd += ' --read '
           cmd += ' -f "%s" %s' % (file, self.username)
           cmd = unicode(cmd, 'utf-8')
           cmd = cmd.encode('latin-1')
           os.system(cmd)
 
       def loop_maildir(self, fld, read=True, create_in_folder=):
           if os.path.exists(fld) and os.path.isdir(fld):
               for sfn in os.listdir(fld):
                   mp = '%s/%s' % (fld, sfn)
                   self.dagent_cmd(create_in_folder, mp, read)
                                      
       def run(self):
           for fn in os.listdir(self.maildir): # examine every subfolder, starting with a "."
               np = '%s/%s' % (self.maildir, fn)
              
               # a default maildir folder, at least with dovecot
               if fn[0] == '.':
                       if os.path.isdir(np):
                           print "d2z@%s, importing: %s" % (self.username, fn[1:])
                           self.loop_maildir('%s/cur' % np, True, fn[1:])
                           self.loop_maildir('%s/new' % np, False, fn[1:])
                           self.loop_maildir('%s/tmp' % np, True, fn[1:])
              
               # the "inbox"-folders on toplevel.
               elif fn in ['cur','new','tmp']:
                   print "d2z@%s, importing: inbox/%s" % (self.username, fn)
                   self.loop_maildir(np, True, )
 
   ## MAIN MAIN MAIN
   args = sys.argv
   bad_args = True
   if len(args) >= 3:
           args = args[1:]
           if divmod(len(args),2)[1] == 0: bad_args = False
           if not bad_args:
               threads = []
 
               for i in range(0, len(args),2):
                   maildir = args[i]
                   username = args[i+1]
                   if os.path.exists(maildir):
                       print "starting thread for maildir: %s, username: %s" % (maildir, username)
                       t = looper(maildir, username)
                       threads.append(t)
                       t.start()
                   else:
                       print "not starting thread for maildir: %s, username: %s, directory does not exist." % (maildir, username)
 
   if bad_args:
           print "insufficient /incorrect number of arguments given.\nusage: dovecot-to-zarafa.py <path-to-maildir> <zarafausername> [ <path-to-maildir2> <zarafausername2> ] ..."

More informations: http://forums.zarafa.com/viewtopic.php?f=10&t=427&view=unread#p24736

Personal tools