1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 """ This module contains the ImapMessage class, which derives from
22 mailbox.Message. The full interface of mailbox.Message including
23 conversion to and from other subclasses of mailbox.Message is
24 implemented.
25 """
26
27 import imaplib
28 import mailbox
29 import time
30
31 INTTIME_FROM_MESSAGE = True
32
33
34
35
36
37
38
39
40
42 """ Message with IMAP-specific properties. This class holds information
43 about an IMAP email message that.
44 IMAP specific properties consist of IMAP flags, the internal
45 date (date when received by the server), and possibly the message
46 size.
47
48 Class specific attributes are:
49
50 internaldate the date and time when the IMAP server received
51 the message (time tuple)
52 size number of bytes of the message, 0 if unknown
53 """
55 """ If message is omitted, create new instance in a default, empty
56 state. If message is an email.Message.Message instance, its
57 contents are copied; furthermore, any format-specific information
58 is converted insofar as possible if message is a Message instance.
59 If message is a string or a file, it should contain an
60 RFC 2822-compliant message, which is read and parsed.
61 When a MaildirMessage instance is created based upon an
62 mailbox.mboxMessage or mailbox.MMDFMessage instance, the
63 Status: and X-Status: headers are omitted.
64 """
65 self._imapflags = []
66 self.internaldate = time.localtime()
67 self.size = 0
68 mailbox.Message.__init__(self, message)
69 self._get_explanation_from(message)
70 if isinstance(message, (mailbox.mboxMessage, mailbox.MMDFMessage)):
71 del self['status']
72 del self['x-status']
73
111
113 """Copy IMAP-specific state to message insofar as possible."""
114 if isinstance(message, ImapMessage):
115 message._imapflags = self._imapflags
116 message.internaldate = self.internaldate
117 message.size = self.size
118 elif isinstance(message, mailbox.MaildirMessage):
119 for flag in maildirflags_from_imap_message(self):
120 message.add_flag(flag)
121 message.set_date(time.mktime(self.internaldate))
122 elif isinstance(message, (mailbox.mboxMessage, mailbox.MMDFMessage)):
123 for flag in mboxflags_from_imap_message(self):
124 message.add_flag(flag)
125 message.set_from('MAILER-DAEMON', time.mktime(self.internaldate))
126 elif isinstance(message, mailbox.MHMessage):
127 for sequence in mhsequences_from_imap_message(self):
128 message.add_sequence(sequence)
129 elif isinstance(message, mailbox.BabylMessage):
130 for label in babyllabels_from_imap_message(self):
131 message.add_label(label)
132 elif isinstance(message, mailbox.Message):
133 pass
134 else:
135 raise TypeError('Cannot convert to specified type: %s' %
136 type(message))
137
138
140 """ Return string for imap flags """
141 return "(%s)" % ' '.join(self._imapflags)
142
143
145 """ Set the flags from a string as returned by
146 self.flagstring()
147 """
148 self.set_imapflags(flagstring[1:-1].split())
149
151 """ Add the \Deleted flag to the list of imap flags """
152 if not "\\Deleted" in self._imapflags:
153 self._imapflags.append("\\Deleted")
154
156 """ Remove flags from the list of imap flags. Do nothing if the
157 flag does not exist. Remember that this is a local modification.
158 """
159 new_imapflags = []
160 flags = [flag.upper() for flag in flags]
161 for flagname in self._imapflags:
162 if not flagname.upper() in flags:
163 new_imapflags.append(flagname)
164 self._imapflags = new_imapflags
165
167 """ Add a flag to the list of imap flags.
168 You cannot add "\RECENT" as a flag.
169 """
170 for flag in flags:
171 if (flag.upper() != "\\RECENT"):
172 if flag not in self._imapflags:
173 self._imapflags.append(flag)
174
176 """ Set imap flags to flags """
177 if isinstance(flags, str):
178 flags = [flags]
179 self._imapflags = []
180 for flag in flags:
181 if (flag.upper() != "\\RECENT"):
182 if flag not in self._imapflags:
183 self._imapflags.append(flag)
184
186 """ Return a list of imap flags """
187 return self._imapflags
188
190 """ Return string for internaldate.
191 Return None if internaldate is None.
192 """
193 if self.internaldate is None:
194 return None
195 return imaplib.Time2Internaldate(self.internaldate)
196
198 """ Set the internaldate from a string as it is returned
199 by self.internaldatestring()
200 """
201 self.internaldate = imaplib.Internaldate2tuple(internaldatestring)
202
203
204
205
206
208 """ Switch key and value in the mappings dict
209 Make new keys upper case
210 """
211 result = {}
212 for (key, value) in mappings.items():
213 value = value.upper()
214 result[value] = key
215 return result
216
218 """ Return a list of IMAP flags from an MaildirMessage"""
219 flagstring = message.get_flags()
220 flags = []
221 mappings = {
222 'D' : '\\Draft',
223 'F' : '\\Flagged',
224 'P' : '$Forwarded',
225 'R' : '\\Answered',
226 'S' : '\\Seen',
227 'T' : '\\Deleted'
228 }
229 for (letter, imapflag) in mappings.items():
230 if letter in flagstring:
231 flags.append(imapflag)
232 return flags
233
234
236 """ Return a string of maildir flags from an ImapMessage"""
237 result = ""
238 imapflags = message.imapflags()
239 mappings = {
240 'D' : '\\Draft',
241 'F' : '\\Flagged',
242 'P' : '$Forwarded',
243 'R' : '\\Answered',
244 'S' : '\\Seen',
245 'T' : '\\Deleted'
246 }
247 mappings = _reverse_mappings(mappings)
248 for imapflag in imapflags:
249 if mappings.has_key(imapflag):
250 result += mappings[imapflag]
251 return result
252
254 """ Return a list of IMAP flags from an mboxMessage"""
255 flagstring = message.get_flags()
256 flags = []
257 mappings = {
258 'F' : '\\Flagged',
259 'A' : '\\Answered',
260 'R' : '\\Seen',
261 'D' : '\\Deleted'
262 }
263 for (letter, imapflag) in mappings.items():
264 if letter in flagstring:
265 flags.append(imapflag)
266 return flags
267
269 """ Return a string of mbox flags from an ImapMessage"""
270 result = ""
271 imapflags = message.imapflags()
272 mappings = {
273 'F' : '\\Flagged',
274 'A' : '\\Answered',
275 'R' : '\\Seen',
276 'D' : '\\Deleted'
277 }
278 mappings = _reverse_mappings(mappings)
279 for imapflag in imapflags:
280 if mappings.has_key(imapflag):
281 result += mappings[imapflag]
282 return result
283
285 """ Return a list of IMAP flags from an MHMessage"""
286 sequences = message.get_sequences()
287 flags = []
288 mappings = {
289 'flagged' : '\\Flagged',
290 'replied' : '\\Answered'
291 }
292 for (sequence, imapflag) in mappings.items():
293 if sequence in sequences:
294 flags.append(imapflag)
295 return flags
296
298 """ Return a list of MH sequences from an ImapMessage"""
299 result = []
300 imapflags = message.imapflags()
301 mappings = {
302 'flagged' : '\\Flagged',
303 'replied' : '\\Answered'
304 }
305 mappings = _reverse_mappings(mappings)
306 for imapflag in imapflags:
307 if mappings.has_key(imapflag):
308 result.append(mappings[imapflag])
309 return result
310
312 """ Return a list of IMAP flags from an BabylMessage"""
313 labels = message.get_labels()
314 flags = []
315 mappings = {
316 'forwarded' : '$Forwarded',
317 'answered' : '\\Answered',
318 'deleted' : '\\Deleted'
319 }
320 for (label, imapflag) in mappings.items():
321 if label in labels:
322 flags.append(imapflag)
323 return flags
324
326 """ Return a list of Babyl lables from an ImapMessage"""
327 result = []
328 imapflags = message.imapflags()
329 mappings = {
330 'forwarded' : '$Forwarded',
331 'answered' : '\\Answered',
332 'deleted' : '\\Deleted'
333 }
334 mappings = _reverse_mappings(mappings)
335 for imapflag in imapflags:
336 if mappings.has_key(imapflag):
337 result.append(mappings[imapflag])
338 return result
339
343
347