Mercurial > libervia-backend
annotate src/plugins/plugin_misc_maildir.py @ 254:9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 17 Jan 2011 04:23:31 +0100 |
parents | f45ffbf211e9 |
children | 55b750017b71 |
rev | line source |
---|---|
253 | 1 #!/usr/bin/python |
2 # -*- coding: utf-8 -*- | |
3 | |
4 """ | |
5 SAT plugin for managing imap server | |
6 Copyright (C) 2011 Jérôme Poisson (goffi@goffi.org) | |
7 | |
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 | |
10 the Free Software Foundation, either version 3 of the License, or | |
11 (at your option) any later version. | |
12 | |
13 This program is distributed in the hope that it will be useful, | |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 GNU General Public License for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with this program. If not, see <http://www.gnu.org/licenses/>. | |
20 """ | |
21 | |
22 from logging import debug, info, error | |
23 import warnings | |
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 | |
26 from twisted.words.protocols.jabber import error as jab_error | |
27 from twisted.cred import portal,checkers | |
28 from twisted.mail import imap4,maildir | |
29 from email.parser import Parser | |
30 import email.message | |
31 from email.charset import Charset | |
32 import os,os.path | |
33 from cStringIO import StringIO | |
34 from twisted.internet import reactor | |
35 import pdb | |
36 | |
37 | |
38 from zope.interface import implements | |
39 | |
40 | |
41 PLUGIN_INFO = { | |
42 "name": "Maildir Plugin", | |
43 "import_name": "Maildir", | |
44 "type": "Misc", | |
45 "protocols": [], | |
46 "dependencies": [], | |
47 "main": "MaildirBox", | |
48 "handler": "no", | |
49 "description": _("""Intercept "normal" type messages, and put them in a Maildir type box""") | |
50 } | |
51 | |
52 MAILDIR_PATH = "Maildir" | |
53 | |
54 class MaildirError(Exception): | |
55 pass | |
56 | |
57 class MaildirBox(): | |
58 | |
59 def __init__(self, host): | |
60 info(_("Plugin Maildir initialization")) | |
61 self.host = host | |
62 | |
63 self.__observed={} | |
64 self.__mailboxes={} | |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
65 self.data=host.memory.getPrivate("MAILDIR_data") or {"INBOX":{"cur_idx":0}} |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
66 #a value in the dictionnary for a mailbox is a dictionnary with the following value |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
67 # - cur_idx: value of the current unique integer increment (UID) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
68 # - message_id (as returned by MaildirMailbox): a tuple of (UID, [flag1, flag2, ...]) |
253 | 69 |
70 #the trigger | |
71 host.trigger.add("MessageReceived", self.MessageReceivedTrigger) | |
72 | |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
73 def __destroy__(self): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
74 debug('Destroying MaildirBox') |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
75 self.host.memory.setPrivate('MAILDIR_data',self.data) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
76 |
253 | 77 def accessMessageBox(self, boxname, observer=None): |
78 """Create and return a MailboxUser instance | |
79 @param boxname: name of the box | |
80 @param observer: method to call when a NewMessage arrive""" | |
81 if not self.__mailboxes.has_key(boxname): | |
82 self.__mailboxes[boxname]=MailboxUser(self, boxname, observer) | |
83 else: | |
84 if observer: | |
85 self.addObserver(observer, boxname) | |
86 return self.__mailboxes[boxname] | |
87 | |
88 def _removeBoxAccess(self, boxname, mailboxUser): | |
89 """Remove a reference to a box | |
90 @param name: name of the box | |
91 @param mailboxUser: MailboxUser instance""" | |
92 if not self.__mailboxes.has_key(boxname): | |
93 err_msg=_("Trying to remove an mailboxUser not referenced") | |
94 error(_("INTERNAL ERROR: ") + err_msg) | |
95 raise MaildirError(err_msg) | |
96 assert self.__mailboxes[boxname]==mailboxUser | |
97 del __mailboxes[boxname] | |
98 | |
99 def _checkBoxReference(self, boxname): | |
100 """Check if there is a reference on a box, and return it | |
101 @param boxname: name of the box to check | |
102 @return: MailboxUser instance or None""" | |
103 if self.__mailboxes.has_key(boxname): | |
104 return self.__mailboxes[boxname] | |
105 | |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
106 def getUid(self, boxname, message_id): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
107 """Return an unique integer, always ascending, for a message |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
108 This is mainly needed for the IMAP protocol |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
109 @param boxname: name of the box where the message is |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
110 @param message_id: unique id of the message as given by MaildirMailbox |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
111 @return: Integer UID""" |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
112 try: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
113 box_data = self.data[boxname] #the boxname MUST exist in the data |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
114 except KeyError: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
115 err_msg=_("Boxname doesn't exist in internal data") |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
116 error(_("INTERNAL ERROR: ") + err_msg) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
117 raise MaildirError(err_msg) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
118 if box_data.has_key(message_id): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
119 ret = box_data[message_id][0] |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
120 else: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
121 box_data['cur_idx']+=1 |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
122 box_data[message_id]=(box_data['cur_idx'],[]) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
123 ret = box_data[message_id] |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
124 self.host.memory.setPrivate('MAILDIR_data',self.data) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
125 return ret |
253 | 126 |
127 | |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
128 def getNextUid(self, boxname): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
129 """Return next unique integer that will generated |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
130 This is mainly needed for the IMAP protocol |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
131 @param boxname: name of the box where the message is |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
132 @return: Integer UID""" |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
133 try: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
134 box_data = self.data[boxname] #the boxname MUST exist in the data |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
135 except KeyError: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
136 err_msg=_("Boxname doesn't exist in internal data") |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
137 error(_("INTERNAL ERROR: ") + err_msg) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
138 raise MaildirError(err_msg) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
139 return box_data['cur_idx']+1 |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
140 |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
141 def getNextExistingUid(self, boxname, uid): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
142 """Give the next uid of existing message |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
143 @param boxname: name of the box where the message is |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
144 @param uid: uid to start from |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
145 @return: uid or None if the is no more message""" |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
146 try: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
147 box_data = self.data[boxname] #the boxname MUST exist in the data |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
148 except KeyError: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
149 err_msg=_("Boxname doesn't exist in internal data") |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
150 error(_("INTERNAL ERROR: ") + err_msg) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
151 raise MaildirError(err_msg) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
152 idx=uid+1 |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
153 while self.getIdfromUid(boxname, idx) == None: #TODO: this is highly inefficient because getIdfromUid is inefficient, fix this |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
154 idx+=1 |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
155 if idx>box_data['cur_idx']: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
156 return None |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
157 return idx |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
158 |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
159 def getMaxUid(self, boxname): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
160 """Give the max existing uid |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
161 @param boxname: name of the box where the message is |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
162 @return: uid""" |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
163 try: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
164 box_data = self.data[boxname] #the boxname MUST exist in the data |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
165 except KeyError: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
166 err_msg=_("Boxname doesn't exist in internal data") |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
167 error(_("INTERNAL ERROR: ") + err_msg) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
168 raise MaildirError(err_msg) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
169 return box_data['cur_idx'] |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
170 |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
171 |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
172 def getIdfromUid(self, boxname, message_uid): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
173 """Return the message unique id from it's integer UID |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
174 @param boxname: name of the box where the message is |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
175 @param message_uid: unique integer identifier |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
176 @return: unique id of the message as given by MaildirMailbox or None if not found""" |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
177 try: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
178 box_data = self.data[boxname] #the boxname MUST exist in the data |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
179 except KeyError: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
180 err_msg=_("Boxname doesn't exist in internal data") |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
181 error(_("INTERNAL ERROR: ") + err_msg) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
182 raise MaildirError(err_msg) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
183 |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
184 for message_id in box_data.keys(): #TODO: this is highly inefficient on big mailbox, must be replaced in the future |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
185 if message_id == 'cur_idx': |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
186 continue |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
187 if box_data[message_id][0] == message_uid: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
188 return message_id |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
189 return None |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
190 |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
191 def cleanTable(self, boxname, existant_id): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
192 """Remove mails which no longuer exist from the table |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
193 @param boxname: name of the box to clean |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
194 @param existant_id: list of id which actually exist""" |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
195 try: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
196 box_data = self.data[boxname] #the boxname MUST exist in the data |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
197 except KeyError: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
198 err_msg=_("Boxname doesn't exist in internal data") |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
199 error(_("INTERNAL ERROR: ") + err_msg) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
200 raise MaildirError(err_msg) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
201 to_remove=[] |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
202 for key in box_data: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
203 if key not in existant_id and key!="cur_idx": |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
204 to_remove.append(key) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
205 for key in to_remove: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
206 del box_data[key] |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
207 |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
208 |
253 | 209 def MessageReceivedTrigger(self, message): |
210 """This trigger catch normal message and put the in the Maildir box. | |
211 If the message is not of "normal" type, do nothing | |
212 @param message: message xmlstrem | |
213 @return: False if it's a normal message, True else""" | |
214 for e in message.elements(): | |
215 if e.name == "body": | |
216 type = message['type'] if message.hasAttribute('type') else 'chat' #FIXME: check specs | |
217 if message['type'] != 'normal': | |
218 return True | |
219 self.accessMessageBox("INBOX").addMessage(message) | |
220 return False | |
221 | |
222 def addObserver(self, callback, boxname, signal="NEW_MESSAGE"): | |
223 """Add an observer for maildir box changes | |
224 @param callback: method to call when the the box is updated | |
225 @param boxname: name of the box to observe | |
226 @param signal: which signal is observed by the caller""" | |
227 if not self.__observed.has_key(boxname): | |
228 self.__observed[boxname]={} | |
229 if not self.__observed[boxname].has_key(signal): | |
230 self.__observed[boxname][signal]=set() | |
231 self.__observed[boxname][signal].add(callback) | |
232 | |
233 def removeObserver(self, callback, boxname, signal="NEW_MESSAGE"): | |
234 """Remove an observer of maildir box changes | |
235 @param callback: method to remove from obervers | |
236 @param boxname: name of the box which was observed | |
237 @param signal: which signal was observed by the caller""" | |
238 if not self.__observed.has_key(boxname): | |
239 err_msg=_("Trying to remove an observer for an inexistant mailbox") | |
240 error(_("INTERNAL ERROR: ") + err_msg) | |
241 raise MaildirError(err_msg) | |
242 if not self.__observed[boxname].has_key(signal): | |
243 err_msg=_("Trying to remove an inexistant observer, no observer for this signal") | |
244 error(_("INTERNAL ERROR: ") + err_msg) | |
245 raise MaildirError(err_msg) | |
246 if not callback in self.__observed[boxname][signal]: | |
247 err_msg=_("Trying to remove an inexistant observer") | |
248 error(_("INTERNAL ERROR: ") + err_msg) | |
249 raise MaildirError(err_msg) | |
250 self.__observed[boxname][signal].remove(callback) | |
251 | |
252 def emitSignal(self, boxname, signal_name): | |
253 """Emit the signal to observer""" | |
254 debug('emitSignal %s %s' %(boxname, signal_name)) | |
255 try: | |
256 for observer_cb in self.__observed[boxname][signal_name]: | |
257 observer_cb() | |
258 except KeyError: | |
259 pass | |
260 | |
261 | |
262 class MailboxUser: | |
263 """This class is used to access a mailbox""" | |
264 | |
265 def xmppMessage2mail(self, message): | |
266 """Convert the XMPP's XML message to a basic rfc2822 message | |
267 @param xml: domish.Element of the message | |
268 @return: string email""" | |
269 mail = email.message.Message() | |
270 mail['MIME-Version'] = "1.0" | |
271 mail['Content-Type'] = "text/plain; charset=UTF-8; format=flowed" | |
272 mail['Content-Transfer-Encoding'] = "8bit" | |
273 mail['From'] = message['from'].encode('utf-8') | |
274 mail['To'] = message['to'].encode('utf-8') | |
275 mail['Date'] = email.utils.formatdate().encode('utf-8') | |
276 #TODO: save thread id | |
277 for e in message.elements(): | |
278 if e.name == "body": | |
279 mail.set_payload(e.children[0].encode('utf-8')) | |
280 elif e.name == "subject": | |
281 mail['Subject'] = e.children[0].encode('utf-8') | |
282 return mail.as_string() | |
283 | |
284 def __init__(self, _maildir, name, observer=None): | |
285 """@param _maildir: the main MaildirBox instance | |
286 @param name: name of the mailbox | |
287 THIS OBJECT MUST NOT BE USED DIRECTLY: use MaildirBox.accessMessageBox instead""" | |
288 if _maildir._checkBoxReference(self): | |
289 error ("INTERNAL ERROR: MailboxUser MUST NOT be instancied directly") | |
290 raise MailboxException('double MailboxUser instanciation') | |
291 if name!="INBOX": | |
292 raise NotImplementedError | |
293 self.name=name | |
294 self.maildir=_maildir | |
295 mailbox_path = os.path.expanduser(os.path.join(self.maildir.host.get_const('local_dir'), MAILDIR_PATH)) | |
296 self.mailbox_path=mailbox_path | |
297 self.mailbox = maildir.MaildirMailbox(mailbox_path) | |
298 self.observer=observer | |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
299 self.__uid_table_update() |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
300 |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
301 |
253 | 302 if observer: |
303 debug("adding observer for %s" % name) | |
304 self.maildir.addObserver(observer, name, "NEW_MESSAGE") | |
305 | |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
306 def __uid_table_update(self): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
307 existant_id=[] |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
308 for mess_idx in range (self.getMessageCount()): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
309 #we update the uid table |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
310 existant_id.append(self.getId(mess_idx)) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
311 self.getUid(mess_idx) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
312 self.maildir.cleanTable(self.name, existant_id) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
313 |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
314 |
253 | 315 def __destroy__(self): |
316 if observer: | |
317 debug("removing observer for %s" % self.name) | |
318 self._maildir.removeObserver(observer, self.name, "NEW_MESSAGE") | |
319 self._maildir._removeBoxAccess(self.name, self) | |
320 | |
321 def addMessage(self, message): | |
322 """Add a message to the box | |
323 @param message: XMPP XML message""" | |
324 self.mailbox.appendMessage(self.xmppMessage2mail(message)).addCallback(self.emitSignal, "NEW_MESSAGE") | |
325 | |
326 def emitSignal(self, ignore, signal): | |
327 """Emit the signal to the observers""" | |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
328 self.getUid(self.getMessageCount()-1) #we make an uid for the last message added |
253 | 329 self.maildir.emitSignal(self.name, signal) |
330 | |
331 def getId(self, mess_idx): | |
332 """Return the Unique ID of the message | |
333 @mess_idx: message index""" | |
334 return self.mailbox.getUidl(mess_idx) | |
335 | |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
336 def getUid(self, mess_idx): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
337 """Return a unique interger id for the message, always ascending""" |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
338 mess_id=self.getId(mess_idx) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
339 return self.maildir.getUid(self.name,mess_id) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
340 |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
341 def getNextUid(self): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
342 return self.maildir.getNextUid(self.name) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
343 |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
344 def getNextExistingUid(self, uid): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
345 return self.maildir.getNextExistingUid(self.name, uid) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
346 |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
347 def getMaxUid(self): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
348 return self.maildir.getMaxUid(self.name) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
349 |
253 | 350 def getMessageCount(self): |
351 """Return number of mails present in this box""" | |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
352 return len(self.mailbox.list) |
253 | 353 |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
354 def getMessageIdx(self, mess_idx): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
355 """Return the full message |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
356 @mess_idx: message index""" |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
357 return self.mailbox.getMessage(mess_idx) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
358 |
253 | 359 def getMessage(self, mess_idx): |
360 """Return the full message | |
361 @mess_idx: message index""" | |
362 return self.mailbox.getMessage(mess_idx) | |
254
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
363 |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
364 def getMessageUid(self, mess_uid): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
365 """Return the full message |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
366 @mess_idx: message unique identifier""" |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
367 for mess_idx in range (self.getMessageCount()): |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
368 if self.getUid(mess_idx) == mess_uid: |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
369 return self.mailbox.getMessage(mess_idx) |
9fc32d1d9046
Plugin IMAP, plugin MAILDIR: added IMAP's UID management, mailbox data persistence
Goffi <goffi@goffi.org>
parents:
253
diff
changeset
|
370 raise IndexError |