Commit | Line | Data |
---|---|---|
67e2ec02 PD |
1 | ''' |
2 | restore-mail-inject.py - Tool to inject mails via IMAP | |
3 | ||
4 | Copyright (c) 2012 Intra2net AG | |
5 | ''' | |
6 | ||
e42bd6a5 | 7 | import sys, os |
67e2ec02 PD |
8 | import re |
9 | ||
10 | MAIL_FILENAME = re.compile("^[0-9]+\.$") | |
e42bd6a5 PD |
11 | MBOXFILE_LINE = re.compile("^(.*?)\t(?:\d )?default[\t ](.*)$") |
12 | ACL_STRING = re.compile("^(.*?)[\t ](.*?)\t(.*)$") | |
67e2ec02 PD |
13 | |
14 | class FileIterator: | |
15 | """This class iterates through the e-mail files.""" | |
16 | ||
17 | # class attributes | |
18 | # mailbox database? | |
19 | mboxdb = None | |
20 | # mailboxes created during file traversal | |
21 | created_mailboxes = None | |
22 | # mailboxes to update during file traversal | |
23 | acl_mailboxes = None | |
24 | ||
e42bd6a5 | 25 | def __init__(self): |
67e2ec02 | 26 | """Creates a connection and a user session.""" |
e42bd6a5 PD |
27 | self.created_mailboxes = [] |
28 | self.acl_mailboxes = [] | |
67e2ec02 PD |
29 | return |
30 | ||
31 | def __del__(self): | |
32 | """Closes the connection and the user session.""" | |
33 | return | |
34 | ||
67e2ec02 PD |
35 | def _message_read(self, filename): |
36 | """Retrieves a message from the message file.""" | |
37 | try: | |
38 | with open(filename, "r") as msgfile: | |
39 | message = msgfile.read() | |
40 | except: | |
41 | print("Could not open the e-mail file %s.", filename) | |
42 | return message | |
43 | ||
e42bd6a5 PD |
44 | def load_mailbox_list(self, mboxlistfile = ""): |
45 | mboxdb = [] | |
46 | if mboxlistfile != "": | |
47 | try: | |
48 | with open(mboxlistfile, 'r') as acl_file: | |
49 | for line in acl_file: | |
50 | lineparts = [] | |
51 | acls = [] | |
52 | ||
53 | linedata = MBOXFILE_LINE.match(line).groups() | |
54 | #print(linedata) | |
55 | #check this condition | |
56 | if len(linedata) == 0: | |
57 | print("Illegal line in mailbox list dump: %s" % line) | |
58 | sys.exit() | |
59 | ||
60 | lineparts.append(linedata[0]) | |
61 | aclstr = linedata[1] | |
62 | while(aclstr != ""): | |
63 | this_acl = [] | |
64 | acldata = ACL_STRING.match(aclstr).groups() | |
65 | if len(acldata) == 0: | |
66 | print("Illegal line in mailbox list dump: %s" % line) | |
67 | sys.exit() | |
68 | aclstr = acldata[2] | |
69 | this_acl.append(acldata[0]) | |
70 | this_acl.append(acldata[1]) | |
71 | acls.append(this_acl) | |
72 | ||
73 | lineparts.append(acls) | |
74 | mboxdb.append(lineparts) | |
75 | ||
76 | #print(mboxdb) | |
77 | except IOError: | |
78 | print("Could not open mboxlist file %s." % mboxlistfile) | |
79 | return mboxdb | |
80 | ||
67e2ec02 PD |
81 | def load_mails(self, filepath, mailpath): |
82 | """Loads all e-mails from file hierarchy. | |
83 | This recursive generator always returns a tuple of | |
84 | the next found (e-mail, mailbox to store, internaldate).""" | |
67e2ec02 PD |
85 | #print("Entered directory %s -> %s." % (filepath, mailpath)) |
86 | try: | |
87 | filepath = os.path.abspath(filepath) | |
88 | os.chdir(filepath) | |
89 | except OSError: | |
90 | print("Can't open the directory %s." % filepath) | |
91 | return | |
92 | # mark mailboxes that should be created | |
93 | self.created_mailboxes.append(mailpath) | |
94 | subpaths = os.listdir(filepath) | |
95 | for subpath in subpaths: | |
96 | #print("Now checking subpath %s in %s" % (subpath, filepath)) | |
e42bd6a5 | 97 | if subpath == "." or subpath == "..": |
67e2ec02 PD |
98 | continue |
99 | new_filepath = filepath + "/" + subpath | |
100 | if (os.path.isfile(new_filepath)): | |
e42bd6a5 | 101 | if os.path.getsize(new_filepath) == 0: |
67e2ec02 PD |
102 | print("Skipping empty file %s." % subpath) |
103 | else: | |
e42bd6a5 PD |
104 | if MAIL_FILENAME.match(subpath): |
105 | #print("Injecting file %s." % subpath) | |
67e2ec02 PD |
106 | try: |
107 | message = self._message_read(new_filepath) | |
108 | # suggest file modification date for internaldate | |
109 | yield (message, mailpath, os.path.getmtime(new_filepath)) | |
110 | except: | |
111 | print("Could not retrieve mail from file: %s", new_filepath) | |
112 | else: | |
e42bd6a5 | 113 | if os.path.isdir(new_filepath): |
67e2ec02 PD |
114 | # cyrus ^ vs . storage replacement |
115 | subpath = subpath.replace("^", ".") | |
116 | new_mailpath = mailpath + "/" + subpath | |
117 | #print("Inserting mails from directory %s into mailbox %s." % (new_filepath, new_mailpath)) | |
118 | # load_mails($mboxdbref, $origuser, $targetuser) | |
119 | rcrs_generator = self.load_mails(new_filepath, new_mailpath) | |
120 | # you enter the generator in the for loop | |
121 | for rcr in rcrs_generator: | |
122 | yield rcr | |
123 | #print("Done with directory %s and mailbox %s." % (new_filepath, new_mailpath)) | |
124 | # mark mailboxes that need acl update | |
e42bd6a5 | 125 | print("acl %s" % mailpath) |
67e2ec02 PD |
126 | self.acl_mailboxes.append(mailpath) |
127 | return | |
128 | # | |
129 | # | |
130 | # |