File and console logging added for exception handling and information
[imap-restore-mail] / restore_mail_inject.py
index fc41f01..c67e6ed 100644 (file)
@@ -2,47 +2,66 @@
 restore-mail-inject.py - Tool to inject mails via IMAP
 
 Copyright (c) 2012 Intra2net AG
-'''
 
+This program relies on the following assumptions:
+- IMAP hierarchy separator is / (unixhierarysep=yes)
+- INBOX maps to user/[username]
+- internal encoding of . etc. as of cyrus 2.2
+'''
+import logging
 import argparse
 from mail_iterator import MailIterator
 from file_iterator import FileIterator
 
+LOG_FILENAME = "restore_mail_inject.log"
+LOG_FILE_LEVEL = logging.DEBUG
+LOG_SHELL_LEVEL = logging.INFO
+
 def main():
     """Main function."""
 
     # prepare configuration
     args = configure_args()
-    print("The module restore_mail_inject.py started with user %s, folder %s and source %s." %
+    prepare_logger()
+    logging.info("The module restore_mail_inject.py started with user %s, folder %s and source %s." %
           (args.user, args.folder, args.srcdir))
 
     # connect
-    try:
-        session = MailIterator("gwt-intranator.m.i2n", "mit.punkt", "mit.punkt")
-        #session = MailIterator("/var/imap/socket/imap", "cyrus", "geheim")
-        storage = FileIterator(args.mboxlist)
-    except UserWarning:
-        print("Couldn't connect to IMAP server.")
-        return
+    session = MailIterator(args.user)
+    #session = MailIterator("/var/imap/socket/imap", "cyrus", "geheim")
+    storage = FileIterator()
+
+    # retrieve mailbox list from the mailbox list file
+    mailbox_list = storage.load_mailbox_list(args.mboxlistfile)
 
     # delete olf IMAP folders if no append requested
-    if(not args.append):
+    if not args.append:
         session.delete_mailboxes(args.folder)
-        if(args.folder == "INBOX"):
+        if args.folder == "INBOX":
             session.clear_inbox_acls(args.user)
 
     # inject emails
     path_generator = storage.load_mails(args.srcdir, args.folder)
     for message, mailbox, date_modified in path_generator:
+
+        # mailboxes marked for creating and acl update
+        # add acls after all subfolders or their acls will be derived from parent folder
         for new_mailbox in storage.created_mailboxes:
             session.create_mailbox(new_mailbox)
         for acl_mailbox in storage.acl_mailboxes:
-            session.add_acls(acl_mailbox, args)
+            session.add_acls(acl_mailbox, mailbox_list, args.ouser, args.user)
+        storage.created_mailboxes = []
+        storage.acl_mailboxes = []
+
         session.inject_message(message, mailbox, date_modified)
-        # add acls after all subfolders or their acls will be derived from parent folder
 
-    print("Finished injecting mails.")
+    # last iteration mailboxes in case root mailbox has no e-mails for injection
+    for new_mailbox in storage.created_mailboxes:
+        session.create_mailbox(new_mailbox)
+    for acl_mailbox in storage.acl_mailboxes:
+        session.add_acls(acl_mailbox, mailbox_list, args.ouser, args.user)
 
+    logging.info("Finished injecting mails. Exiting.")
     return
 
 def configure_args():
@@ -55,7 +74,7 @@ def configure_args():
                         default="INBOX", help='folder to store mails to - if not specified we overwrite INBOX')
     parser.add_argument('-s', '--sourcedir', dest='srcdir', action='store',
                         required=True, help='folder to read mail from')
-    parser.add_argument('-m', '--mboxlist', dest='mboxlist', action='store',
+    parser.add_argument('-m', '--mboxlistfile', dest='mboxlistfile', action='store',
                         default="", help='mboxlist file (flat file format) to read the ACLs from')
     parser.add_argument('-o', '--ouser', dest='ouser', action='store',
                         default="", help='name of the original user (=username if not specified)')
@@ -70,6 +89,25 @@ def configure_args():
 
     return args
 
+def prepare_logger():
+    """Sets up the logging functionality"""
+
+    # reset the log
+    with open(LOG_FILENAME, 'w'):
+        pass
+
+    # add basic configuration
+    logging.basicConfig(filename=LOG_FILENAME,
+                        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
+                        level=LOG_FILE_LEVEL)
+
+    # add a handler for a console output
+    console = logging.StreamHandler()
+    console.setLevel(LOG_SHELL_LEVEL)
+    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
+    console.setFormatter(formatter)
+    logging.getLogger('').addHandler(console)
+    return
 
-if(__name__ == "__main__"):
+if __name__ == "__main__":
     main()