Mercurial > libervia-backend
comparison src/plugins/plugin_misc_maildir.py @ 594:e629371a28d3
Fix pep8 support in src/plugins.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 18 Jan 2013 17:55:35 +0100 |
parents | beaf6bec2fcd |
children | 84a6e83157c2 |
comparison
equal
deleted
inserted
replaced
593:70bae685d05c | 594:e629371a28d3 |
---|---|
19 along with this program. If not, see <http://www.gnu.org/licenses/>. | 19 along with this program. If not, see <http://www.gnu.org/licenses/>. |
20 """ | 20 """ |
21 | 21 |
22 from logging import debug, info, error | 22 from logging import debug, info, error |
23 import warnings | 23 import warnings |
24 warnings.filterwarnings('ignore','the MimeWriter',DeprecationWarning,'twisted' ) #FIXME: to be removed, see http://twistedmatrix.com/trac/ticket/4038 | 24 warnings.filterwarnings('ignore', 'the MimeWriter', DeprecationWarning, 'twisted') # FIXME: to be removed, see http://twistedmatrix.com/trac/ticket/4038 |
25 from twisted.internet import protocol | 25 from twisted.internet import protocol |
26 from twisted.words.protocols.jabber import error as jab_error | 26 from twisted.words.protocols.jabber import error as jab_error |
27 from twisted.cred import portal,checkers | 27 from twisted.cred import portal, checkers |
28 from twisted.mail import imap4,maildir | 28 from twisted.mail import imap4, maildir |
29 from email.parser import Parser | 29 from email.parser import Parser |
30 import email.message | 30 import email.message |
31 from email.charset import Charset | 31 from email.charset import Charset |
32 import os,os.path | 32 import os |
33 from cStringIO import StringIO | 33 from cStringIO import StringIO |
34 from twisted.internet import reactor | 34 from twisted.internet import reactor |
35 import pdb | 35 import pdb |
36 from sat.core.exceptions import ProfileUnknownError | 36 from sat.core.exceptions import ProfileUnknownError |
37 from sat.memory.persistent import PersistentBinaryDict | 37 from sat.memory.persistent import PersistentBinaryDict |
38 | 38 |
39 | |
40 from zope.interface import implements | 39 from zope.interface import implements |
41 | 40 |
42 | |
43 PLUGIN_INFO = { | 41 PLUGIN_INFO = { |
44 "name": "Maildir Plugin", | 42 "name": "Maildir Plugin", |
45 "import_name": "Maildir", | 43 "import_name": "Maildir", |
46 "type": "Misc", | 44 "type": "Misc", |
47 "protocols": [], | 45 "protocols": [], |
48 "dependencies": [], | 46 "dependencies": [], |
49 "main": "MaildirBox", | 47 "main": "MaildirBox", |
50 "handler": "no", | 48 "handler": "no", |
51 "description": _("""Intercept "normal" type messages, and put them in a Maildir type box""") | 49 "description": _("""Intercept "normal" type messages, and put them in a Maildir type box""") |
52 } | 50 } |
53 | 51 |
54 MAILDIR_PATH = "Maildir" | 52 MAILDIR_PATH = "Maildir" |
53 | |
55 | 54 |
56 class MaildirError(Exception): | 55 class MaildirError(Exception): |
57 pass | 56 pass |
57 | |
58 | 58 |
59 class MaildirBox(object): | 59 class MaildirBox(object): |
60 | 60 |
61 def __init__(self, host): | 61 def __init__(self, host): |
62 info(_("Plugin Maildir initialization")) | 62 info(_("Plugin Maildir initialization")) |
63 self.host = host | 63 self.host = host |
64 | 64 |
65 self.__observed={} | 65 self.__observed = {} |
66 self.data={} #list of profile spectific data. key = profile, value = PersistentBinaryDict where key=mailbox name, | 66 self.data = {} # list of profile spectific data. key = profile, value = PersistentBinaryDict where key=mailbox name, |
67 # and value is a dictionnary with the following value | 67 # and value is a dictionnary with the following value |
68 # - cur_idx: value of the current unique integer increment (UID) | 68 # - cur_idx: value of the current unique integer increment (UID) |
69 # - message_id (as returned by MaildirMailbox): a tuple of (UID, [flag1, flag2, ...]) | 69 # - message_id (as returned by MaildirMailbox): a tuple of (UID, [flag1, flag2, ...]) |
70 pList=host.memory.getProfilesList #shorter :) | 70 pList = host.memory.getProfilesList # shorter :) |
71 self.__mailboxes={} #key: profile, value: {boxname: MailboxUser instance} | 71 self.__mailboxes = {} # key: profile, value: {boxname: MailboxUser instance} |
72 | 72 |
73 #the triggers | 73 #the triggers |
74 host.trigger.add("MessageReceived", self.messageReceivedTrigger) | 74 host.trigger.add("MessageReceived", self.messageReceivedTrigger) |
75 | 75 |
76 def profileConnected(self, profile): | 76 def profileConnected(self, profile): |
77 """Called on profile connection, create profile data""" | 77 """Called on profile connection, create profile data""" |
78 self.data[profile] = PersistentBinaryDict("plugin_maildir", profile) | 78 self.data[profile] = PersistentBinaryDict("plugin_maildir", profile) |
79 self.__mailboxes[profile]={} | 79 self.__mailboxes[profile] = {} |
80 | |
80 def dataLoaded(ignore): | 81 def dataLoaded(ignore): |
81 if not self.data[profile]: | 82 if not self.data[profile]: |
82 #the mailbox is new, we initiate the data | 83 #the mailbox is new, we initiate the data |
83 self.data[profile]["INBOX"] = {"cur_idx":0} | 84 self.data[profile]["INBOX"] = {"cur_idx": 0} |
84 self.data[profile].load().addCallback(dataLoaded) | 85 self.data[profile].load().addCallback(dataLoaded) |
85 | 86 |
86 def profileDisconnected(self, profile): | 87 def profileDisconnected(self, profile): |
87 """Called on profile disconnection, free profile's resources""" | 88 """Called on profile disconnection, free profile's resources""" |
88 del self.__mailboxes[profile] | 89 del self.__mailboxes[profile] |
106 @param boxname: name of the box | 107 @param boxname: name of the box |
107 @param observer: method to call when a NewMessage arrive""" | 108 @param observer: method to call when a NewMessage arrive""" |
108 profile = self.host.memory.getProfileName(profile_key) | 109 profile = self.host.memory.getProfileName(profile_key) |
109 if not profile: | 110 if not profile: |
110 raise ProfileUnknownError(profile_key) | 111 raise ProfileUnknownError(profile_key) |
111 if not self.__mailboxes[profile].has_key(boxname): | 112 if boxname not in self.__mailboxes[profile]: |
112 self.__mailboxes[profile][boxname]=MailboxUser(self, boxname, observer, profile=profile) | 113 self.__mailboxes[profile][boxname] = MailboxUser(self, boxname, observer, profile=profile) |
113 else: | 114 else: |
114 if observer: | 115 if observer: |
115 self.addObserver(observer, profile, boxname) | 116 self.addObserver(observer, profile, boxname) |
116 return self.__mailboxes[profile][boxname] | 117 return self.__mailboxes[profile][boxname] |
117 | 118 |
118 def _getProfilePath(self, profile): | 119 def _getProfilePath(self, profile): |
119 """Return a unique path for profile's mailbox | 120 """Return a unique path for profile's mailbox |
120 The path must be unique, usable as a dir name, and bijectional""" | 121 The path must be unique, usable as a dir name, and bijectional""" |
121 return profile.replace('/','_').replace('..','_') #FIXME: this is too naive to work well, must be improved | 122 return profile.replace('/', '_').replace('..', '_') # FIXME: this is too naive to work well, must be improved |
122 | 123 |
123 def _removeBoxAccess(self, boxname, mailboxUser, profile): | 124 def _removeBoxAccess(self, boxname, mailboxUser, profile): |
124 """Remove a reference to a box | 125 """Remove a reference to a box |
125 @param name: name of the box | 126 @param name: name of the box |
126 @param mailboxUser: MailboxUser instance""" | 127 @param mailboxUser: MailboxUser instance""" |
127 if not self.__mailboxes.has_key(boxname): | 128 if boxname not in self.__mailboxes: |
128 err_msg=_("Trying to remove an mailboxUser not referenced") | 129 err_msg = _("Trying to remove an mailboxUser not referenced") |
129 error(_("INTERNAL ERROR: ") + err_msg) | 130 error(_("INTERNAL ERROR: ") + err_msg) |
130 raise MaildirError(err_msg) | 131 raise MaildirError(err_msg) |
131 assert self.__mailboxes[profile][boxname]==mailboxUser | 132 assert self.__mailboxes[profile][boxname] == mailboxUser |
132 del __mailboxes[profile][boxname] | 133 del __mailboxes[profile][boxname] |
133 | 134 |
134 def _checkBoxReference(self, boxname, profile): | 135 def _checkBoxReference(self, boxname, profile): |
135 """Check if there is a reference on a box, and return it | 136 """Check if there is a reference on a box, and return it |
136 @param boxname: name of the box to check | 137 @param boxname: name of the box to check |
137 @return: MailboxUser instance or None""" | 138 @return: MailboxUser instance or None""" |
138 if self.__mailboxes.has_key(profile): | 139 if profile in self.__mailboxes: |
139 if self.__mailboxes[profile].has_key(boxname): | 140 if boxname in self.__mailboxes[profile]: |
140 return self.__mailboxes[profile][boxname] | 141 return self.__mailboxes[profile][boxname] |
141 | 142 |
142 def __getBoxData(self, boxname, profile): | 143 def __getBoxData(self, boxname, profile): |
143 """Return the date of a box""" | 144 """Return the date of a box""" |
144 try: | 145 try: |
145 return self.data[profile][boxname] #the boxname MUST exist in the data | 146 return self.data[profile][boxname] # the boxname MUST exist in the data |
146 except KeyError: | 147 except KeyError: |
147 err_msg=_("Boxname doesn't exist in internal data") | 148 err_msg = _("Boxname doesn't exist in internal data") |
148 error(_("INTERNAL ERROR: ") + err_msg) | 149 error(_("INTERNAL ERROR: ") + err_msg) |
149 raise MaildirError(err_msg) | 150 raise MaildirError(err_msg) |
150 | 151 |
151 def getUid(self, boxname, message_id, profile): | 152 def getUid(self, boxname, message_id, profile): |
152 """Return an unique integer, always ascending, for a message | 153 """Return an unique integer, always ascending, for a message |
153 This is mainly needed for the IMAP protocol | 154 This is mainly needed for the IMAP protocol |
154 @param boxname: name of the box where the message is | 155 @param boxname: name of the box where the message is |
155 @param message_id: unique id of the message as given by MaildirMailbox | 156 @param message_id: unique id of the message as given by MaildirMailbox |
156 @return: Integer UID""" | 157 @return: Integer UID""" |
157 box_data = self.__getBoxData(boxname, profile) | 158 box_data = self.__getBoxData(boxname, profile) |
158 if box_data.has_key(message_id): | 159 if message_id in box_data: |
159 ret = box_data[message_id][0] | 160 ret = box_data[message_id][0] |
160 else: | 161 else: |
161 box_data['cur_idx']+=1 | 162 box_data['cur_idx'] += 1 |
162 box_data[message_id]=[box_data['cur_idx'],[]] | 163 box_data[message_id] = [box_data['cur_idx'], []] |
163 ret = box_data[message_id] | 164 ret = box_data[message_id] |
164 self.data[profile].force(boxname) | 165 self.data[profile].force(boxname) |
165 return ret | 166 return ret |
166 | 167 |
167 def getNextUid(self, boxname, profile): | 168 def getNextUid(self, boxname, profile): |
168 """Return next unique integer that will generated | 169 """Return next unique integer that will generated |
169 This is mainly needed for the IMAP protocol | 170 This is mainly needed for the IMAP protocol |
170 @param boxname: name of the box where the message is | 171 @param boxname: name of the box where the message is |
171 @return: Integer UID""" | 172 @return: Integer UID""" |
172 box_data = self.__getBoxData(boxname, profile) | 173 box_data = self.__getBoxData(boxname, profile) |
173 return box_data['cur_idx']+1 | 174 return box_data['cur_idx'] + 1 |
174 | 175 |
175 def getNextExistingUid(self, boxname, uid, profile): | 176 def getNextExistingUid(self, boxname, uid, profile): |
176 """Give the next uid of existing message | 177 """Give the next uid of existing message |
177 @param boxname: name of the box where the message is | 178 @param boxname: name of the box where the message is |
178 @param uid: uid to start from | 179 @param uid: uid to start from |
179 @return: uid or None if the is no more message""" | 180 @return: uid or None if the is no more message""" |
180 box_data = self.__getBoxData(boxname, profile) | 181 box_data = self.__getBoxData(boxname, profile) |
181 idx=uid+1 | 182 idx = uid + 1 |
182 while self.getIdFromUid(boxname, idx, profile) == None: #TODO: this is highly inefficient because getIdfromUid is inefficient, fix this | 183 while self.getIdFromUid(boxname, idx, profile) is None: # TODO: this is highly inefficient because getIdfromUid is inefficient, fix this |
183 idx+=1 | 184 idx += 1 |
184 if idx>box_data['cur_idx']: | 185 if idx > box_data['cur_idx']: |
185 return None | 186 return None |
186 return idx | 187 return idx |
187 | 188 |
188 def getMaxUid(self, boxname, profile): | 189 def getMaxUid(self, boxname, profile): |
189 """Give the max existing uid | 190 """Give the max existing uid |
196 """Return the message unique id from it's integer UID | 197 """Return the message unique id from it's integer UID |
197 @param boxname: name of the box where the message is | 198 @param boxname: name of the box where the message is |
198 @param message_uid: unique integer identifier | 199 @param message_uid: unique integer identifier |
199 @return: unique id of the message as given by MaildirMailbox or None if not found""" | 200 @return: unique id of the message as given by MaildirMailbox or None if not found""" |
200 box_data = self.__getBoxData(boxname, profile) | 201 box_data = self.__getBoxData(boxname, profile) |
201 for message_id in box_data.keys(): #TODO: this is highly inefficient on big mailbox, must be replaced in the future | 202 for message_id in box_data.keys(): # TODO: this is highly inefficient on big mailbox, must be replaced in the future |
202 if message_id == 'cur_idx': | 203 if message_id == 'cur_idx': |
203 continue | 204 continue |
204 if box_data[message_id][0] == message_uid: | 205 if box_data[message_id][0] == message_uid: |
205 return message_id | 206 return message_id |
206 return None | 207 return None |
209 """Return the messages flags | 210 """Return the messages flags |
210 @param boxname: name of the box where the message is | 211 @param boxname: name of the box where the message is |
211 @param message_idx: message id as given by MaildirMailbox | 212 @param message_idx: message id as given by MaildirMailbox |
212 @return: list of strings""" | 213 @return: list of strings""" |
213 box_data = self.__getBoxData(boxname, profile) | 214 box_data = self.__getBoxData(boxname, profile) |
214 if not box_data.has_key(mess_id): | 215 if mess_id not in box_data: |
215 raise MailboxException("Trying to get flags from an unexisting message") | 216 raise MailboxException("Trying to get flags from an unexisting message") |
216 return box_data[mess_id][1] | 217 return box_data[mess_id][1] |
217 | 218 |
218 def setFlags(self, boxname, mess_id, flags, profile): | 219 def setFlags(self, boxname, mess_id, flags, profile): |
219 """Change the flags of the message | 220 """Change the flags of the message |
220 @param boxname: name of the box where the message is | 221 @param boxname: name of the box where the message is |
221 @param message_idx: message id as given by MaildirMailbox | 222 @param message_idx: message id as given by MaildirMailbox |
222 @param flags: list of strings | 223 @param flags: list of strings |
223 """ | 224 """ |
224 box_data = self.__getBoxData(boxname, profile) | 225 box_data = self.__getBoxData(boxname, profile) |
225 assert(type(flags)==list) | 226 assert(type(flags) == list) |
226 flags=[flag.upper() for flag in flags] #we store every flag UPPERCASE | 227 flags = [flag.upper() for flag in flags] # we store every flag UPPERCASE |
227 if not box_data.has_key(mess_id): | 228 if mess_id not in box_data: |
228 raise MailboxException("Trying to set flags for an unexisting message") | 229 raise MailboxException("Trying to set flags for an unexisting message") |
229 box_data[mess_id][1]=flags | 230 box_data[mess_id][1] = flags |
230 self.data[profile].force(boxname) | 231 self.data[profile].force(boxname) |
231 | 232 |
232 def getMessageIdsWithFlag(self, boxname, flag, profile): | 233 def getMessageIdsWithFlag(self, boxname, flag, profile): |
233 """Return ids of messages where a flag is set | 234 """Return ids of messages where a flag is set |
234 @param boxname: name of the box where the message is | 235 @param boxname: name of the box where the message is |
235 @param flag: flag to check | 236 @param flag: flag to check |
236 @return: list of id (as given by MaildirMailbox)""" | 237 @return: list of id (as given by MaildirMailbox)""" |
237 box_data = self.__getBoxData(boxname, profile) | 238 box_data = self.__getBoxData(boxname, profile) |
238 assert(isinstance(flag,basestring)) | 239 assert(isinstance(flag, basestring)) |
239 flag=flag.upper() | 240 flag = flag.upper() |
240 result = [] | 241 result = [] |
241 for key in box_data: | 242 for key in box_data: |
242 if key=='cur_idx': | 243 if key == 'cur_idx': |
243 continue | 244 continue |
244 if flag in box_data[key][1]: | 245 if flag in box_data[key][1]: |
245 result.append(key) | 246 result.append(key) |
246 return result | 247 return result |
247 | 248 |
248 def purgeDeleted(self, boxname, profile): | 249 def purgeDeleted(self, boxname, profile): |
249 """Remove data for messages with flag "\\Deleted" | 250 """Remove data for messages with flag "\\Deleted" |
250 @param boxname: name of the box where the message is | 251 @param boxname: name of the box where the message is |
251 """ | 252 """ |
252 box_data = self.__getBoxData(boxname, profile) | 253 box_data = self.__getBoxData(boxname, profile) |
253 for mess_id in self.getMessageIdsWithFlag(boxname,"\\Deleted", profile): | 254 for mess_id in self.getMessageIdsWithFlag(boxname, "\\Deleted", profile): |
254 del(box_data[mess_id]) | 255 del(box_data[mess_id]) |
255 self.data[profile].force(boxname) | 256 self.data[profile].force(boxname) |
256 | 257 |
257 def cleanTable(self, boxname, existant_id, profile): | 258 def cleanTable(self, boxname, existant_id, profile): |
258 """Remove mails which no longuer exist from the table | 259 """Remove mails which no longuer exist from the table |
259 @param boxname: name of the box to clean | 260 @param boxname: name of the box to clean |
260 @param existant_id: list of id which actually exist""" | 261 @param existant_id: list of id which actually exist""" |
261 box_data = self.__getBoxData(boxname, profile) | 262 box_data = self.__getBoxData(boxname, profile) |
262 to_remove=[] | 263 to_remove = [] |
263 for key in box_data: | 264 for key in box_data: |
264 if key not in existant_id and key!="cur_idx": | 265 if key not in existant_id and key != "cur_idx": |
265 to_remove.append(key) | 266 to_remove.append(key) |
266 for key in to_remove: | 267 for key in to_remove: |
267 del box_data[key] | 268 del box_data[key] |
268 | 269 |
269 def addObserver(self, callback, profile, boxname, signal="NEW_MESSAGE"): | 270 def addObserver(self, callback, profile, boxname, signal="NEW_MESSAGE"): |
270 """Add an observer for maildir box changes | 271 """Add an observer for maildir box changes |
271 @param callback: method to call when the the box is updated | 272 @param callback: method to call when the the box is updated |
272 @param boxname: name of the box to observe | 273 @param boxname: name of the box to observe |
273 @param signal: which signal is observed by the caller""" | 274 @param signal: which signal is observed by the caller""" |
274 if not self.__observed.has_key((profile,boxname)): | 275 if (profile, boxname) not in self.__observed: |
275 self.__observed[(profile,boxname)]={} | 276 self.__observed[(profile, boxname)] = {} |
276 if not self.__observed[(profile,boxname)].has_key(signal): | 277 if signal not in self.__observed[(profile, boxname)]: |
277 self.__observed[(profile,boxname)][signal]=set() | 278 self.__observed[(profile, boxname)][signal] = set() |
278 self.__observed[(profile,boxname)][signal].add(callback) | 279 self.__observed[(profile, boxname)][signal].add(callback) |
279 | 280 |
280 def removeObserver(self, callback, profile, boxname, signal="NEW_MESSAGE"): | 281 def removeObserver(self, callback, profile, boxname, signal="NEW_MESSAGE"): |
281 """Remove an observer of maildir box changes | 282 """Remove an observer of maildir box changes |
282 @param callback: method to remove from obervers | 283 @param callback: method to remove from obervers |
283 @param boxname: name of the box which was observed | 284 @param boxname: name of the box which was observed |
284 @param signal: which signal was observed by the caller""" | 285 @param signal: which signal was observed by the caller""" |
285 if not self.__observed.has_key((profile,boxname)): | 286 if (profile, boxname) not in self.__observed: |
286 err_msg=_("Trying to remove an observer for an inexistant mailbox") | 287 err_msg = _("Trying to remove an observer for an inexistant mailbox") |
287 error(_("INTERNAL ERROR: ") + err_msg) | 288 error(_("INTERNAL ERROR: ") + err_msg) |
288 raise MaildirError(err_msg) | 289 raise MaildirError(err_msg) |
289 if not self.__observed[(profile,boxname)].has_key(signal): | 290 if signal not in self.__observed[(profile, boxname)]: |
290 err_msg=_("Trying to remove an inexistant observer, no observer for this signal") | 291 err_msg = _("Trying to remove an inexistant observer, no observer for this signal") |
291 error(_("INTERNAL ERROR: ") + err_msg) | 292 error(_("INTERNAL ERROR: ") + err_msg) |
292 raise MaildirError(err_msg) | 293 raise MaildirError(err_msg) |
293 if not callback in self.__observed[(profile,boxname)][signal]: | 294 if not callback in self.__observed[(profile, boxname)][signal]: |
294 err_msg=_("Trying to remove an inexistant observer") | 295 err_msg = _("Trying to remove an inexistant observer") |
295 error(_("INTERNAL ERROR: ") + err_msg) | 296 error(_("INTERNAL ERROR: ") + err_msg) |
296 raise MaildirError(err_msg) | 297 raise MaildirError(err_msg) |
297 self.__observed[(profile,boxname)][signal].remove(callback) | 298 self.__observed[(profile, boxname)][signal].remove(callback) |
298 | 299 |
299 def emitSignal(self, profile, boxname, signal_name): | 300 def emitSignal(self, profile, boxname, signal_name): |
300 """Emit the signal to observer""" | 301 """Emit the signal to observer""" |
301 debug('emitSignal %s %s %s' %(profile, boxname, signal_name)) | 302 debug('emitSignal %s %s %s' % (profile, boxname, signal_name)) |
302 try: | 303 try: |
303 for observer_cb in self.__observed[(profile, boxname)][signal_name]: | 304 for observer_cb in self.__observed[(profile, boxname)][signal_name]: |
304 observer_cb() | 305 observer_cb() |
305 except KeyError: | 306 except KeyError: |
306 pass | 307 pass |
323 #TODO: save thread id | 324 #TODO: save thread id |
324 for e in message.elements(): | 325 for e in message.elements(): |
325 if e.name == "body": | 326 if e.name == "body": |
326 mail.set_payload(e.children[0].encode('utf-8')) | 327 mail.set_payload(e.children[0].encode('utf-8')) |
327 elif e.name == "subject": | 328 elif e.name == "subject": |
328 mail['Subject'] = e.children[0].encode('utf-8') | 329 mail['Subject'] = e.children[0].encode('utf-8') |
329 return mail.as_string() | 330 return mail.as_string() |
330 | 331 |
331 def __init__(self, _maildir, name, observer=None, profile="@NONE@"): | 332 def __init__(self, _maildir, name, observer=None, profile="@NONE@"): |
332 """@param _maildir: the main MaildirBox instance | 333 """@param _maildir: the main MaildirBox instance |
333 @param name: name of the mailbox | 334 @param name: name of the mailbox |
334 @param profile: real profile (ie not a profile_key) | 335 @param profile: real profile (ie not a profile_key) |
335 THIS OBJECT MUST NOT BE USED DIRECTLY: use MaildirBox.accessMessageBox instead""" | 336 THIS OBJECT MUST NOT BE USED DIRECTLY: use MaildirBox.accessMessageBox instead""" |
336 if _maildir._checkBoxReference(name, profile): | 337 if _maildir._checkBoxReference(name, profile): |
337 error ("INTERNAL ERROR: MailboxUser MUST NOT be instancied directly") | 338 error("INTERNAL ERROR: MailboxUser MUST NOT be instancied directly") |
338 raise MailboxException('double MailboxUser instanciation') | 339 raise MailboxException('double MailboxUser instanciation') |
339 if name!="INBOX": | 340 if name != "INBOX": |
340 raise NotImplementedError | 341 raise NotImplementedError |
341 self.name=name | 342 self.name = name |
342 self.profile=profile | 343 self.profile = profile |
343 self.maildir=_maildir | 344 self.maildir = _maildir |
344 profile_path = self.maildir._getProfilePath(profile) | 345 profile_path = self.maildir._getProfilePath(profile) |
345 full_profile_path = os.path.join(self.maildir.host.memory.getConfig('','local_dir'), profile_path) | 346 full_profile_path = os.path.join(self.maildir.host.memory.getConfig('', 'local_dir'), profile_path) |
346 if not os.path.exists(full_profile_path): | 347 if not os.path.exists(full_profile_path): |
347 os.makedirs(full_profile_path,0700) | 348 os.makedirs(full_profile_path, 0700) |
348 mailbox_path = os.path.join(full_profile_path, MAILDIR_PATH) | 349 mailbox_path = os.path.join(full_profile_path, MAILDIR_PATH) |
349 self.mailbox_path=mailbox_path | 350 self.mailbox_path = mailbox_path |
350 self.mailbox = maildir.MaildirMailbox(mailbox_path) | 351 self.mailbox = maildir.MaildirMailbox(mailbox_path) |
351 self.observer=observer | 352 self.observer = observer |
352 self.__uid_table_update() | 353 self.__uid_table_update() |
353 | 354 |
354 if observer: | 355 if observer: |
355 debug("adding observer for %s (%s)" % (name,profile)) | 356 debug("adding observer for %s (%s)" % (name, profile)) |
356 self.maildir.addObserver(observer, profile, name, "NEW_MESSAGE") | 357 self.maildir.addObserver(observer, profile, name, "NEW_MESSAGE") |
357 | 358 |
358 def __uid_table_update(self): | 359 def __uid_table_update(self): |
359 existant_id=[] | 360 existant_id = [] |
360 for mess_idx in range (self.getMessageCount()): | 361 for mess_idx in range(self.getMessageCount()): |
361 #we update the uid table | 362 #we update the uid table |
362 existant_id.append(self.getId(mess_idx)) | 363 existant_id.append(self.getId(mess_idx)) |
363 self.getUid(mess_idx) | 364 self.getUid(mess_idx) |
364 self.maildir.cleanTable(self.name, existant_id, profile=self.profile) | 365 self.maildir.cleanTable(self.name, existant_id, profile=self.profile) |
365 | |
366 | 366 |
367 def __del__(self): | 367 def __del__(self): |
368 if observer: | 368 if observer: |
369 debug("removing observer for %s" % self.name) | 369 debug("removing observer for %s" % self.name) |
370 self._maildir.removeObserver(observer, self.name, "NEW_MESSAGE") | 370 self._maildir.removeObserver(observer, self.name, "NEW_MESSAGE") |
375 @param message: XMPP XML message""" | 375 @param message: XMPP XML message""" |
376 self.mailbox.appendMessage(self.xmppMessage2mail(message)).addCallback(self.emitSignal, "NEW_MESSAGE") | 376 self.mailbox.appendMessage(self.xmppMessage2mail(message)).addCallback(self.emitSignal, "NEW_MESSAGE") |
377 | 377 |
378 def emitSignal(self, ignore, signal): | 378 def emitSignal(self, ignore, signal): |
379 """Emit the signal to the observers""" | 379 """Emit the signal to the observers""" |
380 if signal=="NEW_MESSAGE": | 380 if signal == "NEW_MESSAGE": |
381 self.getUid(self.getMessageCount()-1) #XXX: we make an uid for the last message added | 381 self.getUid(self.getMessageCount() - 1) # XXX: we make an uid for the last message added |
382 self.maildir.emitSignal(self.profile, self.name, signal) | 382 self.maildir.emitSignal(self.profile, self.name, signal) |
383 | 383 |
384 def getId(self, mess_idx): | 384 def getId(self, mess_idx): |
385 """Return the Unique ID of the message | 385 """Return the Unique ID of the message |
386 @mess_idx: message index""" | 386 @mess_idx: message index""" |
387 return self.mailbox.getUidl(mess_idx) | 387 return self.mailbox.getUidl(mess_idx) |
388 | 388 |
389 def getUid(self, mess_idx): | 389 def getUid(self, mess_idx): |
390 """Return a unique interger id for the message, always ascending""" | 390 """Return a unique interger id for the message, always ascending""" |
391 mess_id=self.getId(mess_idx) | 391 mess_id = self.getId(mess_idx) |
392 return self.maildir.getUid(self.name,mess_id, profile=self.profile) | 392 return self.maildir.getUid(self.name, mess_id, profile=self.profile) |
393 | 393 |
394 def getNextUid(self): | 394 def getNextUid(self): |
395 return self.maildir.getNextUid(self.name, profile=self.profile) | 395 return self.maildir.getNextUid(self.name, profile=self.profile) |
396 | 396 |
397 def getNextExistingUid(self, uid): | 397 def getNextExistingUid(self, uid): |
411 | 411 |
412 def getIdxFromUid(self, mess_uid): | 412 def getIdxFromUid(self, mess_uid): |
413 """Return the message index from the uid | 413 """Return the message index from the uid |
414 @param mess_uid: message unique identifier | 414 @param mess_uid: message unique identifier |
415 @return: message index, as managed by MaildirMailbox""" | 415 @return: message index, as managed by MaildirMailbox""" |
416 for mess_idx in range (self.getMessageCount()): | 416 for mess_idx in range(self.getMessageCount()): |
417 if self.getUid(mess_idx) == mess_uid: | 417 if self.getUid(mess_idx) == mess_uid: |
418 return mess_idx | 418 return mess_idx |
419 raise IndexError | 419 raise IndexError |
420 | 420 |
421 def getIdxFromId(self, mess_id): | 421 def getIdxFromId(self, mess_id): |
422 """Return the message index from the unique index | 422 """Return the message index from the unique index |
423 @param mess_id: message unique index as given by MaildirMailbox | 423 @param mess_id: message unique index as given by MaildirMailbox |
424 @return: message sequence index""" | 424 @return: message sequence index""" |
425 for mess_idx in range (self.getMessageCount()): | 425 for mess_idx in range(self.getMessageCount()): |
426 if self.mailbox.getUidl(mess_idx) == mess_id: | 426 if self.mailbox.getUidl(mess_idx) == mess_id: |
427 return mess_idx | 427 return mess_idx |
428 raise IndexError | 428 raise IndexError |
429 | 429 |
430 def getMessage(self, mess_idx): | 430 def getMessage(self, mess_idx): |
446 | 446 |
447 def getFlagsUid(self, mess_uid): | 447 def getFlagsUid(self, mess_uid): |
448 """Return the flags of the message | 448 """Return the flags of the message |
449 @param mess_uid: message unique identifier | 449 @param mess_uid: message unique identifier |
450 @return: list of strings""" | 450 @return: list of strings""" |
451 id = self.maildir.getIdFromUid(self.name,mess_uid, profile=self.profile) | 451 id = self.maildir.getIdFromUid(self.name, mess_uid, profile=self.profile) |
452 return self.maildir.getFlags(self.name, id, profile=self.profile) | 452 return self.maildir.getFlags(self.name, id, profile=self.profile) |
453 | 453 |
454 def setFlags(self, mess_idx, flags): | 454 def setFlags(self, mess_idx, flags): |
455 """Change the flags of the message | 455 """Change the flags of the message |
456 @param mess_idx: message index | 456 @param mess_idx: message index |
462 def setFlagsUid(self, mess_uid, flags): | 462 def setFlagsUid(self, mess_uid, flags): |
463 """Change the flags of the message | 463 """Change the flags of the message |
464 @param mess_uid: message unique identifier | 464 @param mess_uid: message unique identifier |
465 @param flags: list of strings | 465 @param flags: list of strings |
466 """ | 466 """ |
467 id = self.maildir.getIdFromUid(self.name,mess_uid, profile=self.profile) | 467 id = self.maildir.getIdFromUid(self.name, mess_uid, profile=self.profile) |
468 return self.maildir.setFlags(self.name, id, flags, profile=self.profile) | 468 return self.maildir.setFlags(self.name, id, flags, profile=self.profile) |
469 | 469 |
470 def getMessageIdsWithFlag(self, flag): | 470 def getMessageIdsWithFlag(self, flag): |
471 """Return ids of messages where a flag is set | 471 """Return ids of messages where a flag is set |
472 @param flag: flag to check | 472 @param flag: flag to check |
473 @return: list of id (as given by MaildirMailbox)""" | 473 @return: list of id (as given by MaildirMailbox)""" |
474 return self.maildir.getMessageIdsWithFlag(self.name,flag, profile=self.profile) | 474 return self.maildir.getMessageIdsWithFlag(self.name, flag, profile=self.profile) |
475 | 475 |
476 def removeDeleted(self): | 476 def removeDeleted(self): |
477 """Actually delete message flagged "\\Deleted" | 477 """Actually delete message flagged "\\Deleted" |
478 Also purge the internal data of these messages | 478 Also purge the internal data of these messages |
479 """ | 479 """ |
480 for mess_id in self.getMessageIdsWithFlag("\\Deleted"): | 480 for mess_id in self.getMessageIdsWithFlag("\\Deleted"): |
481 print ("Deleting %s" % mess_id) | 481 print ("Deleting %s" % mess_id) |
482 self.mailbox.deleteMessage(self.getIdxFromId(mess_id)) | 482 self.mailbox.deleteMessage(self.getIdxFromId(mess_id)) |
483 self.mailbox = maildir.MaildirMailbox(self.mailbox_path) #We need to reparse the dir to have coherent indexing | 483 self.mailbox = maildir.MaildirMailbox(self.mailbox_path) # We need to reparse the dir to have coherent indexing |
484 self.maildir.purgeDeleted(self.name, profile=self.profile) | 484 self.maildir.purgeDeleted(self.name, profile=self.profile) |
485 | 485 |
486 def emptyTrash(self): | 486 def emptyTrash(self): |
487 """Delete everything in the .Trash dir""" | 487 """Delete everything in the .Trash dir""" |
488 import shutils | 488 import shutils |
489 pdb.set_trace() | 489 pdb.set_trace() |
490 |