import sys, os
import re
+import logging
MAIL_FILENAME = re.compile("^[0-9]+\.$")
MBOXFILE_LINE = re.compile("^(.*?)\t(?:\d )?default[\t ](.*)$")
try:
with open(filename, "r") as msgfile:
message = msgfile.read()
- except:
- print("Could not open the e-mail file %s.", filename)
+ except IOError:
+ logging.warning("Could not open the e-mail file %s", filename)
+ raise
return message
def load_mailbox_list(self, mboxlistfile = ""):
linedata = MBOXFILE_LINE.match(line).groups()
#!!! test this condition
if len(linedata) == 0:
- print("Illegal line in mailbox list dump: %s" % line)
- sys.exit()
+ logging.warning("Illegal line in mailbox list dump: %s" % line)
+ continue
key = linedata[0]
aclstr = linedata[1]
while(aclstr != ""):
acldata = ACL_STRING.match(aclstr).groups()
if len(acldata) == 0:
- print("Illegal line in mailbox list dump: %s" % line)
- sys.exit()
+ logging.error("Illegal acl string in mailbox list dump: %s" % line)
+ continue
aclstr = acldata[2]
acls[acldata[0]]=acldata[1]
mboxdb[key] = acls
-
except IOError:
- print("Could not open mboxlist file %s." % mboxlistfile)
+ logging.warning("Could not open mboxlist file %s" % mboxlistfile)
return mboxdb
def load_mails(self, filepath, mailpath):
"""Loads all e-mails from file hierarchy.
This recursive generator always returns a tuple of
the next found (e-mail, mailbox to store, internaldate)."""
- #print("Entered directory %s -> %s." % (filepath, mailpath))
+ logging.debug("Entered directory %s -> %s" % (filepath, mailpath))
try:
filepath = os.path.abspath(filepath)
os.chdir(filepath)
except OSError:
- print("Can't open the directory %s." % filepath)
+ logging.warning("Can't open the directory %s" % filepath)
return
# mark mailboxes that should be created
self.created_mailboxes.append(mailpath)
subpaths = os.listdir(filepath)
for subpath in subpaths:
- #print("Now checking subpath %s in %s" % (subpath, filepath))
if subpath == "." or subpath == "..":
continue
new_filepath = filepath + "/" + subpath
if (os.path.isfile(new_filepath)):
if os.path.getsize(new_filepath) == 0:
- print("Skipping empty file %s." % subpath)
+ logging.info("Skipping empty file %s" % subpath)
else:
if MAIL_FILENAME.match(subpath):
- #print("Injecting file %s." % subpath)
+ logging.info("Injecting file %s" % subpath)
try:
message = self._message_read(new_filepath)
# suggest file modification date for internaldate
yield (message, mailpath, os.path.getmtime(new_filepath))
- except:
- print("Could not retrieve mail from file: %s" % new_filepath)
+ except IOError:
+ logging.warning("Could not retrieve mail from the file %s" % new_filepath)
else:
if os.path.isdir(new_filepath):
# cyrus ^ vs . storage replacement
subpath = subpath.replace("^", ".")
new_mailpath = mailpath + "/" + subpath
- #print("Inserting mails from directory %s into mailbox %s." % (new_filepath, new_mailpath))
+ logging.debug("Inserting mails from directory %s into mailbox %s" % (new_filepath, new_mailpath))
# load_mails($mboxdbref, $origuser, $targetuser)
rcrs_generator = self.load_mails(new_filepath, new_mailpath)
# you enter the generator in the for loop
for rcr in rcrs_generator:
yield rcr
- #print("Done with directory %s and mailbox %s." % (new_filepath, new_mailpath))
+ logging.debug("Done with directory %s and mailbox %s" % (new_filepath, new_mailpath))
# mark mailboxes that need acl update
self.acl_mailboxes.append(mailpath)
return
\ No newline at end of file
Copyright (c) 2012 Intra2net AG
'''
+import sys
import socket, imaplib
import re
+import logging
MAILBOX_RESP = re.compile(r'\((?P<flags>.*?)\) "(?P<delimiter>.*)" (?P<name>.*)')
UIDVAL_RESP = re.compile(r'(?P<name>.*) \(UIDVALIDITY (?P<uidval>.*)\)')
imap_socket.connect("/var/imap/socket/imap")
self.mail_con.sock = imap_socket
self.mail_con.file = self.mail_con.sock.makefile('rb')
- print("Connected to mail server.")
- except Exception as ex:
- #raise UserWarning("Could not connect to host: %s" % (ex))
- raise
+ logging.info("Connected to mail server.")
+ except (self.mail_con.error, socket.error) as ex:
+ logging.error("Could not connect to host: %s" % (ex))
+ sys.exit()
# log in
try:
self.mail_con.login("cyrus", "geheim")
self.logged_in = True
#self.mail_con.proxyauth(username)
- print("Logged in as %s." % username)
- except:
+ logging.info("Logged in as %s." % username)
+ except self.mail_con.error as ex:
self.logged_in = False
- raise UserWarning("Could not log in as user " + username)
+ logging.error("Could not log in as user %s: %s" % (username, ex))
+ sys.exit()
# list mailboxes
try:
_result, mailboxes = self.mail_con.list()
- except (self.mail_con.error):
- raise UserWarning("Could not retrieve mailboxes for user " + username)
+ except self.mail_con.error as ex:
+ logging.warning("Could not retrieve mailboxes for user %s: %s" % (username, ex))
self.mailboxes = []
for mailbox in mailboxes:
mailbox = MAILBOX_RESP.match(mailbox.decode('iso-8859-1')).groups()
"""Resets the inbox acls for a given user."""
try:
_result, inbox_acls = self.mail_con.getacl("INBOX")
- except:
- print("Could not get the acls of INBOX.")
+ except self.mail_con.error as ex:
+ logging.warning("Could not get the acls of INBOX: %s" % ex)
+ return
inbox_acls = ACLS_RESP.findall(inbox_acls[0][6:])
- #print(inbox_acls)
+ logging.debug("Retrieved acls from INBOX are %s" % inbox_acls)
for acl_ref in inbox_acls:
if acl_ref[0] != user:
try:
- self.mail_con.setacl("INBOX", acl_ref[0], "")
- print("Reset acls on INBOX for user %s" % acl_ref[0])
- except:
- print("Could not reset acls on INBOX for user %s" % acl_ref[0])
+ self.mail_con.deleteacl("INBOX", acl_ref[0])
+ logging.debug("Reset acls on INBOX for user %s" % acl_ref[0].decode('iso-8859-1'))
+ except self.mail_con.error as ex:
+ logging.warning("Could not reset acls on INBOX for user %s: %s" % (acl_ref[0], ex))
return
def add_acls(self, mailbox, mailbox_list, original_user, target_user):
if acl_user != target_user and acl_user != original_user:
try:
self.mail_con.setacl(mailbox, acl_user, mbox_acls[acl_user])
- print("Set acls %s for user %s on mailbox %s." % (mbox_acls[acl_user], acl_user, mailbox))
- except:
- print("Could not set acls %s for user %s on mailbox %s." % (mbox_acls[acl_user], acl_user, mailbox))
+ logging.debug("Set acls %s for user %s on mailbox %s" % (mbox_acls[acl_user], acl_user, mailbox))
+ except self.mail_con.error as ex:
+ logging.warning("Could not set acls %s for user %s on mailbox %s: %s" % (mbox_acls[acl_user], acl_user, mailbox, ex))
return
if re.compile(pattern).match(mailbox[2]):
result, data = self.mail_con.delete(mailbox[2])
if result == "OK":
- print("Deleted mailbox %s" % mailbox[2])
+ logging.debug("Deleted mailbox %s" % mailbox[2])
else:
- print("Could not delete folder %s: %s" % (mailbox[2], data[0]))
+ logging.warning("Could not delete mailbox %s: %s" % (mailbox[2], data[0]))
return
def create_mailbox(self, mailbox):
if mailbox != "INBOX":
result, data = self.mail_con.create(mailbox)
if result == "OK":
- print("Creating mailbox %s" % mailbox)
+ logging.debug("Creating mailbox %s" % mailbox)
else:
- print("Could not create mailbox %s: %s" % (mailbox, data[0]))
+ logging.warning("Could not create mailbox %s: %s" % (mailbox, data[0]))
return
def inject_message(self, message, mailbox, internal_date):
"""Inject a message into a mailbox."""
result, data = self.mail_con.append(mailbox, "\\Seen", internal_date, message.encode())
if result == "OK":
- print("Appending message to mailbox %s" % mailbox)
+ logging.debug("Appending message to mailbox %s" % mailbox)
else:
- print("Could not append the e-mail %s: %s" % (message, data[0]))
+ logging.warning("Could not append the e-mail %s: %s" % (message, data[0]))
return
\ No newline at end of file
- 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(args.user)
- #session = MailIterator("/var/imap/socket/imap", "cyrus", "geheim")
- storage = FileIterator()
- except UserWarning as ex:
- print(ex)
- 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)
# 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
- #print(storage.created_mailboxes, storage.acl_mailboxes)
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)
storage.created_mailboxes = []
storage.acl_mailboxes = []
-
+
session.inject_message(message, mailbox, date_modified)
-
+
# 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)
-
- print("Finished injecting mails. Exiting.")
+
+ logging.info("Finished injecting mails. Exiting.")
return
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__":
main()