#!/usr/bin/python2.4 from cStringIO import StringIO from email.Message import Message import email from email.Generator import Generator import mailbox import optparse import os import smtplib import sys IMPORTERS = {} FOLDERS = {} class ImporterError (Exception): pass class PVMessages (mailbox.PortableUnixMailbox): """Messages object fo PV. Messages are exported in a mbox file. """ def __init__ (self, folder_name): mailbox.PortableUnixMailbox.__init__ (self, file (folder_name), \ factory=self._message_factory) self.folder_name = folder_name def _message_factory (self, fp): message = email.message_from_file (fp) return message class PVFolder (object): """Folder object for PV. For each folder X in the PST, X is exported in a mbox file, and X's children are exported in a directory named X.dir. When a folder X is empty, its children are exported directly in a directory called X (rather than X.dir). """ def __init__ (self, folder_name): if os.path.isabs (folder_name): raise ImporterError ("PVFolder can only work on relative paths") self.folder_name = folder_name if os.path.isdir (folder_name): # folder folder_name is empty self.messages = [] # children are exported in folder_name directly children_dir = folder_name else: # folder folder_name is not empty, and folder_name is a mbox file self.messages = PVMessages (folder_name) # folder_name.dir contains the children children_dir = folder_name + ".dir" self.children = [] if os.path.isdir (children_dir): # we got our children in folder_name.dir for sub_folder in os.path.listdir (children_dir): child = PVFolder (os.path.join (folder_name, sub_folder)) self.children.append (child) FOLDERS ["pv"] = PVFolder class SmtpImporter (object): @classmethod def add_options (self, parser): parser.add_option ("--smtp-server", type="string") parser.add_option ("--smtp-port", type="int") parser.add_option ("--smtp-sender", type="string") parser.add_option ("--smtp-recipient", type="string") parser.set_defaults (smtp_server="localhost", smtp_port=25) def parse_options (self, parser, options): for req_opt in ("smtp_sender", "smtp_recipient"): if getattr (options, req_opt) is None: parser.error ("missing required option %s" % req_opt) self.server = options.smtp_server self.port = options.smtp_port self.sender = options.smtp_sender self.recipient = options.smtp_recipient self.recursive = options.recursive self.smtp = smtplib.SMTP (self.server, self.port) def import_folders (self, folders): for folder in folders: folder_name = folder.folder_name print "Importing folder %s (%d)" % \ (folder_name, len (folder.messages)) for message in folder.messages: message["X-MailImporterType"] = "smtp" message["X-OriginalMailbox"] = folder_name fo = StringIO () generator = Generator (fo) generator.flatten (message) self.smtp.sendmail (self.sender, self.recipient, fo.getvalue ()) if self.recursive: self.import_folders (folder.children) IMPORTERS ["smtp"] = SmtpImporter def main (): parser = optparse.OptionParser () # add common options parser.add_option ("--importer-type", type="choice", \ choices=IMPORTERS.keys ()) parser.add_option ("--folder-type", type="choice", \ choices=FOLDERS.keys ()) parser.add_option ("--recursive", action="store_true", dest="recursive") parser.add_option ("--non-recursive", action="store_false", dest="recursive") # let importers specify their options for importer in IMPORTERS.values (): importer.add_options (parser) parser.set_defaults (recursive=True) options, folders = parser.parse_args () for req_opt in ("importer_type", "folder_type"): if getattr (options, req_opt) is None: parser.error ("missing required option %s" % req_opt) importer = None try: importer = IMPORTERS [options.importer_type] except KeyError: parser.error ("unknown importer %s" % options.importer_type) # pass importer specific options back to the importer importer.parse_options (parser, options) # cross your fingers! importer.import_folders (folders) if __name__ == '__main__': s