Modules now in 'src' folder, COPYING and README added
[imap-restore-mail] / src / restore_mail_inject.py
CommitLineData
67e2ec02
PD
1'''
2restore-mail-inject.py - Tool to inject mails via IMAP
3
4Copyright (c) 2012 Intra2net AG
20760d94 5Author: Plamen Dimitrov and Thomas Jarosch
e42bd6a5 6
20760d94
PD
7This program is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation, either version 3 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
67e2ec02 16'''
f797b0fd 17import logging
67e2ec02
PD
18import argparse
19from mail_iterator import MailIterator
20from file_iterator import FileIterator
5737b10e 21from warnings_handler import WarningsHandler
67e2ec02 22
f797b0fd
PD
23LOG_FILENAME = "restore_mail_inject.log"
24LOG_FILE_LEVEL = logging.DEBUG
25LOG_SHELL_LEVEL = logging.INFO
5737b10e 26LOG_UNCLEAN_EXIT_LEVEL = logging.WARNING
f797b0fd 27
67e2ec02
PD
28def main():
29 """Main function."""
30
31 # prepare configuration
32 args = configure_args()
5737b10e 33 warnings_handler = prepare_logger()
38f15e57
PD
34 logging.info("The module restore_mail_inject.py started with user %s, folder %s and source %s.",
35 args.user, args.folder, args.srcdir)
67e2ec02 36
38f15e57
PD
37 # connect to unix socket or server
38 if(args.unix_socket_disabled):
39 session = MailIterator(args.user)
40 else:
41 session = MailIterator(args.user)
79c28101 42 #session = MailIterator("/var/imap/socket/imap", "cyrus", "geheim")
f797b0fd 43 storage = FileIterator()
67e2ec02 44
e42bd6a5
PD
45 # retrieve mailbox list from the mailbox list file
46 mailbox_list = storage.load_mailbox_list(args.mboxlistfile)
47
67e2ec02 48 # delete olf IMAP folders if no append requested
e42bd6a5 49 if not args.append:
67e2ec02 50 session.delete_mailboxes(args.folder)
e42bd6a5 51 if args.folder == "INBOX":
67e2ec02
PD
52 session.clear_inbox_acls(args.user)
53
54 # inject emails
55 path_generator = storage.load_mails(args.srcdir, args.folder)
56 for message, mailbox, date_modified in path_generator:
f797b0fd 57
e42bd6a5
PD
58 # mailboxes marked for creating and acl update
59 # add acls after all subfolders or their acls will be derived from parent folder
67e2ec02
PD
60 for new_mailbox in storage.created_mailboxes:
61 session.create_mailbox(new_mailbox)
62 for acl_mailbox in storage.acl_mailboxes:
e42bd6a5
PD
63 session.add_acls(acl_mailbox, mailbox_list, args.ouser, args.user)
64 storage.created_mailboxes = []
65 storage.acl_mailboxes = []
f797b0fd 66
67e2ec02 67 session.inject_message(message, mailbox, date_modified)
f797b0fd 68
e42bd6a5
PD
69 # last iteration mailboxes in case root mailbox has no e-mails for injection
70 for new_mailbox in storage.created_mailboxes:
71 session.create_mailbox(new_mailbox)
72 for acl_mailbox in storage.acl_mailboxes:
73 session.add_acls(acl_mailbox, mailbox_list, args.ouser, args.user)
f797b0fd 74
38f15e57 75 logging.info("Finished injecting mails. Exiting with code %s.", warnings_handler.detected_problems)
5737b10e 76 return warnings_handler.detected_problems
67e2ec02
PD
77
78def configure_args():
79 """Configure arguments and return them."""
0cf4dc33 80
67e2ec02
PD
81 # parse arguments
82 parser = argparse.ArgumentParser(description="Tool to inject mails via IMAP.")
83 parser.add_argument('-u', '--username', dest='user', action='store',
84 required=True, help='user to store mails to')
85 parser.add_argument('-f', '--foldername', dest='folder', action='store',
86 default="INBOX", help='folder to store mails to - if not specified we overwrite INBOX')
87 parser.add_argument('-s', '--sourcedir', dest='srcdir', action='store',
88 required=True, help='folder to read mail from')
e42bd6a5 89 parser.add_argument('-m', '--mboxlistfile', dest='mboxlistfile', action='store',
67e2ec02
PD
90 default="", help='mboxlist file (flat file format) to read the ACLs from')
91 parser.add_argument('-o', '--ouser', dest='ouser', action='store',
92 default="", help='name of the original user (=username if not specified)')
93 parser.add_argument('-a', '--append', dest='append', action='store_true',
94 default=False, help="append mails, don't delete anything")
38f15e57
PD
95 parser.add_argument('-n', '--normal', dest='unix_socket_disabled', action='store_true',
96 default=False, help='disable unix socket usage for the IMAP connection')
67e2ec02
PD
97 args = parser.parse_args()
98
99 if (args.folder != "INBOX"):
100 args.folder = "INBOX/" + args.folder
101 if (args.ouser == ""):
102 args.ouser = args.user
103
104 return args
105
f797b0fd
PD
106def prepare_logger():
107 """Sets up the logging functionality"""
108
109 # reset the log
110 with open(LOG_FILENAME, 'w'):
111 pass
112
113 # add basic configuration
114 logging.basicConfig(filename=LOG_FILENAME,
115 format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
116 level=LOG_FILE_LEVEL)
117
118 # add a handler for a console output
5737b10e 119 default_logger = logging.getLogger('')
f797b0fd
PD
120 console = logging.StreamHandler()
121 console.setLevel(LOG_SHELL_LEVEL)
122 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
123 console.setFormatter(formatter)
5737b10e 124 default_logger.addHandler(console)
79c28101 125
5737b10e
PD
126 # add a handler for warnings counting
127 warnings_handler = WarningsHandler()
128 warnings_handler.setLevel(LOG_UNCLEAN_EXIT_LEVEL)
129 default_logger.addHandler(warnings_handler)
0cf4dc33 130
5737b10e 131 return warnings_handler
67e2ec02 132
e42bd6a5 133if __name__ == "__main__":
67e2ec02 134 main()