Mercurial > libervia-backend
comparison src/plugins/plugin_misc_maildir.py @ 257:012c38b56cdd
plugin IMAP, plugin Maildir: profile management
- IMAP Login/pass is now checked against profile name/jabber pass
- Mailboxes are now per-profile
- flags are now checked without case sensitiveness
author | Goffi <goffi@goffi.org> |
---|---|
date | Tue, 18 Jan 2011 00:57:26 +0100 |
parents | 55b750017b71 |
children | 11f71187d5e4 |
comparison
equal
deleted
inserted
replaced
256:f5181f6dd98f | 257:012c38b56cdd |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # -*- coding: utf-8 -*- | 2 # -*- coding: utf-8 -*- |
3 | 3 |
4 """ | 4 """ |
5 SAT plugin for managing imap server | 5 SàT plugin for managing Maildir type mail boxes |
6 Copyright (C) 2011 Jérôme Poisson (goffi@goffi.org) | 6 Copyright (C) 2011 Jérôme Poisson (goffi@goffi.org) |
7 | 7 |
8 This program is free software: you can redistribute it and/or modify | 8 This program is free software: you can redistribute it and/or modify |
9 it under the terms of the GNU General Public License as published by | 9 it under the terms of the GNU General Public License as published by |
10 the Free Software Foundation, either version 3 of the License, or | 10 the Free Software Foundation, either version 3 of the License, or |
31 from email.charset import Charset | 31 from email.charset import Charset |
32 import os,os.path | 32 import os,os.path |
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.exceptions import * | |
36 | 37 |
37 | 38 |
38 from zope.interface import implements | 39 from zope.interface import implements |
39 | 40 |
40 | 41 |
59 def __init__(self, host): | 60 def __init__(self, host): |
60 info(_("Plugin Maildir initialization")) | 61 info(_("Plugin Maildir initialization")) |
61 self.host = host | 62 self.host = host |
62 | 63 |
63 self.__observed={} | 64 self.__observed={} |
64 self.__mailboxes={} | 65 pList=host.memory.getProfilesList #shorter :) |
65 self.data=host.memory.getPrivate("MAILDIR_data") or {"INBOX":{"cur_idx":0}} | 66 self.__mailboxes=dict(zip(pList(),len(pList())*[{}])) |
67 self.data=host.memory.getPrivate("MAILDIR_data") or dict(zip(pList(),len(pList())*[{"INBOX":{"cur_idx":0}}])) #Create empty box for each profile | |
66 #a value in the dictionnary for a mailbox is a dictionnary with the following value | 68 #a value in the dictionnary for a mailbox is a dictionnary with the following value |
67 # - cur_idx: value of the current unique integer increment (UID) | 69 # - cur_idx: value of the current unique integer increment (UID) |
68 # - message_id (as returned by MaildirMailbox): a tuple of (UID, [flag1, flag2, ...]) | 70 # - message_id (as returned by MaildirMailbox): a tuple of (UID, [flag1, flag2, ...]) |
69 | 71 |
70 #the trigger | 72 #the trigger |
72 | 74 |
73 def __del__(self): | 75 def __del__(self): |
74 debug('Destroying MaildirBox') | 76 debug('Destroying MaildirBox') |
75 self.host.memory.setPrivate('MAILDIR_data',self.data) | 77 self.host.memory.setPrivate('MAILDIR_data',self.data) |
76 | 78 |
77 def accessMessageBox(self, boxname, observer=None): | 79 def accessMessageBox(self, boxname, observer=None, profile_key='@DEFAULT@'): |
78 """Create and return a MailboxUser instance | 80 """Create and return a MailboxUser instance |
79 @param boxname: name of the box | 81 @param boxname: name of the box |
80 @param observer: method to call when a NewMessage arrive""" | 82 @param observer: method to call when a NewMessage arrive""" |
81 if not self.__mailboxes.has_key(boxname): | 83 profile = self.host.memory.getProfileName(profile_key) |
82 self.__mailboxes[boxname]=MailboxUser(self, boxname, observer) | 84 if not profile: |
85 raise ProfileUnknownError | |
86 if not self.__mailboxes[profile].has_key(boxname): | |
87 self.__mailboxes[profile][boxname]=MailboxUser(self, boxname, observer, profile=profile) | |
83 else: | 88 else: |
84 if observer: | 89 if observer: |
85 self.addObserver(observer, boxname) | 90 self.addObserver(observer, profile, boxname) |
86 return self.__mailboxes[boxname] | 91 return self.__mailboxes[profile][boxname] |
87 | 92 |
88 def _removeBoxAccess(self, boxname, mailboxUser): | 93 def _getProfilePath(self, profile): |
94 """Return a unique path for profile's mailbox | |
95 The path must be unique, usable as a dir name, and bijectional""" | |
96 return profile.replace('/','_').replace('..','_') #FIXME: this is too naive to work well, must be improved | |
97 | |
98 def _removeBoxAccess(self, boxname, mailboxUser, profile): | |
89 """Remove a reference to a box | 99 """Remove a reference to a box |
90 @param name: name of the box | 100 @param name: name of the box |
91 @param mailboxUser: MailboxUser instance""" | 101 @param mailboxUser: MailboxUser instance""" |
92 if not self.__mailboxes.has_key(boxname): | 102 if not self.__mailboxes.has_key(boxname): |
93 err_msg=_("Trying to remove an mailboxUser not referenced") | 103 err_msg=_("Trying to remove an mailboxUser not referenced") |
94 error(_("INTERNAL ERROR: ") + err_msg) | 104 error(_("INTERNAL ERROR: ") + err_msg) |
95 raise MaildirError(err_msg) | 105 raise MaildirError(err_msg) |
96 assert self.__mailboxes[boxname]==mailboxUser | 106 assert self.__mailboxes[profile][boxname]==mailboxUser |
97 del __mailboxes[boxname] | 107 del __mailboxes[profile][boxname] |
98 | 108 |
99 def _checkBoxReference(self, boxname): | 109 def _checkBoxReference(self, boxname, profile): |
100 """Check if there is a reference on a box, and return it | 110 """Check if there is a reference on a box, and return it |
101 @param boxname: name of the box to check | 111 @param boxname: name of the box to check |
102 @return: MailboxUser instance or None""" | 112 @return: MailboxUser instance or None""" |
103 if self.__mailboxes.has_key(boxname): | 113 if self.__mailboxes.has_key(profile): |
104 return self.__mailboxes[boxname] | 114 if self.__mailboxes[profile].has_key(boxname): |
105 | 115 return self.__mailboxes[profile][boxname] |
106 def __getBoxData(self, boxname): | 116 |
117 def __getBoxData(self, boxname, profile): | |
107 """Return the date of a box""" | 118 """Return the date of a box""" |
108 try: | 119 try: |
109 return self.data[boxname] #the boxname MUST exist in the data | 120 return self.data[profile][boxname] #the boxname MUST exist in the data |
110 except KeyError: | 121 except KeyError: |
111 err_msg=_("Boxname doesn't exist in internal data") | 122 err_msg=_("Boxname doesn't exist in internal data") |
112 error(_("INTERNAL ERROR: ") + err_msg) | 123 error(_("INTERNAL ERROR: ") + err_msg) |
113 raise MaildirError(err_msg) | 124 raise MaildirError(err_msg) |
114 | 125 |
115 def getUid(self, boxname, message_id): | 126 def getUid(self, boxname, message_id, profile): |
116 """Return an unique integer, always ascending, for a message | 127 """Return an unique integer, always ascending, for a message |
117 This is mainly needed for the IMAP protocol | 128 This is mainly needed for the IMAP protocol |
118 @param boxname: name of the box where the message is | 129 @param boxname: name of the box where the message is |
119 @param message_id: unique id of the message as given by MaildirMailbox | 130 @param message_id: unique id of the message as given by MaildirMailbox |
120 @return: Integer UID""" | 131 @return: Integer UID""" |
121 box_data = self.__getBoxData(boxname) | 132 box_data = self.__getBoxData(boxname, profile) |
122 if box_data.has_key(message_id): | 133 if box_data.has_key(message_id): |
123 ret = box_data[message_id][0] | 134 ret = box_data[message_id][0] |
124 else: | 135 else: |
125 box_data['cur_idx']+=1 | 136 box_data['cur_idx']+=1 |
126 box_data[message_id]=[box_data['cur_idx'],[]] | 137 box_data[message_id]=[box_data['cur_idx'],[]] |
127 ret = box_data[message_id] | 138 ret = box_data[message_id] |
128 self.host.memory.setPrivate('MAILDIR_data',self.data) | 139 self.host.memory.setPrivate('MAILDIR_data',self.data) |
129 return ret | 140 return ret |
130 | 141 |
131 def getNextUid(self, boxname): | 142 def getNextUid(self, boxname, profile): |
132 """Return next unique integer that will generated | 143 """Return next unique integer that will generated |
133 This is mainly needed for the IMAP protocol | 144 This is mainly needed for the IMAP protocol |
134 @param boxname: name of the box where the message is | 145 @param boxname: name of the box where the message is |
135 @return: Integer UID""" | 146 @return: Integer UID""" |
136 box_data = self.__getBoxData(boxname) | 147 box_data = self.__getBoxData(boxname, profile) |
137 return box_data['cur_idx']+1 | 148 return box_data['cur_idx']+1 |
138 | 149 |
139 def getNextExistingUid(self, boxname, uid): | 150 def getNextExistingUid(self, boxname, uid, profile): |
140 """Give the next uid of existing message | 151 """Give the next uid of existing message |
141 @param boxname: name of the box where the message is | 152 @param boxname: name of the box where the message is |
142 @param uid: uid to start from | 153 @param uid: uid to start from |
143 @return: uid or None if the is no more message""" | 154 @return: uid or None if the is no more message""" |
144 box_data = self.__getBoxData(boxname) | 155 box_data = self.__getBoxData(boxname, profile) |
145 idx=uid+1 | 156 idx=uid+1 |
146 while self.getIdFromUid(boxname, idx) == None: #TODO: this is highly inefficient because getIdfromUid is inefficient, fix this | 157 while self.getIdFromUid(boxname, idx, profile) == None: #TODO: this is highly inefficient because getIdfromUid is inefficient, fix this |
147 idx+=1 | 158 idx+=1 |
148 if idx>box_data['cur_idx']: | 159 if idx>box_data['cur_idx']: |
149 return None | 160 return None |
150 return idx | 161 return idx |
151 | 162 |
152 def getMaxUid(self, boxname): | 163 def getMaxUid(self, boxname, profile): |
153 """Give the max existing uid | 164 """Give the max existing uid |
154 @param boxname: name of the box where the message is | 165 @param boxname: name of the box where the message is |
155 @return: uid""" | 166 @return: uid""" |
156 box_data = self.__getBoxData(boxname) | 167 box_data = self.__getBoxData(boxname, profile) |
157 return box_data['cur_idx'] | 168 return box_data['cur_idx'] |
158 | 169 |
159 def getIdFromUid(self, boxname, message_uid): | 170 def getIdFromUid(self, boxname, message_uid, profile): |
160 """Return the message unique id from it's integer UID | 171 """Return the message unique id from it's integer UID |
161 @param boxname: name of the box where the message is | 172 @param boxname: name of the box where the message is |
162 @param message_uid: unique integer identifier | 173 @param message_uid: unique integer identifier |
163 @return: unique id of the message as given by MaildirMailbox or None if not found""" | 174 @return: unique id of the message as given by MaildirMailbox or None if not found""" |
164 box_data = self.__getBoxData(boxname) | 175 box_data = self.__getBoxData(boxname, profile) |
165 for message_id in box_data.keys(): #TODO: this is highly inefficient on big mailbox, must be replaced in the future | 176 for message_id in box_data.keys(): #TODO: this is highly inefficient on big mailbox, must be replaced in the future |
166 if message_id == 'cur_idx': | 177 if message_id == 'cur_idx': |
167 continue | 178 continue |
168 if box_data[message_id][0] == message_uid: | 179 if box_data[message_id][0] == message_uid: |
169 return message_id | 180 return message_id |
170 return None | 181 return None |
171 | 182 |
172 def getFlags(self, boxname, mess_id): | 183 def getFlags(self, boxname, mess_id, profile): |
173 """Return the messages flags | 184 """Return the messages flags |
174 @param boxname: name of the box where the message is | 185 @param boxname: name of the box where the message is |
175 @param message_idx: message id as given by MaildirMailbox | 186 @param message_idx: message id as given by MaildirMailbox |
176 @return: list of strings""" | 187 @return: list of strings""" |
177 box_data = self.__getBoxData(boxname) | 188 box_data = self.__getBoxData(boxname, profile) |
178 if not box_data.has_key(mess_id): | 189 if not box_data.has_key(mess_id): |
179 raise MailboxException("Trying to get flags from an unexisting message") | 190 raise MailboxException("Trying to get flags from an unexisting message") |
180 return box_data[mess_id][1] | 191 return box_data[mess_id][1] |
181 | 192 |
182 def setFlags(self, boxname, mess_id, flags): | 193 def setFlags(self, boxname, mess_id, flags, profile): |
183 """Change the flags of the message | 194 """Change the flags of the message |
184 @param boxname: name of the box where the message is | 195 @param boxname: name of the box where the message is |
185 @param message_idx: message id as given by MaildirMailbox | 196 @param message_idx: message id as given by MaildirMailbox |
186 @param flags: list of strings | 197 @param flags: list of strings |
187 """ | 198 """ |
188 box_data = self.__getBoxData(boxname) | 199 box_data = self.__getBoxData(boxname, profile) |
189 assert(type(flags)==list) | 200 assert(type(flags)==list) |
201 flags=[flag.upper() for flag in flags] #we store every flag UPPERCASE | |
190 if not box_data.has_key(mess_id): | 202 if not box_data.has_key(mess_id): |
191 raise MailboxException("Trying to set flags for an unexisting message") | 203 raise MailboxException("Trying to set flags for an unexisting message") |
192 box_data[mess_id][1]=flags | 204 box_data[mess_id][1]=flags |
193 self.host.memory.setPrivate('MAILDIR_data',self.data) | 205 self.host.memory.setPrivate('MAILDIR_data',self.data) |
194 | 206 |
195 def getMessageIdsWithFlag(self, boxname, flag): | 207 def getMessageIdsWithFlag(self, boxname, flag, profile): |
196 """Return ids of messages where a flag is set | 208 """Return ids of messages where a flag is set |
197 @param boxname: name of the box where the message is | 209 @param boxname: name of the box where the message is |
198 @param flag: flag to check | 210 @param flag: flag to check |
199 @return: list of id (as given by MaildirMailbox)""" | 211 @return: list of id (as given by MaildirMailbox)""" |
200 box_data = self.__getBoxData(boxname) | 212 box_data = self.__getBoxData(boxname, profile) |
201 assert(isinstance(flag,basestring)) | 213 assert(isinstance(flag,basestring)) |
214 flag=flag.upper() | |
202 result = [] | 215 result = [] |
203 for key in box_data: | 216 for key in box_data: |
204 if key=='cur_idx': | 217 if key=='cur_idx': |
205 continue | 218 continue |
206 if flag in box_data[key][1]: | 219 if flag in box_data[key][1]: |
207 result.append(key) | 220 result.append(key) |
208 return result | 221 return result |
209 | 222 |
210 def purgeDeleted(self, boxname): | 223 def purgeDeleted(self, boxname, profile): |
211 """Remove data for messages with flag "\\Deleted" | 224 """Remove data for messages with flag "\\Deleted" |
212 @param boxname: name of the box where the message is | 225 @param boxname: name of the box where the message is |
213 """ | 226 """ |
214 box_data = self.__getBoxData(boxname) | 227 box_data = self.__getBoxData(boxname, profile) |
215 for mess_id in self.getMessageIdsWithFlag(boxname,"\\Deleted"): | 228 for mess_id in self.getMessageIdsWithFlag(boxname,"\\Deleted", profile): |
216 del(box_data[mess_id]) | 229 del(box_data[mess_id]) |
217 self.host.memory.setPrivate('MAILDIR_data',self.data) | 230 self.host.memory.setPrivate('MAILDIR_data',self.data) |
218 | 231 |
219 def cleanTable(self, boxname, existant_id): | 232 def cleanTable(self, boxname, existant_id, profile): |
220 """Remove mails which no longuer exist from the table | 233 """Remove mails which no longuer exist from the table |
221 @param boxname: name of the box to clean | 234 @param boxname: name of the box to clean |
222 @param existant_id: list of id which actually exist""" | 235 @param existant_id: list of id which actually exist""" |
223 box_data = self.__getBoxData(boxname) | 236 box_data = self.__getBoxData(boxname, profile) |
224 to_remove=[] | 237 to_remove=[] |
225 for key in box_data: | 238 for key in box_data: |
226 if key not in existant_id and key!="cur_idx": | 239 if key not in existant_id and key!="cur_idx": |
227 to_remove.append(key) | 240 to_remove.append(key) |
228 for key in to_remove: | 241 for key in to_remove: |
229 del box_data[key] | 242 del box_data[key] |
230 | 243 |
231 | 244 |
232 def MessageReceivedTrigger(self, message): | 245 def MessageReceivedTrigger(self, message, profile): |
233 """This trigger catch normal message and put the in the Maildir box. | 246 """This trigger catch normal message and put the in the Maildir box. |
234 If the message is not of "normal" type, do nothing | 247 If the message is not of "normal" type, do nothing |
235 @param message: message xmlstrem | 248 @param message: message xmlstrem |
236 @return: False if it's a normal message, True else""" | 249 @return: False if it's a normal message, True else""" |
237 for e in message.elements(): | 250 for e in message.elements(): |
238 if e.name == "body": | 251 if e.name == "body": |
239 type = message['type'] if message.hasAttribute('type') else 'chat' #FIXME: check specs | 252 type = message['type'] if message.hasAttribute('type') else 'chat' #FIXME: check specs |
240 if message['type'] != 'normal': | 253 if message['type'] != 'normal': |
241 return True | 254 return True |
242 self.accessMessageBox("INBOX").addMessage(message) | 255 self.accessMessageBox("INBOX", profile_key=profile).addMessage(message) |
243 return False | 256 return False |
244 | 257 |
245 def addObserver(self, callback, boxname, signal="NEW_MESSAGE"): | 258 def addObserver(self, callback, profile, boxname, signal="NEW_MESSAGE"): |
246 """Add an observer for maildir box changes | 259 """Add an observer for maildir box changes |
247 @param callback: method to call when the the box is updated | 260 @param callback: method to call when the the box is updated |
248 @param boxname: name of the box to observe | 261 @param boxname: name of the box to observe |
249 @param signal: which signal is observed by the caller""" | 262 @param signal: which signal is observed by the caller""" |
250 if not self.__observed.has_key(boxname): | 263 if not self.__observed.has_key((profile,boxname)): |
251 self.__observed[boxname]={} | 264 self.__observed[(profile,boxname)]={} |
252 if not self.__observed[boxname].has_key(signal): | 265 if not self.__observed[(profile,boxname)].has_key(signal): |
253 self.__observed[boxname][signal]=set() | 266 self.__observed[(profile,boxname)][signal]=set() |
254 self.__observed[boxname][signal].add(callback) | 267 self.__observed[(profile,boxname)][signal].add(callback) |
255 | 268 |
256 def removeObserver(self, callback, boxname, signal="NEW_MESSAGE"): | 269 def removeObserver(self, callback, profile, boxname, signal="NEW_MESSAGE"): |
257 """Remove an observer of maildir box changes | 270 """Remove an observer of maildir box changes |
258 @param callback: method to remove from obervers | 271 @param callback: method to remove from obervers |
259 @param boxname: name of the box which was observed | 272 @param boxname: name of the box which was observed |
260 @param signal: which signal was observed by the caller""" | 273 @param signal: which signal was observed by the caller""" |
261 if not self.__observed.has_key(boxname): | 274 if not self.__observed.has_key((profile,boxname)): |
262 err_msg=_("Trying to remove an observer for an inexistant mailbox") | 275 err_msg=_("Trying to remove an observer for an inexistant mailbox") |
263 error(_("INTERNAL ERROR: ") + err_msg) | 276 error(_("INTERNAL ERROR: ") + err_msg) |
264 raise MaildirError(err_msg) | 277 raise MaildirError(err_msg) |
265 if not self.__observed[boxname].has_key(signal): | 278 if not self.__observed[(profile,boxname)].has_key(signal): |
266 err_msg=_("Trying to remove an inexistant observer, no observer for this signal") | 279 err_msg=_("Trying to remove an inexistant observer, no observer for this signal") |
267 error(_("INTERNAL ERROR: ") + err_msg) | 280 error(_("INTERNAL ERROR: ") + err_msg) |
268 raise MaildirError(err_msg) | 281 raise MaildirError(err_msg) |
269 if not callback in self.__observed[boxname][signal]: | 282 if not callback in self.__observed[(profile,boxname)][signal]: |
270 err_msg=_("Trying to remove an inexistant observer") | 283 err_msg=_("Trying to remove an inexistant observer") |
271 error(_("INTERNAL ERROR: ") + err_msg) | 284 error(_("INTERNAL ERROR: ") + err_msg) |
272 raise MaildirError(err_msg) | 285 raise MaildirError(err_msg) |
273 self.__observed[boxname][signal].remove(callback) | 286 self.__observed[(profile,boxname)][signal].remove(callback) |
274 | 287 |
275 def emitSignal(self, boxname, signal_name): | 288 def emitSignal(self, profile, boxname, signal_name): |
276 """Emit the signal to observer""" | 289 """Emit the signal to observer""" |
277 debug('emitSignal %s %s' %(boxname, signal_name)) | 290 debug('emitSignal %s %s %s' %(profile, boxname, signal_name)) |
278 try: | 291 try: |
279 for observer_cb in self.__observed[boxname][signal_name]: | 292 for observer_cb in self.__observed[(profile, boxname)][signal_name]: |
280 observer_cb() | 293 observer_cb() |
281 except KeyError: | 294 except KeyError: |
282 pass | 295 pass |
283 | 296 |
284 | 297 |
302 mail.set_payload(e.children[0].encode('utf-8')) | 315 mail.set_payload(e.children[0].encode('utf-8')) |
303 elif e.name == "subject": | 316 elif e.name == "subject": |
304 mail['Subject'] = e.children[0].encode('utf-8') | 317 mail['Subject'] = e.children[0].encode('utf-8') |
305 return mail.as_string() | 318 return mail.as_string() |
306 | 319 |
307 def __init__(self, _maildir, name, observer=None): | 320 def __init__(self, _maildir, name, observer=None, profile="@NONE@"): |
308 """@param _maildir: the main MaildirBox instance | 321 """@param _maildir: the main MaildirBox instance |
309 @param name: name of the mailbox | 322 @param name: name of the mailbox |
323 @param profile: real profile (ie not a profile_key) | |
310 THIS OBJECT MUST NOT BE USED DIRECTLY: use MaildirBox.accessMessageBox instead""" | 324 THIS OBJECT MUST NOT BE USED DIRECTLY: use MaildirBox.accessMessageBox instead""" |
311 if _maildir._checkBoxReference(self): | 325 if _maildir._checkBoxReference(name, profile): |
312 error ("INTERNAL ERROR: MailboxUser MUST NOT be instancied directly") | 326 error ("INTERNAL ERROR: MailboxUser MUST NOT be instancied directly") |
313 raise MailboxException('double MailboxUser instanciation') | 327 raise MailboxException('double MailboxUser instanciation') |
314 if name!="INBOX": | 328 if name!="INBOX": |
315 raise NotImplementedError | 329 raise NotImplementedError |
316 self.name=name | 330 self.name=name |
331 self.profile=profile | |
317 self.maildir=_maildir | 332 self.maildir=_maildir |
318 mailbox_path = os.path.expanduser(os.path.join(self.maildir.host.get_const('local_dir'), MAILDIR_PATH)) | 333 profile_path = self.maildir._getProfilePath(profile) |
334 full_profile_path = os.path.join(os.path.expanduser(self.maildir.host.get_const('local_dir')),profile_path) | |
335 if not os.path.exists(full_profile_path): | |
336 os.makedirs(full_profile_path,0700) | |
337 mailbox_path = os.path.join(full_profile_path, MAILDIR_PATH) | |
319 self.mailbox_path=mailbox_path | 338 self.mailbox_path=mailbox_path |
320 self.mailbox = maildir.MaildirMailbox(mailbox_path) | 339 self.mailbox = maildir.MaildirMailbox(mailbox_path) |
321 self.observer=observer | 340 self.observer=observer |
322 self.__uid_table_update() | 341 self.__uid_table_update() |
323 | 342 |
324 | |
325 if observer: | 343 if observer: |
326 debug("adding observer for %s" % name) | 344 debug("adding observer for %s (%s)" % (name,profile)) |
327 self.maildir.addObserver(observer, name, "NEW_MESSAGE") | 345 self.maildir.addObserver(observer, profile, name, "NEW_MESSAGE") |
328 | 346 |
329 def __uid_table_update(self): | 347 def __uid_table_update(self): |
330 existant_id=[] | 348 existant_id=[] |
331 for mess_idx in range (self.getMessageCount()): | 349 for mess_idx in range (self.getMessageCount()): |
332 #we update the uid table | 350 #we update the uid table |
333 existant_id.append(self.getId(mess_idx)) | 351 existant_id.append(self.getId(mess_idx)) |
334 self.getUid(mess_idx) | 352 self.getUid(mess_idx) |
335 self.maildir.cleanTable(self.name, existant_id) | 353 self.maildir.cleanTable(self.name, existant_id, profile=self.profile) |
336 | 354 |
337 | 355 |
338 def __del__(self): | 356 def __del__(self): |
339 if observer: | 357 if observer: |
340 debug("removing observer for %s" % self.name) | 358 debug("removing observer for %s" % self.name) |
341 self._maildir.removeObserver(observer, self.name, "NEW_MESSAGE") | 359 self._maildir.removeObserver(observer, self.name, "NEW_MESSAGE") |
342 self._maildir._removeBoxAccess(self.name, self) | 360 self.maildir._removeBoxAccess(self.name, self, profile=self.profile) |
343 | 361 |
344 def addMessage(self, message): | 362 def addMessage(self, message): |
345 """Add a message to the box | 363 """Add a message to the box |
346 @param message: XMPP XML message""" | 364 @param message: XMPP XML message""" |
347 self.mailbox.appendMessage(self.xmppMessage2mail(message)).addCallback(self.emitSignal, "NEW_MESSAGE") | 365 self.mailbox.appendMessage(self.xmppMessage2mail(message)).addCallback(self.emitSignal, "NEW_MESSAGE") |
348 | 366 |
349 def emitSignal(self, ignore, signal): | 367 def emitSignal(self, ignore, signal): |
350 """Emit the signal to the observers""" | 368 """Emit the signal to the observers""" |
351 self.getUid(self.getMessageCount()-1) #we make an uid for the last message added | 369 if signal=="NEW_MESSAGE": |
352 self.maildir.emitSignal(self.name, signal) | 370 self.getUid(self.getMessageCount()-1) #XXX: we make an uid for the last message added |
371 self.maildir.emitSignal(self.profile, self.name, signal) | |
353 | 372 |
354 def getId(self, mess_idx): | 373 def getId(self, mess_idx): |
355 """Return the Unique ID of the message | 374 """Return the Unique ID of the message |
356 @mess_idx: message index""" | 375 @mess_idx: message index""" |
357 return self.mailbox.getUidl(mess_idx) | 376 return self.mailbox.getUidl(mess_idx) |
358 | 377 |
359 def getUid(self, mess_idx): | 378 def getUid(self, mess_idx): |
360 """Return a unique interger id for the message, always ascending""" | 379 """Return a unique interger id for the message, always ascending""" |
361 mess_id=self.getId(mess_idx) | 380 mess_id=self.getId(mess_idx) |
362 return self.maildir.getUid(self.name,mess_id) | 381 return self.maildir.getUid(self.name,mess_id, profile=self.profile) |
363 | 382 |
364 def getNextUid(self): | 383 def getNextUid(self): |
365 return self.maildir.getNextUid(self.name) | 384 return self.maildir.getNextUid(self.name, profile=self.profile) |
366 | 385 |
367 def getNextExistingUid(self, uid): | 386 def getNextExistingUid(self, uid): |
368 return self.maildir.getNextExistingUid(self.name, uid) | 387 return self.maildir.getNextExistingUid(self.name, uid, profile=self.profile) |
369 | 388 |
370 def getMaxUid(self): | 389 def getMaxUid(self): |
371 return self.maildir.getMaxUid(self.name) | 390 return self.maildir.getMaxUid(self.name, profile=self.profile) |
372 | 391 |
373 def getMessageCount(self): | 392 def getMessageCount(self): |
374 """Return number of mails present in this box""" | 393 """Return number of mails present in this box""" |
375 return len(self.mailbox.list) | 394 return len(self.mailbox.list) |
376 | 395 |
410 def getFlags(self, mess_idx): | 429 def getFlags(self, mess_idx): |
411 """Return the flags of the message | 430 """Return the flags of the message |
412 @param mess_idx: message index | 431 @param mess_idx: message index |
413 @return: list of strings""" | 432 @return: list of strings""" |
414 id = self.getId(mess_idx) | 433 id = self.getId(mess_idx) |
415 return self.maildir.getFlags(self.name, id) | 434 return self.maildir.getFlags(self.name, id, profile=self.profile) |
416 | 435 |
417 def getFlagsUid(self, mess_uid): | 436 def getFlagsUid(self, mess_uid): |
418 """Return the flags of the message | 437 """Return the flags of the message |
419 @param mess_uid: message unique identifier | 438 @param mess_uid: message unique identifier |
420 @return: list of strings""" | 439 @return: list of strings""" |
421 id = self.maildir.getIdFromUid(self.name,mess_uid) | 440 id = self.maildir.getIdFromUid(self.name,mess_uid, profile=self.profile) |
422 return self.maildir.getFlags(self.name, id) | 441 return self.maildir.getFlags(self.name, id, profile=self.profile) |
423 | 442 |
424 def setFlags(self, mess_idx, flags): | 443 def setFlags(self, mess_idx, flags): |
425 """Change the flags of the message | 444 """Change the flags of the message |
426 @param mess_idx: message index | 445 @param mess_idx: message index |
427 @param flags: list of strings | 446 @param flags: list of strings |
428 """ | 447 """ |
429 id = self.getId(mess_idx) | 448 id = self.getId(mess_idx) |
430 return self.maildir.setFlags(self.name, id, flags) | 449 self.maildir.setFlags(self.name, id, flags, profile=self.profile) |
431 | 450 |
432 def setFlagsUid(self, mess_uid, flags): | 451 def setFlagsUid(self, mess_uid, flags): |
433 """Change the flags of the message | 452 """Change the flags of the message |
434 @param mess_uid: message unique identifier | 453 @param mess_uid: message unique identifier |
435 @param flags: list of strings | 454 @param flags: list of strings |
436 """ | 455 """ |
437 id = self.maildir.getIdFromUid(self.name,mess_uid) | 456 id = self.maildir.getIdFromUid(self.name,mess_uid, profile=self.profile) |
438 return self.maildir.setFlags(self.name, id, flags) | 457 return self.maildir.setFlags(self.name, id, flags, profile=self.profile) |
439 | 458 |
440 def getMessageIdsWithFlag(self, flag): | 459 def getMessageIdsWithFlag(self, flag): |
441 """Return ids of messages where a flag is set | 460 """Return ids of messages where a flag is set |
442 @param flag: flag to check | 461 @param flag: flag to check |
443 @return: list of id (as given by MaildirMailbox)""" | 462 @return: list of id (as given by MaildirMailbox)""" |
444 return self.maildir.getMessageIdsWithFlag(self.name,flag) | 463 return self.maildir.getMessageIdsWithFlag(self.name,flag, profile=self.profile) |
445 | 464 |
446 def removeDeleted(self): | 465 def removeDeleted(self): |
447 """Actually delete message flagged "\\Deleted" | 466 """Actually delete message flagged "\\Deleted" |
448 Also purge the internal data of these messages | 467 Also purge the internal data of these messages |
449 """ | 468 """ |
450 for mess_id in self.getMessageIdsWithFlag("\\Deleted"): | 469 for mess_id in self.getMessageIdsWithFlag("\\Deleted"): |
451 print ("Deleting %s", mess_id) | 470 print ("Deleting %s", mess_id) |
452 self.mailbox.deleteMessage(self.getIdxFromId(mess_id)) | 471 self.mailbox.deleteMessage(self.getIdxFromId(mess_id)) |
453 self.mailbox = maildir.MaildirMailbox(self.mailbox_path) #We need to reparse the dir to have coherent indexing | 472 self.mailbox = maildir.MaildirMailbox(self.mailbox_path) #We need to reparse the dir to have coherent indexing |
454 self.maildir.purgeDeleted(self.name) | 473 self.maildir.purgeDeleted(self.name, profile=self.profile) |
455 | 474 |
456 def emptyTrash(self): | 475 def emptyTrash(self): |
457 """Delete everything in the .Trash dir""" | 476 """Delete everything in the .Trash dir""" |
458 import shutils | 477 import shutils |
459 pdb.set_trace() | 478 pdb.set_trace() |